aboutsummaryrefslogtreecommitdiffstats
path: root/win
diff options
context:
space:
mode:
authorGravatar Peter McGoron 2022-09-26 13:17:04 -0400
committerGravatar Peter McGoron 2022-09-26 13:17:04 -0400
commita31884d44375d99c1ac47e27150b3b05d42871ef (patch)
tree9a26a9aebc1ccf8a33085f34d5c3b00c7d4e4347 /win
start unfinished code
Diffstat (limited to 'win')
-rw-r--r--win/shim.c369
1 files changed, 369 insertions, 0 deletions
diff --git a/win/shim.c b/win/shim.c
new file mode 100644
index 0000000..d1d41bb
--- /dev/null
+++ b/win/shim.c
@@ -0,0 +1,369 @@
+#include <windows.h>
+#include <stdio.h>
+#include <string.h>
+#include <time.h>
+#include "sdnet.h"
+
+#define export __declspec(dllexport)
+#define ADDR "192.168.1.1"
+#define PORT 1394
+
+static FILE *log;
+static SOCKET sock = INVALID_SOCKET;
+static WSADATA wsd;
+
+static FILE *makelog(void) {
+ char buf[128];
+ time_t t = time(NULL);
+
+ snprintf(buf, sizeof(buf), "logfile-%lu.txt", (unsigned long) t);
+
+ return fopen(buf, "w");
+}
+
+static SOCKET makesock(void) {
+ struct addrinfo hints, *ai, *p;
+ SOCKET s;
+
+ if (WSAStartup(MAKEWORD(2,2), &wsd) != 0) {
+ fputs(log, "wsa\n");
+ return INVALID_SOCKET;
+ }
+
+ memset(&hints, 0, sizeof(hints));
+ hints.ai_family = AF_INET;
+ hints.ai_socktype = SOCK_STREAM;
+ hints.ai_protocol = IPPROTO_TCP;
+
+ if (getaddrinfo(ADDR, PORT, &hints, &ai) != 0) {
+ fputs(log, "getaddrinfo\n");
+ return INVALID_SOCKET;
+ }
+
+ for (p = ai; p; p = p->ai_next) {
+ s = socket(p->ai_family, p->ai_socktype, p->ai_protocol);
+ if (s == INVALID_SOCKET)
+ continue;
+ if (connect(s, p->ai_addr, (int)->ai_addrlen) == SOCKET_ERROR) {
+ closesocket(s);
+ continue;
+ }
+ break;
+ }
+
+ freeaddrinfo(ai);
+ if (!p) {
+ fputs(log, "getaddrinfo socket connect\n");
+ return INVALID_SOCKET;
+ }
+
+ return s;
+}
+
+export LONG sdNET_OpenAdapter(PHANDLE hDevice, ULONG wwuid,
+ ULONG adpNumber) {
+ (void)wwuid;
+ (void)adpNumber;
+
+ if (!log)
+ return sdNET_ERR_ADAPTER_BUSY;
+
+ log = makelog();
+ if (!log)
+ return sdNET_ERR_ADAPTER_BUSY;
+ fputs(log, "open log\n");
+
+ sock = makesock();
+ if (!sock)
+ return sdNET_ERR_ADAPTER_BUSY;
+
+ *hDevice = 1394;
+ return sdNET_ERR_SUCCESS;
+}
+
+export LONG sdNET_CloseAdapter(PHANDLE hDevice) {
+ if (*hDevice != 1394)
+ return sdNET_ERR_INVALID_HANDLE;
+ fputs(log, "Closing\n");
+ fclose(log);
+ closesocket(sock);
+
+ log = NULL;
+ sock = INVALID_SOCKET;
+
+ return sdNET_ERR_INVALID_HANDLE;
+}
+
+static int dump_tcode(unsigned long tcode)
+{
+ unsigned long other = tcode & ~IEEE1394_tCODE_MASK;
+ int is_iso = 0;
+
+ fprint(logfile, "Transaction Code: ");
+
+ switch (tcode & IEEE1394_tCODE_MASK) {
+ case IEEE1394_QUAD_WRREQ:
+ log("Async request subaction, quadlet");
+ break;
+ case IEEE1394_BLOCK_WRREQ:
+ log(Async request subaction, block");
+ break;
+ case IEEE1394_WRRESP:
+ log("Async response subaction for both write request types, no payload");
+ break;
+ case IEEE1394_QUAD_RDREQ:
+ log("Async request subaction, no payload");
+ break;
+ case IEEE1394_BLOCK_RDREQ:
+ log("Async request subaction quadlet payload");
+ break;
+ case IEEE1394_QUAD_RDRESP:
+ log("Async response subaction to request for quadlet, quadlet payload");
+ break;
+ case IEEE1394_BLOCK_RDRESP:
+ log("Async response subaction to request for block, block payload");
+ break;
+ case IEEE1394_CYCLE_START_REQ:
+ log("Async request to start isochronous cycle, quadlet payload");
+ break;
+ case IEEE1394_LOCK_REQ:
+ log("Async request subaction, block payload");
+ break;
+ case IEEE1394_ISOBLOCK_REQ:
+ log("Isochronous subaction, block payload");
+ is_iso = 1;
+ break;
+ case IEEE194_LOCK_RESP:
+ log("Asynchronous request subaction for lock request, block payload");
+ break;
+ default:
+ log("Unknown code %lu", tcode & IEEE1394_tCODE_MASK);
+ break;
+ }
+
+ if (other) {
+ log("Other transaction code: %lu", other);
+ }
+
+ log("\n");
+ return is_iso;
+}
+
+static void dump_data(unsigned long len, unsigned long *data)
+{
+ /* Dump in base52 instead? */
+ unsigned long i;
+
+ log("Data length: %lu\n", len);
+ log("Data:");
+ for (i = 0; i < len >> 2; i++) {
+ fprintf(" %08lX", *data);
+ data++;
+ }
+
+ log("\n");
+}
+
+static void dump_asy(PsdNET_Packet_t p)
+{
+ fprintf(logfile,
+ "Asynchronous Packet.\n"
+ "Bus: %lu\n"
+ "Node: %lu\n"
+ "Address Offset, High: 0x%08lX\n"
+ "Address Offset, Low: 0x%08lX\n"
+ "Transaction Label: %lu\n",
+ p->type.asy.bus,
+ p->type.asy.node,
+ p->type.asy.offsetHigh,
+ p->type.asy.offsetLow
+ );
+
+ log("Retry code: ");
+ switch (p->type.asy.retryCode) {
+ case IEEE1394_Retry_0:
+ log("Initial subaction.\n");
+ break;
+ case IEEE1394_Retry_X:
+ log("Retry subaction from acknowledge busy, or retry from acknowledge busy A or B.\n");
+ break;
+ case IEEE1394_Retry_A:
+ log("Retry subaction, dual-phase retry node, A.\n");
+ break;
+ case IEEE1394_Retry_B:
+ log("Retry subaction, dual-phase retry node, B.\n");
+ break;
+ default:
+ log("Unknown %lu\n", p->type.asy.retryCode);
+ break;
+ }
+
+ log("Response code: ");
+ switch(p->type.asy.rCode) {
+ case IEEE1394_RESP_COMPLETE:
+ log("Complete\n");
+ break;
+ case IEEE1394_RESP_CONFLICT_ERROR:
+ log("Resource conflict\n");
+ break;
+ case IEEE1394_RESP_DATA_ERROR:
+ log("Hardware error\n");
+ break;
+ case IEEE1394_RESP_TYPE_ERROR:
+ log("Invalid value or transaction\n");
+ break;
+ case IEEE1394_RESP_ADDR_ERROR:
+ log("Destination not accessable\n");
+ break;
+ default:
+ log("Unknown %lu\n", p->type.asy.rCode);
+ }
+
+ log("Extended response code: ");
+ switch (p->type.asy.xtCode) {
+ case IEEE1394_MASK_SWAP:
+ log("Mask swap\n");
+ break;
+ case IEEE1394_COMPARE_SWAP:
+ log("Compare swap\n");
+ break;
+ case IEEE1394_FETCH_ADD:
+ log("Fetch add\n");
+ break;
+ case IEEE1394_BOUNDED_ADD:
+ log("Bounded add\n");
+ break;
+ case IEEE1394_WRAP_ADD:
+ log("Wrap add\n");
+ break;
+ case IEEE1394_VENDER_DEP:
+ log("Vendor dependent\n");
+ default:
+ log("Unknown %lu\n", p->type.asy.xtCode);
+ }
+}
+
+static void dump_iso(PsdNET_Packet_t p)
+{
+ log("Isochronous packet.\n"
+ "Channel: %lu\n"
+ "Synchronization code: %lu\n",
+ p->type.iso.channel,
+ p->type.iso.synchro);
+
+ log("Tag: ");
+ switch (p->type.iso.tag) {
+ case IEEE1394_TAG_UNFORMATTED:
+ log("Unformatted\n");
+ break;
+ case IEEE1394_TAG_FORMAT1:
+ log("1\n");
+ break;
+ case IEEE1394_TAG_FORMAT2:
+ log("2\n");
+ break;
+ case IEEE1394_TAG_FORMAT3:
+ log("3\n");
+ break;
+ default:
+ log("Unknown tag %lu\n", p->type.iso.tag);
+ break;
+ }
+}
+
+static void dump_packet(PsdNET_Packet_t p)
+{
+ log("Timeout: %lu\n", p->tCode);
+ log("Flags:");
+ if (p->flags & SDNET__NOBLOCKINGMODE) {
+ log(" Nonblocking");
+ } else if (p->flags & SDNET__BLOCKINGMODE) {
+ log(" Blocking");
+ }
+ log("\n");
+
+ if (dump_tcode(p->tCode) == 1)
+ dump_iso(p);
+ else
+ dump_asy(p);
+
+
+ log("Acknowledge code: ");
+ switch (p->ack) {
+ case IEEE1394_ACK_COMPLETE:
+ log("Accepted and completed\n");
+ break;
+ case IEEE1394_ACK_PENDING:
+ log("Accepted and pending\n");
+ break;
+ case IEEE1394_ACK_BUSY_X:
+ log("Rejected, retry\n");
+ break;
+ case IEEE1394_ACK_BUSY_A:
+ log("Rejected, retry at phase A\n");
+ break;
+ case IEEE1394_ACK_BUSY_B:
+ log("Rejected, retry at phase B\n");
+ break;
+ case IEEE1394_ACK_DATA_ERROR:
+ log("CRC/length check fail\n");
+ break;
+ case IEEE1394_ACK_TYPE_ERROR:
+ log("Unsupported or incorrect value, or invalid transaction\n");
+ default:
+ log("Unknown %lu\n", p->ack);
+ }
+
+ log("Speed: ");
+ switch (p->speed) {
+ case IEEE1394_ASYSPD_100Mbits:
+ case IEEE1394_ISOSPD_100Mbits:
+ log("100\n");
+ break;
+ case IEEE1394_ASYSPD200Mbits:
+ case IEEE1394_ISOSPD200Mbits:
+ log("200\n");
+ break;
+ case IEEE1394_ASYSPD400Mbits:
+ case IEEE1394_ISOSPD400Mbits:
+ log("400\n");
+ break;
+ default:
+ log("Unknown %lu\n", p->speed);
+ }
+
+ dump_data(p->datalen, p->data);
+}
+
+export LONG sdNET_SendAsyncPacket(PHANDLE hDevice, PsdNET_Packet_t pk) {
+ fputs(log, "Send Async\n");
+ dump_packet(pk);
+ /* TODO: convert pk->asy.data and pk->asy.datalen from long to octet */
+ msg_send_async(sock, pk->asy.bus, pk->asy.node,
+ pk->asy.offset_high << 32 | pk->asy.offset_low,
+ pk->tcode, pk->asy.tLabel, pk->asy.datalen, pk->asy.data);
+ return sdNET_ERR_TIMEOUT;
+}
+
+export LONG sdNET_SendIsochPacket(PHANDLE hDevice, PsdNET_Packet_t pk) {
+ fputs(log, "Send Isoch\n");
+ dump_packet(pk);
+ return sdNET_ERR_TIMEOUT;
+}
+
+export LONG sdNET_ReceivePacket(PHANDLE hDevice, PsdNET_Packet_t pk) {
+ char buf[512];
+ fputs(log, "Receive One\n");
+
+ return sdNET_ERR_TIMEOUT;
+}
+
+export LONG sdNET_IOControl(PHANDLE hDevice, ULONG cmd, PVOID iodata) {
+ fputs(log, "IOControl\n");
+ return sdNET_ERR_IOCTL_FAILED;
+}
+
+export LONG sdNET_MultiReceive(PHANDLE hDevice, PsdNET_MultiPk_t multiPk) {
+ fputs(log, "Recv many\n");
+ return sdNET_ERR_TIMEOUT;
+}