static int yLinSetErrEx(u32 line,char *intro, int err,char *errmsg) { const char *msg; if(errmsg==NULL) return YAPI_IO_ERROR; switch(err){ case LIBUSB_SUCCESS: msg="Success (no error)";break; case LIBUSB_ERROR_IO: msg="Input/output error"; break; case LIBUSB_ERROR_INVALID_PARAM:msg="Invalid parameter"; break; case LIBUSB_ERROR_ACCESS: msg="Access denied (insufficient permissions)"; break; case LIBUSB_ERROR_NO_DEVICE: msg="No such device (it may have been disconnected)"; break; case LIBUSB_ERROR_NOT_FOUND: msg="Entity not found"; break; case LIBUSB_ERROR_BUSY: msg="Resource busy"; break; case LIBUSB_ERROR_TIMEOUT: msg="Operation timed out"; break; case LIBUSB_ERROR_OVERFLOW: msg="Overflow"; break; case LIBUSB_ERROR_PIPE: msg="Pipe error"; break; case LIBUSB_ERROR_INTERRUPTED: msg="System call interrupted (perhaps due to signal)"; break; case LIBUSB_ERROR_NO_MEM: msg="Insufficient memory"; break; case LIBUSB_ERROR_NOT_SUPPORTED:msg="Operation not supported or unimplemented on this platform"; break; default: case LIBUSB_ERROR_OTHER: msg="Other error"; break; } if (intro){ YSPRINTF(errmsg,YOCTO_ERRMSG_LEN,"%s:%s",intro,msg); } else{ YSPRINTF(errmsg,YOCTO_ERRMSG_LEN,"LIN(%d):%s",line,msg); } HALLOG("LIN(%d):%s\n",line,msg); return YAPI_IO_ERROR; };
int yyySetup(yInterfaceSt *iface,char *errmsg) { char str[32]; yyyInitPktQueue(iface); yInitializeCriticalSection(&iface->yyyCS); if(iface->devref==NULL){ return YERR(YAPI_DEVICE_NOT_FOUND); } IOReturn ret = IOHIDDeviceOpen(iface->devref, kIOHIDOptionsTypeNone); if (ret != kIOReturnSuccess) { YSPRINTF(str,32,"Unable to open device (0x%x)",ret); return YERRMSG(YAPI_IO_ERROR,str); } /* Create the Run Loop Mode for this device. printing the reference seems to work. */ sprintf(str, "yocto_%p", iface->devref); iface->run_loop_mode = CFStringCreateWithCString(NULL, str, kCFStringEncodingASCII); /* Attach the device to a Run Loop */ IOHIDDeviceScheduleWithRunLoop(iface->devref, yContext->usb_run_loop, iface->run_loop_mode); IOHIDDeviceRegisterInputReportCallback( iface->devref, // IOHIDDeviceRef for the HID device (u8*) &iface->tmprxpkt, // pointer to the report data USB_PKT_SIZE, // number of bytes in the report (CFIndex) &Handle_IOHIDDeviceIOHIDReportCallback, // the callback routine iface); // context passed to callback return 0; }
// return YAPI_SUCCESS if we can reserve access to the device return // an error if the device is already reserved static int yReserveGlobalAccess(yContextSt *ctx, char *errmsg) { int fd; int chk_val, mypid, usedpid = 0; size_t res; mkfifo(YOCTO_LOCK_PIPE, 0600); fd = open(YOCTO_LOCK_PIPE, O_RDWR|O_NONBLOCK); if (fd < 0) { // we cannot open lock file so we cannot realy // check double instance so we asume that we are // alone return YAPI_SUCCESS; } chk_val = 0; mypid = (int) getpid(); res = read(fd, &chk_val, sizeof(chk_val)); if (res == sizeof(chk_val)) { //there is allready someone usedpid = chk_val; } else{ // nobody there -> store my PID chk_val = mypid; } write(fd, &chk_val, sizeof(chk_val)); if (usedpid != 0) { if (usedpid == 1) { // locked by api that not store the pid return YERRMSG(YAPI_DOUBLE_ACCES, "Another process is already using yAPI"); } else { char msg[YOCTO_ERRMSG_LEN]; YSPRINTF(msg, YOCTO_ERRMSG_LEN, "Another process (pid %d) is already using yAPI", (u32) usedpid); return YERRMSG(YAPI_DOUBLE_ACCES, msg); } } return YAPI_SUCCESS; }
// Decode a standard (V1) or typed notification (V2), possibly not null terminated, // to its text representation (always null terminated) // void decodePubVal(Notification_funydx funInfo, const char *funcval, char *buffer) { const unsigned char *p = (const unsigned char *)funcval; u16 funcValType; s32 numVal; float floatVal; int i; if(funInfo.v2.typeV2 == NOTIFY_V2_6RAWBYTES || funInfo.v2.typeV2 == NOTIFY_V2_TYPEDDATA) { if(funInfo.v2.typeV2 == NOTIFY_V2_6RAWBYTES) { funcValType = PUBVAL_6RAWBYTES; } else { funcValType = *p++; } switch(funcValType) { case PUBVAL_LEGACY: // fallback to legacy handling, just in case break; case PUBVAL_1RAWBYTE: case PUBVAL_2RAWBYTES: case PUBVAL_3RAWBYTES: case PUBVAL_4RAWBYTES: case PUBVAL_5RAWBYTES: case PUBVAL_6RAWBYTES: // 1..6 hex bytes for(i = 0; i < funcValType; i++) { unsigned c = *p++; unsigned b = c >> 4; buffer[2*i] = (b>9u) ? b+'a'-10 : b+'0'; b = c & 0xf; buffer[2*i+1] = (b>9u) ? b+'a'-10 : b+'0'; } buffer[2*i] = 0; return; case PUBVAL_C_LONG: case PUBVAL_YOCTO_FLOAT_E3: // 32bit integer in little endian format or Yoctopuce 10-3 format numVal = *p++; numVal += (s32)*p++ << 8; numVal += (s32)*p++ << 16; numVal += (s32)*p++ << 24; #ifdef MICROCHIP_API if(funcValType == PUBVAL_C_LONG) { s32toa(numVal, buffer); } else { dectoa(numVal, buffer, YOCTO_PUBVAL_LEN-1, 1); } #else if(funcValType == PUBVAL_C_LONG) { YSPRINTF(buffer, YOCTO_PUBVAL_LEN, "%d", numVal); } else { char *endp; YSPRINTF(buffer, YOCTO_PUBVAL_LEN, "%.3f", numVal/1000.0); endp = buffer + strlen(buffer); while(endp > buffer && endp[-1] == '0') { *--endp = 0; } if(endp > buffer && endp[-1] == '.') { *--endp = 0; } } #endif return; case PUBVAL_C_FLOAT: // 32bit (short) float memcpy(&floatVal, p, sizeof(floatVal)); #ifdef MICROCHIP_API dectoa(floatVal*1000.0, buffer, YOCTO_PUBVAL_LEN-1, 1); #else { char largeBuffer[64]; char *endp; YSPRINTF(largeBuffer, 64, "%.6f", floatVal); endp = largeBuffer + strlen(largeBuffer); while(endp > largeBuffer && endp[-1] == '0') { *--endp = 0; } if(endp > largeBuffer && endp[-1] == '.') { *--endp = 0; } YSTRCPY(buffer, YOCTO_PUBVAL_LEN, largeBuffer); } #endif return; default: buffer[0] = '?'; buffer[1] = 0; return; } } // Legacy handling: just pad with NUL up to 7 chars for(i = 0; i < 6; i++,p++) { u8 c = *p; if(!c) break; buffer[i] = c; } buffer[i] = 0; }
int yyySetup(yInterfaceSt *iface,char *errmsg) { char str[32]; int i; CFIndex deviceCount; IOHIDDeviceRef *dev_refs; if (yContext->osx_flags & YCTX_OSX_MULTIPLES_HID) { if (YISERR(setupHIDManager(yContext, &iface->hid,errmsg))) { return YAPI_IO_ERROR; } // get all device detected by the OSX dev_refs = getDevRef(&iface->hid, &deviceCount); } else { dev_refs = getDevRef(&yContext->hid, &deviceCount); } if(dev_refs == NULL) { return YERRMSG(YAPI_IO_ERROR,"Device disapear before yyySetup"); } for(i=0 ; i < deviceCount ;i++){ u16 vendorid; u16 deviceid; IOHIDDeviceRef dev = dev_refs[i]; vendorid = get_int_property(dev,CFSTR(kIOHIDVendorIDKey)); deviceid = get_int_property(dev,CFSTR(kIOHIDProductIDKey)); if (iface->vendorid == vendorid && iface->deviceid == deviceid){ char serial[YOCTO_SERIAL_LEN * 2]; memset(serial, 0, YOCTO_SERIAL_LEN * 2); get_txt_property(dev,serial,YOCTO_SERIAL_LEN * 2, CFSTR(kIOHIDSerialNumberKey)); if (YSTRCMP(serial, iface->serial) == 0){ HALLOG("right Interface detected (%x:%x:%s)\n",vendorid,deviceid,iface->serial); iface->devref = dev; break; } } } yFree(dev_refs); if (i == deviceCount) { return YERRMSG(YAPI_IO_ERROR,"Unable to match device detected"); } IOReturn ret = IOHIDDeviceOpen(iface->devref, kIOHIDOptionsTypeNone); if (ret != kIOReturnSuccess) { YSPRINTF(str,32,"Unable to open device (0x%x)",ret); return YERRMSG(YAPI_IO_ERROR,str); } yPktQueueInit(&iface->rxQueue); yPktQueueInit(&iface->txQueue); /* Create the Run Loop Mode for this device. printing the reference seems to work. */ sprintf(str, "yocto_%p", iface->devref); iface->run_loop_mode = CFStringCreateWithCString(NULL, str, kCFStringEncodingASCII); /* Attach the device to a Run Loop */ IOHIDDeviceScheduleWithRunLoop(iface->devref, yContext->usb_run_loop, iface->run_loop_mode); IOHIDDeviceRegisterInputReportCallback( iface->devref, // IOHIDDeviceRef for the HID device (u8*) &iface->tmprxpkt, // pointer to the report data USB_PKT_SIZE, // number of bytes in the report (CFIndex) &Handle_IOHIDDeviceIOHIDReportCallback, // the callback routine iface); // context passed to callback // save setuped iface pointer in context in order // to retreive it durring unplugcallback for (i=0; i< SETUPED_IFACE_CACHE_SIZE ; i++) { if(yContext->setupedIfaceCache[i]==NULL){ yContext->setupedIfaceCache[i] = iface; break; } } if (i==SETUPED_IFACE_CACHE_SIZE) { return YERRMSG(YAPI_IO_ERROR,"Too many setuped USB interfaces"); } iface->flags.yyySetupDone = 1; return 0; }