/* $Id: pontifex.c,v 1.6 2004/03/10 07:17:53 jmuelmen Exp $ */ #ifndef NOT_VC #include #include #include "surface.h" #include #else #include #include #endif #include #include int surf_vendor(Surf *pSurf,unsigned int requestType, unsigned int request, unsigned int value, unsigned int idx, void *buff, int len); int surf_descriptor(Surf *pSurf,unsigned int requestType, unsigned int request, unsigned int value, unsigned int idx, void *buff, int len); /* * USB spec information * * This is all stuff grabbed from various USB specs and is pretty much * not subject to change */ /* * Device and/or Interface Class codes */ #define USB_CLASS_PER_INTERFACE 0 /* for DeviceClass */ #define USB_CLASS_AUDIO 1 #define USB_CLASS_COMM 2 #define USB_CLASS_HID 3 #define USB_CLASS_PRINTER 7 #define USB_CLASS_MASS_STORAGE 8 #define USB_CLASS_HUB 9 #define USB_CLASS_DATA 10 #define USB_CLASS_VENDOR_SPEC 0xff /* * Descriptor types */ #define USB_DT_DEVICE 0x01 #define USB_DT_CONFIG 0x02 #define USB_DT_STRING 0x03 #define USB_DT_INTERFACE 0x04 #define USB_DT_ENDPOINT 0x05 #define USB_DT_HID 0x21 #define USB_DT_REPORT 0x22 #define USB_DT_PHYSICAL 0x23 #define USB_DT_HUB 0x29 /* * Descriptor sizes per descriptor type */ #define USB_DT_DEVICE_SIZE 18 #define USB_DT_CONFIG_SIZE 9 #define USB_DT_INTERFACE_SIZE 9 #define USB_DT_ENDPOINT_SIZE 7 #define USB_DT_ENDPOINT_AUDIO_SIZE 9 /* Audio extension */ #define USB_DT_HUB_NONVAR_SIZE 7 #define PFX_NEXT_BRD 0x00 #define PFX_READ 0x01 #define PFX_WRITE 0x02 #define PFX_OPEN 0x03 #define PFX_CLOSE 0x04 #define PFX_RESET 0x05 #define PFX_CTRL 0x06 #define PONTIFEX_READ_PORT 14159 #define PONTIFEX_WRITE_PORT 14160 #define BUFLEN 1024 int main(int argc, char **argv) { Surf surf[4]; int sock, length; struct sockaddr_in sn, rn; unsigned char buf[BUFLEN]; int err; int board; int board_open = 0; #ifndef NOT_VC /* Fucking windows ass-shit. */ WORD wVersionRequested; /* "WSA" means "wipes shitty ass" */ WSADATA wsaData; /* retarded fucking ass wipes */ wVersionRequested = MAKEWORD( 2, 2 ); err = WSAStartup( wVersionRequested, &wsaData ); #endif /* make a socket */ sock = socket(AF_INET, SOCK_DGRAM, 0); if (sock < 0) { #ifndef NOT_VC switch (WSAGetLastError()) { case WSANOTINITIALISED: printf("Not initialized\n"); break; case WSAEAFNOSUPPORT: printf("No support\n"); break; default: printf("No fucking clue\n"); } #endif perror("opening datagram socket"); exit(1); } /* Create name to receive from. */ rn.sin_family = AF_INET; rn.sin_addr.s_addr = INADDR_ANY; rn.sin_port = htons(PONTIFEX_READ_PORT); if (bind(sock, (struct sockaddr *)&rn, sizeof(rn))) { #ifndef NOT_VC switch (err = WSAGetLastError()) { case WSANOTINITIALISED: printf("Not initialized\n"); break; case WSAEAFNOSUPPORT: printf("No support\n"); break; default: printf("No fucking clue\n"); } #endif perror("binding datagram socket"); exit(1); } length = sizeof(rn); if (getsockname(sock, (struct sockaddr *)&rn, &length)) { perror("getting socket name"); exit(1); } printf("Socket has port %d... ", ntohs(rn.sin_port)); if (ntohs(rn.sin_port) != PONTIFEX_READ_PORT) { printf("we're unhappy.\n"); return 1; } else printf("we're happy.\n"); /* now make a sockaddr_in to send to */ sn.sin_addr.s_addr = inet_addr("127.0.0.1"); printf("Sending to host 0x%x\n", ntohl(sn.sin_addr.s_addr)); sn.sin_family = AF_INET; sn.sin_port = htons(PONTIFEX_WRITE_PORT); #if 0 /* wait for the test message from ambush */ if ((length = recv(sock, buf, 1024, 0)) >= 0) { buf[length] = 0; /* printf("Read %d bytes: %s\n", length, buf); */ } else perror("receiving datagram packet"); /* send test message back */ if ((length = sendto(sock, DATA, sizeof(DATA), 0, &sn, sizeof(sn))) < 0) perror("sending test datagram message"); /* else printf("Sent %d bytes\n", length); */ #endif board = 0; /* now go into a loop and pass data along to surface */ while ((length = recv(sock, buf, BUFLEN, 0)) >= 0) { int dev; int ep; int rqt, req, val, idx; int count; int rc; int i; if (!length) { printf("Busy-waiting"); continue; } switch (buf[0]) { case PFX_NEXT_BRD: /* kluge for now */ if (board) { buf[0] = -1; sendto(sock, buf, 1, 0, &sn, sizeof(sn)); break; } buf[0] = 0; sendto(sock, buf, 1, 0, &sn, sizeof(sn)); board++; break; case PFX_READ: dev = buf[1]; ep = buf[2]; count = buf[3]; count = surf_recv(&surf[dev], ep, buf, count); sendto(sock, buf, count, 0, &sn, sizeof(sn)); break; case PFX_WRITE: dev = buf[1]; ep = buf[2]; count = surf_send(&surf[dev], ep, buf + 3, length - 3); break; case PFX_OPEN: dev = buf[1]; if (!board_open) { surf_init(&surf[dev]); board_open = 1; } buf[0] = 0; sendto(sock, buf, 1, 0, &sn, sizeof(sn)); break; case PFX_CLOSE: dev = buf[1]; if (board_open) { surf_close(&surf[dev]); board_open = 0; } buf[0] = 0; sendto(sock, buf, 1, 0, &sn, sizeof(sn)); break; case PFX_RESET: board = 0; break; case PFX_CTRL: i = 1; dev = buf[i++]; rqt = buf[i++]; req = buf[i++]; val = buf[i++] << 8; val += buf[i++]; idx = buf[i++] << 8; idx += buf[i++]; count = buf[i++]; /* because windows was written by ass fucks, we have to use different functions depending on what our request is. */ switch (req) { case USB_REQ_GET_DESCRIPTOR: rc = surf_descriptor(&surf[dev], rqt, req, val, idx, buf + i, count); sendto(sock, buf + i, rc, 0, &sn, sizeof(sn)); break; default: /* fix me. implement me. */ sendto(sock, NULL, 0, 0, &sn, sizeof(sn)); break; } break; } } close(sock); return 0; }