int Response::getResponse(Device *device) { int res; memset(reportBuffer,0,sizeof(reportBuffer)); if (NULL == device->handle) { return -1; } res = hid_get_feature_report(device->handle, reportBuffer, sizeof(reportBuffer)); // qDebug() << "get report size:" << res; if (res!=-1) { deviceStatus = reportBuffer[1]; lastCommandType = reportBuffer[2]; lastCommandCRC = ((uint32_t *)(reportBuffer+3))[0]; lastCommandStatus = reportBuffer[7]; responseCRC = ((uint32_t *)(reportBuffer+61))[0]; memcpy(data,reportBuffer+8,PAYLOAD_SIZE); /* Copy Stick 2.0 status vom HID response data */ memcpy ((void*)&HID_Stick20Status_st,reportBuffer+1+OUTPUT_CMD_RESULT_STICK20_STATUS_START,sizeof (HID_Stick20Status_st)); DebugResponse (); return 0; } else { return -1; } }
/********************************************************** * Function get_relay_hidapi() * * Description: Get the current relay state * * Parameters: portname (in) - communication port * relay (in) - relay number * relay_state (out) - current relay state * serial (in) - serial number [not used] * * Return: 0 - success * -1 - fail *********************************************************/ int get_relay_hidapi(char* portname, uint8_t relay, relay_state_t* relay_state, char* serial) { hid_device *hid_dev; unsigned char buf[REPORT_LEN]; if (relay<FIRST_RELAY || relay>(FIRST_RELAY+g_num_relays-1)) { fprintf(stderr, "ERROR: Relay number out of range\n"); return -1; } /* Open HID API device */ if ((hid_dev = hid_open_path(portname)) == NULL) { fprintf(stderr, "unable to open HID API device %s\n", portname); return -2; } /* Read relay states requesting a feature report with Id 0x01 */ buf[0] = 0x01; if (hid_get_feature_report(hid_dev, buf, sizeof(buf)) != REPORT_LEN) { fprintf(stderr, "unable to read feature report from device %s (%ls)\n", portname, hid_error(hid_dev)); return -3; } //printf("DBG: Relay ID: %s\n", buf); //printf("DBG: Read relay bits %02X\n", buf[REPORT_RDDAT_OFFSET]); relay = relay-1; *relay_state = (buf[REPORT_RDDAT_OFFSET] & (0x01<<relay)) ? ON : OFF; hid_close(hid_dev); return 0; }
//----------------------------------------------------------------------------- bool HIDDevice::GetFeatureReport(UByte* data, UInt32 length) { if (DeviceHandle < 0) return false; int skipped_report_id = 0; int report_number = data[0]; if (report_number == 0x0) { /* Offset the return buffer by 1, so that the report ID will remain in byte 0. */ data++; length--; skipped_report_id = 1; } int r = hid_get_feature_report(DeviceHandle, data, length); // int r = ioctl(DeviceHandle, HIDIOCGFEATURE(length), data); if(r < 0) { OVR_DEBUG_LOG(("Error in LibOVR GetFeatureReport: %s",strerror(errno))); } return (r >= 0); }
int HID_API_EXPORT hid_read_timeout(hid_device *dev, unsigned char *data, size_t length, int milliseconds) { int res = -1; int report_number = data[0]; int skipped_report_id = 0; if (dev->output_endpoint <= 0) { if (data[0] == 0) length = 256; else length = 255; return hid_get_feature_report(dev, data, length); // if (report_number == 0x0) { // data++; // length--; // skipped_report_id = 1; // } // /* No interrput out endpoint. Use the Control Endpoint */ // res = libusb_control_transfer(dev->device_handle, // LIBUSB_REQUEST_TYPE_CLASS|LIBUSB_RECIPIENT_INTERFACE|LIBUSB_ENDPOINT_IN, // 0x01/*HID Set_Report*/, // (3/*HID output*/ << 8) | report_number, // dev->interface, // (unsigned char *)tmp_data, 255, // 1000/*timeout millis*/); // // if (res < 0) // return -1; // // if (skipped_report_id) { // length++; // } // // return res; } else { /* Use the interrupt out endpoint */ int actual_length; res = libusb_interrupt_transfer(dev->device_handle, dev->input_endpoint, (unsigned char*)data, length, &actual_length, 1000); if (res < 0) return -1; if (skipped_report_id) actual_length++; return actual_length; } }
uint32_t CDevice::VerifyBootloader() { uint32_t crc; int ret; hidbuf[0] = ID_BOOTLOADER_VERIFY; ret = hid_get_feature_report(handle, hidbuf, 6); crc = hidbuf[1]; crc |= hidbuf[2] << 8; crc |= hidbuf[3] << 16; crc |= hidbuf[4] << 24; // printf("bootloader crc32 = %08X, reportlen = %d\n", crc,ret); return(ret == 6 ? crc : 0); }
ByteString HidDevice::getFeatureReport(uint8_t reportId) { uint8_t buf[MAX_REPORT_LEN+1]; buf[0] = reportId; int r = hid_get_feature_report(devHandle, buf, sizeof(buf)); if(r<0) { std::string errorString; utf16BufferToUtf8String(errorString, hid_error(devHandle)); throw HidDeviceError(errorString); } return ByteString(buf+1, r-1); }
bool CDevice::GenericRead(int reportid, uint8_t *buf, int size, bool holdCS) { int ret; if (size > SPI_READMAX) { printf("Read too big.\n"); return(false); } hidbuf[0] = holdCS ? reportid : (reportid + 1); ret = hid_get_feature_report(handle, hidbuf, 64); if (ret < 0) return(false); memcpy(buf, hidbuf + 1, size); return(true); }
int relay_get_state(const char * path) { hid_device *dev; unsigned char buf[RELAY_COMMAND_SIZE]; if((dev = hid_open_path(path)) == NULL) { return -1; } buf[0] = 0x01; // get first page if(hid_get_feature_report(dev, buf, sizeof(buf)) == -1) { return -1; } /* printf("buffer -> %d %d %d %d %d %d %d %d %d\n", buf[0], buf[1], buf[2], buf[3], buf[4], buf[5], buf[6], buf[7], buf[8]); */ return buf[7] & 1; }
///////////////////////////////////////////////////////////////////////////////////////////// // Sensor Display Info // HID Type: Get Feature // HID Packet Length: 56 ///////////////////////////////////////////////////////////////////////////////////////////// BOOLEAN getSensorInfo( Device *dev ) { UInt8 Buffer[56]; //UInt16 CommandId; int res; Buffer[0] = 0x9; // DisplayInfo res = hid_get_feature_report(dev->hidapi_dev, Buffer, 56 ); if (res < 0) { return FALSE; } else { dev->sensorInfo.DistortionType = Buffer[3]; dev->sensorInfo.HResolution = DecodeUInt16(Buffer+4); dev->sensorInfo.VResolution = DecodeUInt16(Buffer+6); dev->sensorInfo.HScreenSize = DecodeUInt32(Buffer+8) * (1/1000000.f); dev->sensorInfo.VScreenSize = DecodeUInt32(Buffer+12) * (1/1000000.f); dev->sensorInfo.VCenter = DecodeUInt32(Buffer+16) * (1/1000000.f); dev->sensorInfo.LensSeparation = DecodeUInt32(Buffer+20) * (1/1000000.f); dev->sensorInfo.EyeToScreenDistance[0] = DecodeUInt32(Buffer+24) * (1/1000000.f); dev->sensorInfo.EyeToScreenDistance[1] = DecodeUInt32(Buffer+28) * (1/1000000.f); dev->sensorInfo.DistortionK[0] = DecodeFloat(Buffer+32); dev->sensorInfo.DistortionK[1] = DecodeFloat(Buffer+36); dev->sensorInfo.DistortionK[2] = DecodeFloat(Buffer+40); dev->sensorInfo.DistortionK[3] = DecodeFloat(Buffer+44); dev->sensorInfo.DistortionK[4] = DecodeFloat(Buffer+48); dev->sensorInfo.DistortionK[5] = DecodeFloat(Buffer+52); #if 0 { int i; printf ("\nSensor Info:\n"); for (i = 0; i < res; i++) printf("%hhx ", Buffer[i]); puts("\n"); printf ("\nR: %d x %d", dev->sensorInfo.HResolution, dev->sensorInfo.VResolution ); printf ("\tS: %f x %f\n", dev->sensorInfo.HScreenSize, dev->sensorInfo.VScreenSize ); } #endif } return TRUE; }
int vrpn_HidInterface::get_feature_report(size_t bytes, vrpn_uint8 *buffer) { if (!_working) { fprintf(stderr,"vrpn_HidInterface::get_feature_report(): Interface not currently working\n"); return -1; } int ret = hid_get_feature_report(_device, buffer, bytes); if (ret == -1) { fprintf(stderr, "vrpn_HidInterface::get_feature_report(): failed to get feature report\n"); const wchar_t * errmsg = hid_error(_device); if (errmsg) { fprintf(stderr, "vrpn_HidInterface::get_feature_report(): error message: %ls\n", errmsg); } } else { //fprintf(stderr, "vrpn_HidInterface::get_feature_report(): got feature report, %d bytes\n", static_cast<int>(bytes)); } return ret; }
int touchmouse_set_device_mode(touchmouse_device *dev, touchmouse_mode mode) { // We need to set two bits in a particular Feature report. We first fetch // the current state of the feature report, set the interesting bits, and // write that feature report back to the device. TM_SPEW("touchmouse_set_device_mode: Reading current config flags\n"); unsigned char data[27] = {0x22}; int transferred = 0; transferred = hid_get_feature_report(dev->dev, data, 27); if (transferred > 0) { TM_SPEW("%d bytes received:\n", transferred); int i; for(i = 0; i < transferred; i++) { TM_SPEW("%02X ", data[i]); } TM_SPEW("\n"); } if (transferred != 0x1B) { TM_ERROR("touchmouse_set_device_mode: Failed to read Feature 0x22 correctly; expected 27 bytes, got %d\n", transferred); return -1; } // This particular byte/setting appears to control the // "send all the raw input" flag. switch (mode) { case TOUCHMOUSE_DEFAULT: data[4] = 0x00; TM_DEBUG("touchmouse_set_device_mode: Trying to disable full touch updates...\n"); break; case TOUCHMOUSE_RAW_IMAGE: data[4] = 0x06; TM_DEBUG("touchmouse_set_device_mode: Trying to enable full touch updates...\n"); break; } transferred = hid_send_feature_report(dev->dev, data, 27); TM_SPEW("Wrote %d bytes\n", transferred); if (transferred == 0x1B) { TM_DEBUG("touchmouse_set_device_mode: Successfully set device mode.\n"); return 0; } TM_ERROR("touchmouse_set_device_mode: Failed to set device mode.\n"); return -1; }
bool CDevice::SramTransfer(uint32_t slot) { int ret; hidbuf[0] = ID_SPI_SRAM_TRANSFER; hidbuf[1] = (uint8_t)(slot); hidbuf[2] = (uint8_t)(slot >> 8); if (hid_send_feature_report(handle, hidbuf, 4) >= 0) { } while (1) { hidbuf[0] = ID_SPI_SRAM_TRANSFER_STATUS; ret = hid_get_feature_report(handle, hidbuf, 2); if (hidbuf[1] == 0) break; } return(true); }
bool CDevice::Selftest() { int ret; hidbuf[0] = ID_SELFTEST; hidbuf[1] = 0; ret = hid_send_feature_report(handle, hidbuf, 2); if (ret == -1) { wprintf(L"error: %s\n", hid_error(handle)); } uint32_t start = getTicks(); do { } while ((getTicks() - start) < 1000); hidbuf[1] = 0xFF; ret = hid_get_feature_report(handle, hidbuf, 2); printf("self-test code $%02X\n", hidbuf[1]); return(hidbuf[1] == 0 ? true : false); }
/*---------------------------------------------------------------------------*/ int t100::readData(uint8_t* buf,uint8_t len) { int rval; /* Reset the buffer */ memset(tempBuffer,0x00,256); /* Read the data */ rval = hid_get_feature_report(this->t100_handle, tempBuffer, len+1); if(rval < 0) { this->problem = true; return -1; } #ifdef LINUX /* Store the data */ for(int i = 2; i < (rval-1); ++i) { buf[i-2] = tempBuffer[i]; } #endif #ifdef OSX /* Store the data */ for(int i = 1; i < rval; ++i) { buf[i-1] = tempBuffer[i]; } #endif #if WIN /* Store the data */ for(int i = 2; i < (rval-1); ++i) { buf[i-2] = tempBuffer[i]; } #endif return (rval-1); }
JNIEXPORT jint JNICALL Java_com_codeminders_hidapi_HIDDevice_getFeatureReport (JNIEnv *env, jobject self, jbyteArray data) { hid_device *peer = getPeer(env, self); if(!peer) { throwIOException(env, peer); return 0; /* not an error, freed previously */ } jsize bufsize = env->GetArrayLength(data); jbyte *buf = env->GetByteArrayElements(data, NULL); int res = hid_get_feature_report(peer, (unsigned char*) buf, bufsize); env->ReleaseByteArrayElements(data, buf, res==-1?JNI_ABORT:0); if(res==-1) { throwIOException(env, peer); return 0; /* not an error, freed previously */ } return res; }
bool PSDualShock4Controller::getBTAddressesViaUSB(std::string& host, std::string& controller) { bool success = false; int res; unsigned char btg[PSDS4_BTADDR_GET_SIZE + 1]; unsigned char ctrl_char_buff[PSDS4_BTADDR_SIZE]; unsigned char host_char_buff[PSDS4_BTADDR_SIZE]; memset(btg, 0, sizeof(btg)); btg[0] = PSDualShock4_USBReport_GetBTAddr; res = hid_get_feature_report(HIDDetails.Handle, btg, sizeof(btg)); if (res == sizeof(btg)) { memcpy(host_char_buff, btg + 10, PSDS4_BTADDR_SIZE); host = ServerUtility::bluetooth_byte_addr_to_string(host_char_buff); memcpy(ctrl_char_buff, btg + 1, PSDS4_BTADDR_SIZE); controller = ServerUtility::bluetooth_byte_addr_to_string(ctrl_char_buff); success = true; } else { char hidapi_err_mbs[256]; bool valid_error_mesg = false; valid_error_mesg = hid_error_mbs(HIDDetails.Handle, hidapi_err_mbs, sizeof(hidapi_err_mbs)); if (valid_error_mesg) { SERVER_LOG_ERROR("PSDualShock4Controller::getBTAddress") << "HID ERROR: " << hidapi_err_mbs; } } return success; }
int CDevice::DiskRead(uint8_t *buf) { int result; hidbuf[0] = ID_DISK_READ; result = hid_get_feature_report(handle, hidbuf, DISK_READMAX + 2); // + reportID + sequence //hidapi increments the result by 1 to account for the report id, if it was a success if (result > 0) { result--; } //read time out if (result < 2) { printf("\nDisk read timed out\n"); return(-1); } //adapter will send incomplete/empty packets when it's out of data (end of disk) else if (result > 2) { memcpy(buf, hidbuf + 2, result - 2); //sequence out of order (data lost) if (hidbuf[1] != sequence++) { printf("\nDisk read sequence out of order (got %d, wanted %d)\n",hidbuf[1],sequence-1); return(-1); } else { // printf("read %d bytes\n", result - 2); return(result - 2); } } else { printf("\nDisk read returned no data\n"); return(0); } }
enum BOCA_FEATURE_REPORT_STATUS boca_hid_status_feature(boca_hid_printer_t *self) { enum BOCA_FEATURE_REPORT_STATUS ret = BOCA_REPORT_UNKNOWN; if (!self->device) return ret; unsigned char *buf = (unsigned char *) calloc(PACKET_SIZE, sizeof(byte)); buf[0] = 0x0; int byte_read = hid_get_feature_report(self->device, buf, sizeof(byte) * PACKET_SIZE); if(self->verbose) zsys_debug("hid printer: read %d bytes from feature port", byte_read); if (byte_read > 0) { if (byte_read == 2) ret = (enum BOCA_FEATURE_REPORT_STATUS) (int) buf[1]; else ret = (enum BOCA_FEATURE_REPORT_STATUS) (int) buf[0]; if (self->verbose) { zsys_debug("hid printer: BOCA status %s", boca_feature_report_display(ret)); } } else { zsys_warning("hid printer: could not read from BOCA %ls", hid_error(self->device)); } return ret; }
int LedDeviceLightpackHidapi::testAndOpen(hid_device_info *device, const std::string & requestedSerialNumber) { if ((device->vendor_id == USB_VENDOR_ID && device->product_id == USB_PRODUCT_ID) || (device->vendor_id == USB_OLD_VENDOR_ID && device->product_id == USB_OLD_PRODUCT_ID)) { Debug(_log, "Found a lightpack device. Retrieving more information..."); // get the serial number std::string serialNumber = ""; if (device->serial_number != nullptr) { // the serial number needs to be converted to a char array instead of wchar size_t size = wcslen(device->serial_number); serialNumber.resize(size, '.'); for (size_t i = 0; i < size; ++i) { int c = wctob(device->serial_number[i]); if (c != EOF) { serialNumber[i] = c; } } } else { Error(_log, "No serial number for Lightpack device"); } Debug(_log, "Lightpack device found: path=%s serial=%s", device->path.c_str(), serialNumber.c_str()); // check if this is the device we are looking for if (requestedSerialNumber.empty() || requestedSerialNumber == serialNumber) { // This is it! _deviceHandle = hid_open_path(device->path); if (_deviceHandle != nullptr) { _serialNumber = serialNumber; Info(_log, "Lightpack device successfully opened"); // get the firmware version uint8_t buffer[256]; buffer[0] = 0; // report id int error = hid_get_feature_report(_deviceHandle, buffer, sizeof(buffer)); if (error < 4) { Error(_log, "Unable to retrieve firmware version number from Lightpack device"); } else { _firmwareVersion.majorVersion = buffer[INDEX_FW_VER_MAJOR+1]; _firmwareVersion.minorVersion = buffer[INDEX_FW_VER_MINOR+1]; } // FOR TESTING PURPOSE: FORCE MAJOR VERSION TO 6 _firmwareVersion.majorVersion = 6; // disable smoothing of the chosen device disableSmoothing(); // determine the number of leds if (_firmwareVersion.majorVersion == 4) { _hwLedCount = 8; } else { _hwLedCount = 10; } // determine the bits per channel if (_firmwareVersion.majorVersion == 6) { // maybe also or version 7? The firmware suggest this is only for 6... (2013-11-13) _bitsPerChannel = 12; } else { _bitsPerChannel = 8; } // set the led buffer size (repport id + command + 6 bytes per led) _ledBuffer = std::vector<uint8_t>(2 + _hwLedCount * 6, 0); _ledBuffer[0] = 0x0; // report id _ledBuffer[1] = CMD_UPDATE_LEDS; // return success Debug(_log,"Lightpack device opened: path=%s serial=%s version=%s.%s.%s", device->path.c_str(), _serialNumber.c_str(), _firmwareVersion.majorVersion.c_str(), _firmwareVersion.minorVersion.c_str()); return 0; } else { Warning(_log, "Unable to open Lightpack device. Searching for other device"); } } } return -1; }
int main(int argc, char* argv[]) { if (argc > 1 && strcmp(argv[1], "--help") == 0) { printf("Usage: %s [on|off [<path>|<decimal int>|<hex int>|all]...]...\n", argv[0]); printf("\t'on' or 'off' is the command that is issued to all subsequent relays\n"); printf("\t<path> - determine the relay by path, usually '/dev/hidrawX'\n"); printf("\t<decimal int> - determine the relay by the internal number.\n"); printf("\t Be aware, that this number is not persistent,\n"); printf("\t and may change on device reconnection, software upgrade, or reboot.\n"); printf("\t<hex int> - determine the relay by a unique ID.\n"); printf("\t This ID is persistent, and will always identify the same relay.\n"); printf("\t'all' - apply the command to all relays.\n"); printf("\n\tCalling without parameters will list all the devices with the corresponding paths, internal numbers and IDs.\n\n"); printf("Example: %s on all off /dev/hidraw2 3 0x17F\n", argv[0]); printf("\tSwitches on all the relays except for three, determined by their path, internal number and unique ID respectively.\n"); return 0; } unsigned char buf[8]; unsigned long device_id; struct hid_device_info *devs, *cur_dev; hid_device *handle; int i=0; devs = hid_enumerate(0x16c0, 0x05df); if (devs == NULL) { printf("No devices found.\n"); return 0; } cur_dev = devs; while (cur_dev) { i++; handle = hid_open_path(cur_dev->path); if (handle) { device_id = 0; memset(buf, 0, sizeof(buf)); buf[0] = 0x1d; if (hid_send_feature_report(handle, buf, 8) == -1) { fprintf(stderr, "Error sending request to the device number %d path: %s\n", i, cur_dev->path); } if (hid_get_feature_report(handle, buf, 8) == -1) { fprintf(stderr, "Error getting response from the device number %d path: %s\n", i, cur_dev->path); } if (buf[0]==0x1d) { device_id = (buf[4] << 24) + (buf[5] << 16) + (buf[6] << 8) + buf[7]; } if (device_id == 0) { fprintf(stderr, "Unable to get unique ID for the device number %d path: %s\n", i, cur_dev->path); } //parsing input here (yes, for every device anew) int arg_on_off = 0; int on_off = 0; for (int arg = 1; arg < argc; arg++){ //we look which command was the most recent if(strcmp(argv[arg], "on") == 0) { arg_on_off = 1; continue; } if(strcmp(argv[arg], "off") == 0) { arg_on_off = -1; continue; } //"all" means that the most recent command applies to all if(strcmp(argv[arg], "all") == 0) { on_off = arg_on_off; continue; } //it's not a command, hence it's the device int device; if (sscanf (argv[arg], "%i", &device)!=1) { //match by path if (strcmp(argv[arg], cur_dev->path) == 0) on_off = arg_on_off; } else { if (argv[arg][0] == '0' && argv[arg][1] == 'x') { //hex int, it's a unique id if (device_id != 0 && device_id == device) on_off = arg_on_off; } else { //decimal int, match by number if (device == i) on_off = arg_on_off; } } } //by this point we have on_off set to 0,-1 or 1 char state[20] = "unknown"; //issue the command if needed if (on_off != 0) { memset(buf, sizeof(buf), 0); buf[0] = 0xe7; if(on_off == 1) //on buf[1] = 0x0; if(on_off == -1) //off buf[1] = 0x19; if (hid_send_feature_report(handle, buf, 8) == -1) { fprintf(stderr, "Error issuing the command to the device number %d path: %s\n", i, cur_dev->path); } } //check the result memset(buf, 0x7e, sizeof(buf)); if (hid_send_feature_report(handle, buf, 8) == -1) { fprintf(stderr, "Error checking state of the device number %d path: %s\n", i, cur_dev->path); } if (hid_get_feature_report(handle, buf, 8) == -1) { fprintf(stderr, "Error reading state of the device number %d path: %s\n", i, cur_dev->path); } if (buf[0] == 0x7e) { if (buf[1] == 0x19) sprintf(state, "off"); else if (buf[1] == 0) sprintf(state, "on"); } hid_close(handle); if (device_id) { printf("Device number %d path: %s unique ID: 0x%lx state: %s\n", i, cur_dev->path, device_id, state); } else { printf("Device number %d path: %s state: %s\n", i, cur_dev->path, state); } } else { fprintf(stderr, "Unable to access the device number %d path: %s\n", i, cur_dev->path); } cur_dev = cur_dev->next; } hid_free_enumeration(devs); return 0; }
static int get_feature_report(rift_priv* priv, rift_sensor_feature_cmd cmd, unsigned char* buf) { memset(buf, 0, FEATURE_BUFFER_SIZE); buf[0] = (unsigned char)cmd; return hid_get_feature_report(priv->handle, buf, FEATURE_BUFFER_SIZE); }
int main(int argc, char* argv[]) { int res; unsigned char buf[256]; #define MAX_STR 255 wchar_t wstr[MAX_STR]; hid_device *handle; int i; #ifdef WIN32 UNREFERENCED_PARAMETER(argc); UNREFERENCED_PARAMETER(argv); #endif struct hid_device_info *devs, *cur_dev; if (hid_init()) return -1; devs = hid_enumerate(0x0, 0x0); cur_dev = devs; while (cur_dev) { printf("Device Found\n type: %04hx %04hx\n path: %s\n serial_number: %ls", cur_dev->vendor_id, cur_dev->product_id, cur_dev->path, cur_dev->serial_number); printf("\n"); printf(" Manufacturer: %ls\n", cur_dev->manufacturer_string); printf(" Product: %ls\n", cur_dev->product_string); printf(" Release: %hx\n", cur_dev->release_number); printf(" Interface: %d\n", cur_dev->interface_number); printf("\n"); cur_dev = cur_dev->next; } hid_free_enumeration(devs); // Set up the command buffer. memset(buf,0x00,sizeof(buf)); buf[0] = 0x01; buf[1] = 0x81; // Open the device using the VID, PID, // and optionally the Serial number. ////handle = hid_open(0x4d8, 0x3f, L"12345"); handle = hid_open(0x4d8, 0x3f, NULL); if (!handle) { printf("unable to open device\n"); return 1; } // Read the Manufacturer String wstr[0] = 0x0000; res = hid_get_manufacturer_string(handle, wstr, MAX_STR); if (res < 0) printf("Unable to read manufacturer string\n"); printf("Manufacturer String: %ls\n", wstr); // Read the Product String wstr[0] = 0x0000; res = hid_get_product_string(handle, wstr, MAX_STR); if (res < 0) printf("Unable to read product string\n"); printf("Product String: %ls\n", wstr); // Read the Serial Number String wstr[0] = 0x0000; res = hid_get_serial_number_string(handle, wstr, MAX_STR); if (res < 0) printf("Unable to read serial number string\n"); printf("Serial Number String: (%d) %ls", wstr[0], wstr); printf("\n"); // Read Indexed String 1 wstr[0] = 0x0000; res = hid_get_indexed_string(handle, 1, wstr, MAX_STR); if (res < 0) printf("Unable to read indexed string 1\n"); printf("Indexed String 1: %ls\n", wstr); // Set the hid_read() function to be non-blocking. hid_set_nonblocking(handle, 1); // Try to read from the device. There shoud be no // data here, but execution should not block. res = hid_read(handle, buf, 17); // Send a Feature Report to the device buf[0] = 0x2; buf[1] = 0xa0; buf[2] = 0x0a; buf[3] = 0x00; buf[4] = 0x00; res = hid_send_feature_report(handle, buf, 17); if (res < 0) { printf("Unable to send a feature report.\n"); } memset(buf,0,sizeof(buf)); // Read a Feature Report from the device buf[0] = 0x2; res = hid_get_feature_report(handle, buf, sizeof(buf)); if (res < 0) { printf("Unable to get a feature report.\n"); printf("%ls", hid_error(handle)); } else { // Print out the returned buffer. printf("Feature Report\n "); for (i = 0; i < res; i++) printf("%02hhx ", buf[i]); printf("\n"); } memset(buf,0,sizeof(buf)); // Toggle LED (cmd 0x80). The first byte is the report number (0x1). buf[0] = 0x1; buf[1] = 0x80; res = hid_write(handle, buf, 17); if (res < 0) { printf("Unable to write()\n"); printf("Error: %ls\n", hid_error(handle)); } // Request state (cmd 0x81). The first byte is the report number (0x1). buf[0] = 0x1; buf[1] = 0x81; hid_write(handle, buf, 17); if (res < 0) printf("Unable to write() (2)\n"); // Read requested state. hid_read() has been set to be // non-blocking by the call to hid_set_nonblocking() above. // This loop demonstrates the non-blocking nature of hid_read(). res = 0; while (res == 0) { res = hid_read(handle, buf, sizeof(buf)); if (res == 0) printf("waiting...\n"); if (res < 0) printf("Unable to read()\n"); #ifdef WIN32 Sleep(500); #else usleep(500*1000); #endif } printf("Data read:\n "); // Print out the returned buffer. for (i = 0; i < res; i++) printf("%02hhx ", buf[i]); printf("\n"); hid_close(handle); /* Free static HIDAPI objects. */ hid_exit(); #ifdef WIN32 system("pause"); #endif return 0; }
int main(int argc, char* argv[]) { int res; unsigned char buf[65]; #define MAX_STR 255 wchar_t wstr[MAX_STR]; hid_device *handle; int i; // Enumerate and print the HID devices on the system struct hid_device_info *devs, *cur_dev; devs = hid_enumerate(0x0, 0x0); cur_dev = devs; while (cur_dev) { printf("Device Found\n type: %04hx %04hx\n path: %s\n serial_number: %ls", cur_dev->vendor_id, cur_dev->product_id, cur_dev->path, cur_dev->serial_number); printf("\n"); printf(" Manufacturer: %ls\n", cur_dev->manufacturer_string); printf(" Product: %ls\n", cur_dev->product_string); printf("\n"); cur_dev = cur_dev->next; } hid_free_enumeration(devs); // Open the device using the VID, PID, // and optionally the Serial number. handle = hid_open(0x8021, 0x1941, NULL); // Read the Manufacturer String res = hid_get_manufacturer_string(handle, wstr, MAX_STR); printf("Manufacturer String: %ls\n", wstr); // Read the Product String res = hid_get_product_string(handle, wstr, MAX_STR); printf("Product String: %ls\n", wstr); // Read the Serial Number String res = hid_get_serial_number_string(handle, wstr, MAX_STR); printf("Serial Number String: %ls", wstr); printf("\n"); // Send a Feature Report to the device buf[0] = 0x2; // First byte is report number buf[1] = 0xa0; buf[2] = 0x0a; res = hid_send_feature_report(handle, buf, 17); // Read a Feature Report from the device buf[0] = 0x2; res = hid_get_feature_report(handle, buf, sizeof(buf)); // Print out the returned buffer. printf("Feature Report\n "); for (i = 0; i < res; i++) printf("%02hhx ", buf[i]); printf("\n"); // Set the hid_read() function to be non-blocking. hid_set_nonblocking(handle, 1); // Send an Output report to toggle the LED (cmd 0x80) buf[0] = 1; // First byte is report number buf[1] = 0x80; res = hid_write(handle, buf, 65); // Send an Output report to request the state (cmd 0x81) buf[1] = 0x81; hid_write(handle, buf, 65); // Read requested state res = hid_read(handle, buf, 65); if (res < 0) printf("Unable to read()\n"); // Print out the returned buffer. for (i = 0; i < res; i++) printf("buf[%d]: %d\n", i, buf[i]); return 0; }
int main(int argc, char *argv[]) { int res; hid_device *handle; unsigned char command[2] = {0}; unsigned char report[9] = {0}; res = hid_init(); if (res < 0) return -1; handle = hid_open(0x4d8, 0xf6fe, NULL); if (handle == NULL) return -1; command[0] = '\x10'; res = hid_send_feature_report(handle, command, 2); if (res < 0) return -1; printf("Switched LCD backlight off\n"); command[0] = '\x40'; res = hid_send_feature_report(handle, command, 2); if (res < 0) return -1; printf("Switched buzzer off\n"); command[0] = '\xa2'; res = hid_send_feature_report(handle, command, 2); if (res < 0) return -1; printf("Reset counters... counting...\n"); sleep(30); res = hid_get_feature_report(handle, report, 9); if (res < 0) return -1; unsigned int clock = report[1] + report[2] * 256 + report[3] * 256 * 256; unsigned int counts = report[5] + report[6] * 256 + report[7] * 256 * 256; printf("Clock: %i, counts: %i\n", clock, counts); double cpm = counts * 1000.0 * 60 / clock; printf("%g CPM\n", cpm); double uSvph = cpm / 171.2; printf("%g microSv/h\n", uSvph); double ccpm = cpm / (1 - (cpm * (200e-6/60))); printf("%g corrected CPM\n", ccpm); double cuSvph = ccpm / 171.2; double std = (sqrt(counts) * 1000.0 * 60 / clock) / 171.2; printf("%g+-%g microSv/h\n", cuSvph, std); if (argc == 2) { char *thingspeak_command = NULL; res = asprintf(&thingspeak_command, "curl -v -k --data 'api_key=%s&field1=%f&field2=%f&field3=%f&field4=%f&field5=%f' https://api.thingspeak.com/update", argv[1], cpm, uSvph, ccpm, cuSvph, std); if (res < 0) return -1; res = system(thingspeak_command); if (res < 0) { printf("Cannot upload data to ThingSpeak\n"); return -1; } else if (WEXITSTATUS(res) != 0) { printf("cURL failed to upload data to ThingSpeak\n"); return -1; } free(thingspeak_command); thingspeak_command = NULL; } res = hid_exit(); if (res < 0) return -1; return 0; }
bool PSNaviController::getBTAddress(std::string& host, std::string& controller) { bool success = false; if (IsBluetooth && !controller.empty()) { std::replace(controller.begin(), controller.end(), '-', ':'); std::transform(controller.begin(), controller.end(), controller.begin(), ::tolower); //TODO: If the third entry is not : and length is PSNAVI_BTADDR_SIZE // std::stringstream ss; // ss << controller.substr(0, 2) << ":" << controller.substr(2, 2) << // ":" << controller.substr(4, 2) << ":" << controller.substr(6, 2) << // ":" << controller.substr(8, 2) << ":" << controller.substr(10, 2); // controller = ss.str(); success = true; } else { int res; unsigned char btg[PSNAVI_BTADDR_GET_SIZE]; unsigned char ctrl_char_buff[PSNAVI_BTADDR_SIZE]; memset(btg, 0, sizeof(btg)); btg[0] = PSNavi_Req_GetBTAddr; /* _WIN32 only has move->handle_addr for getting bluetooth address. */ if (HIDDetails.Handle_addr) { res = hid_get_feature_report(HIDDetails.Handle_addr, btg, sizeof(btg)); } else { res = hid_get_feature_report(HIDDetails.Handle, btg, sizeof(btg)); } if (res == sizeof(btg)) { memcpy(ctrl_char_buff, btg + 2, PSNAVI_BTADDR_SIZE); controller = btAddrUcharToString(ctrl_char_buff); success = true; } else { char hidapi_err_mbs[256]; bool valid_error_mesg= false; if (HIDDetails.Handle_addr) { valid_error_mesg = hid_error_mbs(HIDDetails.Handle_addr, hidapi_err_mbs, sizeof(hidapi_err_mbs)); } else { valid_error_mesg = hid_error_mbs(HIDDetails.Handle, hidapi_err_mbs, sizeof(hidapi_err_mbs)); } if (valid_error_mesg) { SERVER_LOG_ERROR("PSNaviController::getBTAddress") << "HID ERROR: " << hidapi_err_mbs; } } } return success; }
int main( int argc, char *argv[]) { struct relay *relays = 0; unsigned char buf[9];// 1 extra byte for the report ID char arg_t[20] = {'\0'}; int debug = 0; int num_relays = 2; char *token; const char delimiters[] = "_="; int i; struct hid_device_info *devs, *cur_dev; hid_device *handle; int size = sizeof(struct relay); unsigned short vendor_id = 0x16c0; unsigned short product_id = 0x05df; char *vendor, *product; /* allocate the memeory for all the relays */ if (argc > 1) { relays = malloc(size*(argc+1)); /* Yeah, I know. Not using the first member */ relays[0].this_serial[0] = '\0'; } else debug = 1; /* loop through the command line and grab the relay details */ for (i = 1 ; i < argc; i++ ) { /* copy the arg and bounds check */ strncpy(arg_t,argv[i],19); arg_t[19] = '\0'; token = strtok(arg_t, delimiters); if (token != NULL) { strcpy(relays[i].this_serial,token); } token = strtok((char *)NULL, delimiters); if (token != NULL) { relays[i].relay_num = atoi(token); } token = strtok(NULL, delimiters); if (token != NULL) { if (atoi(token)) { relays[i].state = ON; } else { relays[i].state = OFF; } } fprintf(stderr,"Orig: %s, Serial: %s, Relay: %d State: %x\n",arg_t,relays[i].this_serial,relays[i].relay_num,relays[i].state); relays[i].found = 0; } product = getenv("USBID"); if (product != NULL) { vendor = strsep(&product, ":"); if (vendor && *vendor) { vendor_id = strtol(vendor, NULL, 16); } if (product && *product) { product_id = strtol(product, NULL, 16); } } devs = hid_enumerate(vendor_id, product_id); cur_dev = devs; while (cur_dev) { fprintf(stderr,"Device Found\n type: %04hx %04hx\n path: %s\n serial_number: %ls", cur_dev->vendor_id, cur_dev->product_id, cur_dev->path, cur_dev->serial_number); fprintf(stderr,"\n"); fprintf(stderr," Manufacturer: %ls\n", cur_dev->manufacturer_string); fprintf(stderr," Product: %ls\n", cur_dev->product_string); fprintf(stderr," Release: %hx\n", cur_dev->release_number); fprintf(stderr," Interface: %d\n", cur_dev->interface_number); // The product string is USBRelayx where x is number of relays read to the \0 in case there are more than 9 num_relays = atoi((const char *)&cur_dev->product_string[8] ); fprintf(stderr," Number of Relays = %d\n",num_relays); handle = hid_open_path(cur_dev->path); if (!handle) { fprintf(stderr,"unable to open device\n"); return 1; } buf[0] = 0x01; int ret = hid_get_feature_report(handle,buf,sizeof(buf)); if (ret == -1) { perror("hid_get_feature_report"); exit(1); } if (debug) { for ( i = 0; i < num_relays ; i++ ) { if (buf[7] & 1 << i) { printf("%s_%d=1\n",buf,i+1); } else { printf("%s_%d=0\n",buf,i+1); } } } /* loop through the supplied command line and try to match the serial */ for (i=1;i<argc;i++) { fprintf(stderr,"Serial: %s, Relay: %d State: %x \n",relays[i].this_serial,relays[i].relay_num,relays[i].state); if (!strcmp(relays[i].this_serial, (const char *) buf)) { fprintf(stderr,"%d HID Serial: %s ", i, buf); fprintf(stderr,"Serial: %s, Relay: %d State: %x\n",relays[i].this_serial,relays[i].relay_num,relays[i].state); operate_relay(handle,relays[i].relay_num,relays[i].state); relays[i].found = 1; } } hid_close(handle); fprintf(stderr,"\n"); cur_dev = cur_dev->next; } hid_free_enumeration(devs); /* Free static HIDAPI objects. */ hid_exit(); for (i=1;i<argc;i++){ fprintf(stderr,"Serial: %s, Relay: %d State: %x ",relays[i].this_serial,relays[i].relay_num,relays[i].state); if (relays[i].found ) fprintf(stderr,"--- Found\n"); else fprintf(stderr,"--- Not Found\n"); } if (relays) free(relays); exit(0); }
int main(int argc, char** argv) { int openall = 0; int nogamma = 0; int16_t arg=0; static int vid,pid; int rc; char tmpstr[100]; uint16_t seed = time(NULL); srand(seed); memset( cmdbuf, 0, sizeof(cmdbuf)); static int cmd = CMD_NONE; vid = blink1_vid(), pid = blink1_pid(); // parse options int option_index = 0, opt; char* opt_str = "aqvhm:t:d:U:u:gn:"; static struct option loptions[] = { {"all", no_argument, 0, 'a'}, {"verbose", optional_argument, 0, 'v'}, {"quiet", optional_argument, 0, 'q'}, {"millis", required_argument, 0, 'm'}, {"delay", required_argument, 0, 't'}, {"id", required_argument, 0, 'd'}, {"num", required_argument, 0, 'n'}, {"nogamma", no_argument, 0, 'g'}, {"help", no_argument, 0, 'h'}, {"list", no_argument, &cmd, CMD_LIST }, {"hidread", no_argument, &cmd, CMD_HIDREAD }, {"hidwrite", required_argument, &cmd, CMD_HIDWRITE }, {"eeread", required_argument, &cmd, CMD_EEREAD }, {"eewrite", required_argument, &cmd, CMD_EEWRITE }, {"rgb", required_argument, &cmd, CMD_RGB }, {"savergb", required_argument, &cmd, CMD_SAVERGB }, {"readrgb", required_argument, &cmd, CMD_READRGB }, {"off", no_argument, &cmd, CMD_OFF }, {"on", no_argument, &cmd, CMD_ON }, {"red", no_argument, &cmd, CMD_RED }, {"green", no_argument, &cmd, CMD_GRN }, {"blue", no_argument, &cmd, CMD_BLU}, {"blink", required_argument, &cmd, CMD_BLINK}, {"play", required_argument, &cmd, CMD_PLAY}, {"random", required_argument, &cmd, CMD_RANDOM }, {"version", no_argument, &cmd, CMD_VERSION }, {"serialnumread", no_argument, &cmd, CMD_SERIALNUMREAD }, {"serialnumwrite",required_argument, &cmd,CMD_SERIALNUMWRITE }, {"servertickle", required_argument, &cmd, CMD_SERVERDOWN }, {"vid", required_argument, 0, 'U'}, // FIXME: This sucks {"pid", required_argument, 0, 'u'}, {NULL, 0, 0, 0} }; while(1) { opt = getopt_long(argc, argv, opt_str, loptions, &option_index); if (opt==-1) break; // parsed all the args switch (opt) { case 0: // deal with long opts that have no short opts switch(cmd) { case CMD_RGB: hexread(rgbbuf, optarg, sizeof(rgbbuf)); break; case CMD_HIDWRITE: case CMD_EEREAD: case CMD_EEWRITE: case CMD_SAVERGB: case CMD_READRGB: case CMD_BLINK: case CMD_PLAY: hexread(cmdbuf, optarg, sizeof(cmdbuf)); // cmd w/ hexlist arg break; case CMD_RANDOM: case CMD_SERVERDOWN: if( optarg ) arg = strtol(optarg,NULL,0); // cmd w/ number arg break; case CMD_SERIALNUMWRITE: strcpy(tmpstr, optarg); break; case CMD_ON: rgbbuf[0] = 255; rgbbuf[1] = 255; rgbbuf[2] = 255; break; case CMD_OFF: rgbbuf[0] = 0; rgbbuf[1] = 0; rgbbuf[2] = 0; break; case CMD_RED: rgbbuf[0] = 255; break; case CMD_GRN: rgbbuf[1] = 255; break; case CMD_BLU: rgbbuf[2] = 255; break; } // switch(cmd) break; case 'g': nogamma = 1; case 'a': openall = 1; break; case 'm': millis = strtol(optarg,NULL,10); break; case 't': delayMillis = strtol(optarg,NULL,10); break; case 'n': ledn = strtol(optarg,NULL,10); break; case 'q': if( optarg==NULL ) quiet++; else quiet = strtol(optarg,NULL,0); break; case 'v': if( optarg==NULL ) verbose++; else verbose = strtol(optarg,NULL,0); break; case 'd': if( strcmp(optarg,"all") == 0 ) { numDevicesToUse = 0; //blink1_max_devices; for( int i=0; i< blink1_max_devices; i++) { deviceIds[i] = i; } } else { numDevicesToUse = hexread(deviceIds,optarg,sizeof(deviceIds)); } break; case 'U': vid = strtol(optarg,NULL,0); break; case 'u': pid = strtol(optarg,NULL,0); break; case 'h': usage( "blink1-tool" ); exit(1); break; } } if(argc < 2){ usage( "blink1-tool" ); exit(1); } //FIXME: confusing if( nogamma ) { if ( !quiet ) { printf("disabling auto degamma\n"); } blink1_disableDegamma(); } // debug (not on Windows though, no getuid()) /* if( 0 ) { uid_t id = getuid(); printf("userid:%d\n",id); wchar_t myser[10]; dev = blink1_open(); hid_get_serial_number_string(dev, myser, 10); printf("ser:%ls\n",myser); } */ // get a list of all devices and their paths int count = blink1_enumerateByVidPid(vid,pid); if( count == 0 ) { if ( !quiet ) { printf("no blink(1) devices found\n"); } exit(1); } if( numDevicesToUse == 0 ) numDevicesToUse = count; //if( !dev_serial ) // dev_serial = blink1_getCachedSerial( deviceIds[0] ); if( verbose && !quiet ) { printf("deviceId[0] = %d\n", deviceIds[0]); //printf("cached path = '%ls'\n", dev_serial); for( int i=0; i< count; i++ ) { printf("%d: serial: '%ls'\n", i,blink1_getCachedSerial(i) ); } } // actually open up the device to start talking to it dev = blink1_openById( deviceIds[0] ); if( dev == NULL ) { if ( !quiet ) { printf("cannot open blink(1), bad serial number\n"); } exit(1); } // an idea: // blink1 mk2 does gamma correction in hardware //if( blink1_getVersion() >= 200 ) { // nogamma = 1; //} if( cmd == CMD_LIST ) { printf("blink(1) list: \n"); for( int i=0; i< count; i++ ) { printf("id:%d - serialnum:%ls\n", i, blink1_getCachedSerial(i) ); } } else if( cmd == CMD_HIDREAD ) { printf("hidread: "); int len = sizeof(cmdbuf); if((rc = hid_get_feature_report(dev, cmdbuf, len)) == -1){ fprintf(stderr,"error reading data: %s\n",blink1_error_msg(rc)); } else { hexdump(cmdbuf, sizeof(cmdbuf)); } } else if( cmd == CMD_HIDWRITE ) { if ( !quiet ) { printf("hidwrite: "); hexdump(cmdbuf,sizeof(cmdbuf)); } if((rc = hid_send_feature_report(dev, cmdbuf, sizeof(cmdbuf))) == -1) { fprintf(stderr,"error writing data: %d\n",rc); } } else if( cmd == CMD_EEREAD ) { // FIXME printf("eeread: addr 0x%2.2x = ", cmdbuf[0]); uint8_t val = 0; rc = blink1_eeread(dev, cmdbuf[0], &val ); if( rc==-1 ) { // on error printf("error\n"); } else { printf("%2.2x\n", val); } } else if( cmd == CMD_EEWRITE ) { // FIXME if ( !quiet ) { printf("eewrite: \n"); } rc = blink1_eewrite(dev, cmdbuf[0], cmdbuf[1] ); if( rc==-1 && !quiet ) { // error printf("error\n"); } } else if( cmd == CMD_VERSION ) { printf("firmware version: "); rc = blink1_getVersion(dev); printf("%d\n", rc ); } else if( cmd == CMD_RGB || cmd == CMD_ON || cmd == CMD_OFF || cmd == CMD_RED || cmd == CMD_BLU || cmd ==CMD_GRN ) { blink1_close(dev); // close global device, open as needed uint8_t r = rgbbuf[0]; uint8_t g = rgbbuf[1]; uint8_t b = rgbbuf[2]; for( int i=0; i< numDevicesToUse; i++ ) { dev = blink1_openById( deviceIds[i] ); if( dev == NULL ) continue; if ( !quiet ) { printf("set dev:%d to rgb:0x%2.2x,0x%2.2x,0x%2.2x over %d msec\n", deviceIds[i],r,g,b,millis); } if( ledn==0 ) { rc = blink1_fadeToRGB(dev,millis, r,g,b); } else { rc = blink1_fadeToRGBN(dev,millis,r,g,b, ledn); } if( rc == -1 && !quiet ) { // on error, do something, anything. come on. printf("error on fadeToRGB\n"); } blink1_close( dev ); } } else if( cmd == CMD_PLAY ) { uint8_t play = cmdbuf[0]; uint8_t pos = cmdbuf[1]; if ( !quiet ) { printf("%s color pattern at pos %d\n", ((play)?"playing":"stopping"),pos); } rc = blink1_play(dev, play, pos); if( rc == -1 && !quiet ) { } } else if( cmd == CMD_SAVERGB ) { uint8_t r = cmdbuf[0]; uint8_t g = cmdbuf[1]; uint8_t b = cmdbuf[2]; uint8_t p = cmdbuf[3]; if ( !quiet ) { printf("saving rgb: 0x%2.2x,0x%2.2x,0x%2.2x to pos %d\n", r,g,b,p ); } rc = blink1_writePatternLine(dev, millis, r,g,b, p ); if( rc==-1 && !quiet ) { printf("error on writePatternLine\n"); } } else if( cmd == CMD_READRGB ) { uint8_t p = cmdbuf[0]; uint8_t r,g,b; uint16_t msecs; printf("reading rgb at pos %d: ", p ); rc = blink1_readPatternLine(dev, &msecs, &r,&g,&b, p ); if( rc==-1 && !quiet ) { printf("error on writePatternLine\n"); } printf("r,g,b = %x,%x,%x millis:%d\n", r,g,b, msecs); } else if( cmd == CMD_RANDOM ) { int cnt = blink1_getCachedCount(); if( cnt>1 ) blink1_close(dev); // close global device, open as needed if ( !quiet ) { printf("random %d times: \n", arg); } for( int i=0; i<arg; i++ ) { uint8_t r = rand()%255; uint8_t g = rand()%255; uint8_t b = rand()%255 ; uint8_t id = rand() % blink1_getCachedCount(); if ( !quiet ) { printf("%d: %d/%d : %2.2x,%2.2x,%2.2x \n", i, id, blink1_getCachedCount(), r,g,b); } hid_device* mydev = dev; if( cnt > 1 ) mydev = blink1_openById( id ); if( ledn == 0 ) { rc = blink1_fadeToRGB(mydev, millis,r,g,b); } else { uint8_t n = 1 + rand() % ledn; rc = blink1_fadeToRGBN(mydev, millis,r,g,b,n); } if( rc == -1 && !quiet ) { // on error, do something, anything. come on. printf("error during random\n"); //break; } if( cnt > 1 ) blink1_close( mydev ); blink1_sleep(delayMillis); } } else if( cmd == CMD_BLINK ) { uint8_t n = cmdbuf[0]; uint8_t r = rgbbuf[0]; uint8_t g = rgbbuf[1]; uint8_t b = rgbbuf[2]; if( r == 0 && b == 0 && g == 0 ) { r = g = b = 255; } if ( !quiet ) { printf("blink %d times rgb:%x,%x,%x: \n", n,r,g,b); } for( int i=0; i<n; i++ ) { rc = blink1_fadeToRGB(dev, millis,r,g,b); blink1_sleep(delayMillis); rc = blink1_fadeToRGB(dev, millis,0,0,0); blink1_sleep(delayMillis); } } else if( cmd == CMD_SERVERDOWN ) { int on = arg; if ( !quiet ) { printf("setting serverdown %s (at %d millis)\n", ((on)?"ON":"OFF"), delayMillis); } blink1_serverdown( dev, on, delayMillis ); } // use caution with this, could make your blink(1) unusable // --serialnumwrite abcd1234 else if( cmd == CMD_SERIALNUMWRITE ) { if ( !quiet ) { printf("serial number write: %s\n",tmpstr); } //for( int i=0; i<4; i++) printf("%2.2X,",cmdbuf[i]); //printf("\n"); if( (rc = blink1_serialnumwrite( dev, tmpstr)) == -1 ) { fprintf(stderr,"error writing new serial number: %d\n",rc); } } return 0; }
/********************************************************** * Function detect_relay_card_hidapi() * * Description: Detect the HID API compatible relay card * * Parameters: portname (out) - pointer to a string where * the detected com port will * be stored * num_relays(out)- pointer to number of relays * serial(in) - pointer to a string containing * serial number [optional] * * Return: 0 - success * -1 - fail, no relay card found *********************************************************/ int detect_relay_card_hidapi(char* portname, uint8_t* num_relays, char* serial, relay_info_t** relay_info) { struct hid_device_info *devs, *nextdev; hid_device *hid_dev; unsigned char buf[REPORT_LEN]; uint8_t found=0; uint8_t num; relay_info_t* rinfo; if ((devs = hid_enumerate(VENDOR_ID, DEVICE_ID)) == NULL) { return -1; } if (devs->product_string == NULL || devs->path == NULL) { return -2; } /* Find controller with matching serial number if it's specified */ buf[0]=0; nextdev = devs; while (nextdev) { /* Open HID API device */ if ((hid_dev = hid_open_path(nextdev->path)) == NULL) { fprintf(stderr, "unable to open HID API device %s\n", portname); return -3; } /* Read relay Id requesting a feature report with Id 0x01 */ buf[0] = 0x01; if (hid_get_feature_report(hid_dev, buf, sizeof(buf)) != REPORT_LEN) { fprintf(stderr, "unable to read feature report from device %s (%ls)\n", portname, hid_error(hid_dev)); return -4; } //printf("DBG: Relay ID: %s\n", buf); hid_close(hid_dev); if (relay_info != NULL) { // Save serial number and type in current relay info struct (*relay_info)->relay_type = HID_API_RELAY_TYPE; strcpy((*relay_info)->serial, (char *)buf); // Allocate new struct rinfo = malloc(sizeof(relay_info_t)); rinfo->next = NULL; // Link current to new struct (*relay_info)->next = rinfo; // Move pointer to new struct *relay_info = rinfo; } else if (serial == NULL || !strcmp(serial, (char *)buf)) { found = 1; break; } nextdev = nextdev->next; } if (found == 0) { return -5; } //printf("DBG: card %ls found\n", devs->product_string); /* Get number of relays from product description */ num = atoi((const char *)(nextdev->product_string+strlen(PRODUCT_STR_BASE))); if (num>0) { g_num_relays = num; } /* Return parameters */ if (num_relays!=NULL) *num_relays = g_num_relays; sprintf(portname, "%s", nextdev->path); hid_free_enumeration(devs); return 0; }