void Chatpad::read_thread() { try { uint8_t data[5]; while(!m_quit_thread) { int len = 0; int ret = libusb_interrupt_transfer(m_handle, LIBUSB_ENDPOINT_IN | 6, data, sizeof(data), &len, 0); if (ret != LIBUSB_SUCCESS) { raise_exception(std::runtime_error, "libusb_interrupt_transfer() failed: " << usb_strerror(ret)); } else { if (g_logger.get_log_level() > Logger::kDebug) { log_debug("read: " << len << "/5: data: " << raw2str(data, len)); } if (data[0] == 0x00) { struct ChatpadKeyMsg msg; memcpy(&msg, data, sizeof(msg)); process(msg); } } } } catch(const std::exception& err) { log_error(err.what()); } }
main (int argc, char *argv[]) { int i, j, k, c; struct HRAW hraw, hraw2; struct HSTR hstr, hstr2; struct HVAL hval, hval2; char *pname, *fin, *fout; char fgas[100]; FILE *infid, *outfid; FILE *gasfid[MAXGAS]; /* options defaults */ int gasid = 0; int isonum = 0; double wL = 0; double wU = 30000; double smin = 0; int bflag = 0; int outfmt = 0; int debug = 1; extern int getopt(); extern char *optarg; extern int optind; extern char *sbase(); pname = argv[0]; while ((c=getopt(argc, argv, "g:i:L:U:s:brd")) != EOF) switch (c) { case 'g': /* select a particular gas id */ gasid = atoi(optarg); break; case 'i': /* select a particular isotope */ isonum = atoi(optarg); break; case 'L': /* wavenumber lower bound */ wL = atof(optarg); break; case 'U': /* wavenumber upper bound */ wU = atof(optarg); break; case 's': /* specify a line strength threshold */ smin = atof(optarg); break; case 'b': /* break database into individual gasses */ bflag = 1; break; case 'r': /* readable output */ outfmt = 1; break; case 'd': /* debugging info */ debug = 1; break; case '?': /* bad command */ exit(1); break; } if (argc - optind < 1) { fprintf(stderr, "%s: error -- no input file specified\n", pname); exit(1); } fin = argv[optind++]; if (argc - optind == 1) fout = argv[optind++]; else fout = "-"; if (debug) { fprintf(stderr, "fin = %s, fout = %s\n", fin, fout); fprintf(stderr, "bflag = %d, gasid = %d, smin = %g, L = %g, U = %g\n", bflag, gasid, smin, wL, wU); } /* open input file */ if (strcmp(fin, "-") == 0) infid = stdin; else if ((infid = fopen(fin, "r")) == NULL) { fprintf(stderr, "%s: can't open input file %s", pname, fin); exit(0); } if (!bflag) { /* SELECT MODE: write a selected subset of the input file * to the output file */ if (strcmp(fout, "-") == 0) outfid = stdout; else if ((outfid = fopen(fout, "w")) == NULL) { fprintf(stderr, "%s: can't open output file %s", pname, fout); exit(0); } while (fread(&hraw, sizeof(hraw), 1, infid) == 1) { raw2str(&hraw, &hstr); str2val(&hstr, &hval); if ((gasid == 0 || hval.IGAS == gasid) && (isonum == 0 || hval.ISO == isonum) && hval.WNUM >= wL && hval.WNUM <= wU && hval.STREN >= smin) { if (outfmt == 0) write_hraw(&hraw, outfid); else if (outfmt == 1) write_hval(&hval, outfid); } } fclose(outfid); } else { /* SPLIT MODE: separate input file into componant gasses, * one gas per file, in a common directory */ if (strcmp(fout, "-") == 0) { fprintf(stderr, "%s: output directory can't be stdout!\n", pname); exit(127); } else if (mkdir(fout, 0755) == -1) { fprintf(stderr, "%s: can't create output directory %s\n", pname, fout); exit(127); } for (i=0; i<MAXGAS; i++) gasfid[i] = NULL; while (fread(&hraw, sizeof(hraw), 1, infid) == 1) { raw2str(&hraw, &hstr); str2val(&hstr, &hval); if (gasfid[hval.IGAS] == NULL) { /* open output file for new gas */ sprintf(fgas, "%s/g%d.dat", fout, hval.IGAS); if ((gasfid[hval.IGAS] = fopen(fgas, "w")) == NULL) { fprintf(stderr, "%s: can't open output file %s\n", pname, fgas); exit(0); } } if ((isonum == 0 || hval.ISO == isonum) && hval.WNUM >= wL && hval.WNUM <= wU && hval.STREN >= smin) { if (outfmt == 0) write_hraw(&hraw, gasfid[hval.IGAS]); else if (outfmt == 1) write_hval(&hval, gasfid[hval.IGAS]); } } for (i=0; i<MAXGAS; i++) if (gasfid[i] != NULL) fclose(gasfid[i]); } }
bool GenericUSBController::parse(uint8_t* data, int len, XboxGenericMsg* msg_out) { std::cout << "GenericUSBController:parse(): " << raw2str(data, len) << std::endl; return false; }
bool Xbox360WirelessController::parse(uint8_t* data, int len, XboxGenericMsg* msg_out) { if (len == 0) { return false; } else { if (len == 2 && data[0] == 0x08) { // Connection Status Message if (data[1] == 0x00) { log_info("connection status: nothing"); // reset the controller into neutral position on disconnect memset(msg_out, 0, sizeof(*msg_out)); set_active(false); return true; } else if (data[1] == 0x80) { log_info("connection status: controller connected"); set_led(get_led()); set_active(true); } else if (data[1] == 0x40) { log_info("Connection status: headset connected"); } else if (data[1] == 0xc0) { log_info("Connection status: controller and headset connected"); set_led(get_led()); } else { log_info("Connection status: unknown"); } } else if (len == 29) { set_active(true); if (data[0] == 0x00 && data[1] == 0x0f && data[2] == 0x00 && data[3] == 0xf0) { // Initial Announc Message m_serial = (boost::format("%2x:%2x:%2x:%2x:%2x:%2x:%2x") % int(data[7]) % int(data[8]) % int(data[9]) % int(data[10]) % int(data[11]) % int(data[12]) % int(data[13])).str(); m_battery_status = data[17]; log_info("Serial: " << m_serial); log_info("Battery Status: " << m_battery_status); } else if (data[0] == 0x00 && data[1] == 0x01 && data[2] == 0x00 && data[3] == 0xf0 && data[4] == 0x00 && data[5] == 0x13) { // Event message msg_out->type = XBOX_MSG_XBOX360; Xbox360Msg& msg = msg_out->xbox360; uint8_t* ptr = data+4; msg.type = ptr[0]; msg.length = ptr[1]; msg.dpad_up = unpack::bit(ptr+2, 0); msg.dpad_down = unpack::bit(ptr+2, 1); msg.dpad_left = unpack::bit(ptr+2, 2); msg.dpad_right = unpack::bit(ptr+2, 3); msg.start = unpack::bit(ptr+2, 4); msg.back = unpack::bit(ptr+2, 5); msg.thumb_l = unpack::bit(ptr+2, 6); msg.thumb_r = unpack::bit(ptr+2, 7); msg.lb = unpack::bit(ptr+3, 0); msg.rb = unpack::bit(ptr+3, 1); msg.guide = unpack::bit(ptr+3, 2); msg.dummy1 = unpack::bit(ptr+3, 3); msg.a = unpack::bit(ptr+3, 4); msg.b = unpack::bit(ptr+3, 5); msg.x = unpack::bit(ptr+3, 6); msg.y = unpack::bit(ptr+3, 7); msg.lt = ptr[4]; msg.rt = ptr[5]; msg.x1 = unpack::int16le(ptr+6); msg.y1 = unpack::int16le(ptr+8); msg.x2 = unpack::int16le(ptr+10); msg.y2 = unpack::int16le(ptr+12); msg.dummy2 = unpack::int32le(ptr+14); msg.dummy3 = unpack::int16le(ptr+18); return true; } else if (data[0] == 0x00 && data[1] == 0x00 && data[2] == 0x00 && data[3] == 0x13) { // Battery status m_battery_status = data[4]; log_info("battery status: " << m_battery_status); } else if (data[0] == 0x00 && data[1] == 0x00 && data[2] == 0x00 && data[3] == 0xf0) { // 0x00 0x00 0x00 0xf0 0x00 ... is send after each button // press, doesn't seem to contain any information } else { log_debug("unknown: " << raw2str(data, len)); } } else { log_debug("unknown: " << raw2str(data, len)); } } return false; }
bool Xbox360WirelessController::parse(const uint8_t* data, int len, ControllerMessage* msg_out) { if (len == 0) { return false; } else { if (len == 2 && data[0] == 0x08) { // Connection Status Message if (data[1] == 0x00) { log_info("connection status: nothing"); // reset the controller into neutral position on disconnect msg_out->clear(); set_active(false); return true; } else if (data[1] == 0x80) { log_info("connection status: controller connected"); set_led_real(get_led()); set_active(true); } else if (data[1] == 0x40) { log_info("Connection status: headset connected"); } else if (data[1] == 0xc0) { log_info("Connection status: controller and headset connected"); set_led_real(get_led()); } else { log_info("Connection status: unknown"); } } else if (len == 29) { set_active(true); if (data[0] == 0x00 && data[1] == 0x0f && data[2] == 0x00 && data[3] == 0xf0) { // Initial Announc Message m_serial = (boost::format("%2x:%2x:%2x:%2x:%2x:%2x:%2x") % int(data[7]) % int(data[8]) % int(data[9]) % int(data[10]) % int(data[11]) % int(data[12]) % int(data[13])).str(); m_battery_status = data[17]; log_info("Serial: " << m_serial); log_info("Battery Status: " << m_battery_status); } else if (data[0] == 0x00 && data[1] == 0x01 && data[2] == 0x00 && data[3] == 0xf0 && data[4] == 0x00 && data[5] == 0x13) { // Event message const uint8_t* ptr = data + 4; msg_out->set_key(xbox.dpad_up, unpack::bit(ptr+2, 0)); msg_out->set_key(xbox.dpad_down, unpack::bit(ptr+2, 1)); msg_out->set_key(xbox.dpad_left, unpack::bit(ptr+2, 2)); msg_out->set_key(xbox.dpad_right, unpack::bit(ptr+2, 3)); msg_out->set_key(xbox.btn_start, unpack::bit(ptr+2, 4)); msg_out->set_key(xbox.btn_back, unpack::bit(ptr+2, 5)); msg_out->set_key(xbox.btn_thumb_l, unpack::bit(ptr+2, 6)); msg_out->set_key(xbox.btn_thumb_r, unpack::bit(ptr+2, 7)); msg_out->set_key(xbox.btn_lb, unpack::bit(ptr+3, 0)); msg_out->set_key(xbox.btn_rb, unpack::bit(ptr+3, 1)); msg_out->set_key(xbox.btn_guide, unpack::bit(ptr+3, 2)); //msg_out->dummy1 = unpack::bit(ptr+3, 3); msg_out->set_key(xbox.btn_a, unpack::bit(ptr+3, 4)); msg_out->set_key(xbox.btn_b, unpack::bit(ptr+3, 5)); msg_out->set_key(xbox.btn_x, unpack::bit(ptr+3, 6)); msg_out->set_key(xbox.btn_y, unpack::bit(ptr+3, 7)); msg_out->set_abs(xbox.abs_lt, ptr[4]); msg_out->set_abs(xbox.abs_rt, ptr[5]); msg_out->set_abs(xbox.abs_x1, unpack::int16le(ptr+6)); msg_out->set_abs(xbox.abs_y1, unpack::s16_invert(unpack::int16le(ptr+8))); msg_out->set_abs(xbox.abs_x2, unpack::int16le(ptr+10)); msg_out->set_abs(xbox.abs_y2, unpack::s16_invert(unpack::int16le(ptr+12))); return true; } else if (data[0] == 0x00 && data[1] == 0x00 && data[2] == 0x00 && data[3] == 0x13) { // Battery status m_battery_status = data[4]; log_info("battery status: " << m_battery_status); } else if (data[0] == 0x00 && data[1] == 0x00 && data[2] == 0x00 && data[3] == 0xf0) { // 0x00 0x00 0x00 0xf0 0x00 ... is send after each button // press, doesn't seem to contain any information } else { log_debug("unknown: " << raw2str(data, len)); } } else { log_debug("unknown: " << raw2str(data, len)); } } return false; }
bool Xbox360Controller::parse(uint8_t* data, int len, XboxGenericMsg* msg_out) { if (len == 0) { // happens with the Xbox360 controller every now and then, just // ignore, seems harmless, so just ignore //log_debug("zero length read"); } else if (len == 3 && data[0] == 0x01 && data[1] == 0x03) { log_debug("Xbox360Controller: LED Status: " << int(data[2])); } else if (len == 3 && data[0] == 0x03 && data[1] == 0x03) { // data[2] == 0x00 means that rumble is disabled // data[2] == 0x01 unknown, but rumble works // data[2] == 0x02 unknown, but rumble works // data[2] == 0x03 is default with rumble enabled log_info("rumble status: " << int(data[2])); } else if (len == 3 && data[0] == 0x08 && data[1] == 0x03) { // FIXME: maybe a proper indicator for the actvity on the chatpad // port, so that we don't have to send chatpad init if (data[2] == 0x00) { log_info("peripheral: none"); } else if (data[2] == 0x01) { log_info("peripheral: chatpad"); } else if (data[2] == 0x02) { log_info("peripheral: headset"); } else if (data[2] == 0x03) { log_info("peripheral: headset, chatpad"); } else { log_info("peripheral: unknown: " << int(data[2])); } } else if (len == 20 && data[0] == 0x00 && data[1] == 0x14) { msg_out->type = XBOX_MSG_XBOX360; Xbox360Msg& msg = msg_out->xbox360; msg.type = data[0]; msg.length = data[1]; msg.dpad_up = unpack::bit(data+2, 0); msg.dpad_down = unpack::bit(data+2, 1); msg.dpad_left = unpack::bit(data+2, 2); msg.dpad_right = unpack::bit(data+2, 3); msg.start = unpack::bit(data+2, 4); msg.back = unpack::bit(data+2, 5); msg.thumb_l = unpack::bit(data+2, 6); msg.thumb_r = unpack::bit(data+2, 7); msg.lb = unpack::bit(data+3, 0); msg.rb = unpack::bit(data+3, 1); msg.guide = unpack::bit(data+3, 2); msg.dummy1 = unpack::bit(data+3, 3); msg.a = unpack::bit(data+3, 4); msg.b = unpack::bit(data+3, 5); msg.x = unpack::bit(data+3, 6); msg.y = unpack::bit(data+3, 7); msg.lt = data[4]; msg.rt = data[5]; msg.x1 = unpack::int16le(data+6); msg.y1 = unpack::int16le(data+8); msg.x2 = unpack::int16le(data+10); msg.y2 = unpack::int16le(data+12); msg.dummy2 = unpack::int32le(data+14); msg.dummy3 = unpack::int16le(data+18); return true; } else { log_debug("unknown: " << raw2str(data, len)); } return false; }