/* NXTLeftRightController.c Copyright 2006, Sivan Toledo, Tel-Aviv University */ #define _WIN32_WINNT 0x0500 #include #include #pragma comment(lib, "user32.lib") TCHAR *GetLastErrorMessage(DWORD last_error) { static TCHAR errmsg[512]; if (!FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, 0, last_error, 0, errmsg, 511, NULL)) { /* if we fail, call ourself to find out why and return that error */ return (GetLastErrorMessage(GetLastError())); } return errmsg; } void nxt_process_msg(unsigned char* msg) { INPUT in; printf("Processing message <%s>\n",msg); if (strcmp((char*)msg,"RIGHT")==0) { in.type = INPUT_KEYBOARD; // INPUT_KEYBOARD in.ki.wVk = VK_RIGHT; in.ki.wScan = 0; in.ki.dwFlags = 0; in.ki.time = 0; // system supplies time stamp in.ki.dwExtraInfo = 0; SendInput(1,&in,sizeof(in)); } if (strcmp((char*)msg,"LEFT")==0) { in.type = INPUT_KEYBOARD; // INPUT_KEYBOARD in.ki.wVk = VK_LEFT; in.ki.wScan = 0; in.ki.dwFlags = 0; in.ki.time = 0; // system supplies time stamp in.ki.dwExtraInfo = 0; SendInput(1,&in,sizeof(in)); } } #define DIRECT_COMMAND 0 #define SYSTEM_COMMAND 1 #define REPLY 2 void nxt_bt_read(HANDLE h) { unsigned char buffer[256]; DWORD bytes_received; DWORD total = 0; /* read the two-byte header containing the length of the message */ while (total < 2) { printf("Calling ReadFile, total so far = %d\n",total); if (ReadFile(h, buffer+total, 256, &bytes_received, NULL) == 0) { printf("ReadFile error: %s",GetLastErrorMessage(GetLastError())); return; } else { total += bytes_received; } } DWORD packet_length; packet_length = buffer[0] + 256*buffer[1]; /* LSB, MSB */ printf("packet length = %d\n",packet_length); while (total < 2+packet_length) { printf("Calling ReadFile, total so far = %d\n",total); if (ReadFile(h, buffer + total, 256, &bytes_received,NULL) == 0) { printf("ReadFile error: %s",GetLastErrorMessage(GetLastError())); return; } else { total += bytes_received; } } printf("done reading the packet, analyzing it now\n"); unsigned char type, reply_requested, command, msg_size, inbox; unsigned char* msg; switch (buffer[2]) { /* packet type */ case 0x00: type = DIRECT_COMMAND; reply_requested = 1; break; case 0x01: type = SYSTEM_COMMAND; reply_requested = 1; break; case 0x02: type = REPLY; reply_requested = 0; break; case 0x80: type = DIRECT_COMMAND; reply_requested = 0; break; case 0x81: type = SYSTEM_COMMAND; reply_requested = 0; break; } switch (buffer[3]) { /* command */ case 0x09: inbox = buffer[4]; msg_size = buffer[5]; msg = buffer+6; nxt_process_msg(msg); break; } } int main(int argc, char* argv[]) { if (argc < 2) { printf("usage: %s COM?\n",argv[0]); printf(" where ? is the port number of the bluetooth serial port\n"); printf(" when this computer is used as a bluetooth client.\n"); printf(" To find out the port number, right click on the bluetooth icon\n"); printf(" in the tray, select Advanced Configuration, select the Local Services\n"); printf(" tab, and note the COM port of the serial service.\n"); printf(" \n"); printf(" When used with an appropriate NXT program, the NXT is used as a two-key\n"); printf(" keyboard, with the keys LEFT and RIGHT.\n"); printf(" \n"); printf(" On the NXT side, pair with the PC (initiate the pairing from the NXT)\n"); printf(" and run a program that sends the strings LEFT and RIGHT when you click.\n"); printf(" on the buttons.\n"); exit(0); } HANDLE h; DCB config_; char port_name[256]; strcpy(port_name,"//./"); strcat(port_name,argv[1]); h = CreateFile(port_name, // Specify port device: default "COM1" GENERIC_READ | GENERIC_WRITE, // Specify mode that open device. 0, // the devide isn't shared. NULL, // the object gets a default security. OPEN_EXISTING, // Specify which action to take on file. 0, // default. NULL); // default. if (h == INVALID_HANDLE_VALUE) { printf("failed to open COM port <%s>: %s", port_name, GetLastErrorMessage(GetLastError())); return -1; } if (GetCommState(h,&config_) == 0) { printf("GetCommState error: %s",GetLastErrorMessage(GetLastError())); return -1; } COMMTIMEOUTS comTimeOut; GetCommTimeouts(h,&comTimeOut); printf("read interval timeout = %d\n",comTimeOut.ReadIntervalTimeout); printf("read multiplier timeout = %d\n",comTimeOut.ReadTotalTimeoutMultiplier); printf("read constant timeout = %d\n",comTimeOut.ReadTotalTimeoutConstant); comTimeOut.ReadIntervalTimeout = 3; comTimeOut.ReadTotalTimeoutMultiplier = 3; comTimeOut.ReadTotalTimeoutConstant = 60000; comTimeOut.WriteTotalTimeoutMultiplier = 0; comTimeOut.WriteTotalTimeoutConstant = 0; SetCommTimeouts(h,&comTimeOut); while (1) { nxt_bt_read(h); } if (CloseHandle(h) == 0) { return -1; } return 0; }