int USPiInitialize (void) { assert (s_pLibrary == 0); s_pLibrary = (TUSPiLibrary *) malloc (sizeof (TUSPiLibrary)); assert (s_pLibrary != 0); DeviceNameService (&s_pLibrary->NameService); DWHCIDevice (&s_pLibrary->DWHCI); s_pLibrary->pEth0 = 0; if (!DWHCIDeviceInitialize (&s_pLibrary->DWHCI)) { LogWrite (FromUSPi, LOG_ERROR, "Cannot initialize USB host controller interface"); _DWHCIDevice (&s_pLibrary->DWHCI); _DeviceNameService (&s_pLibrary->NameService); free (s_pLibrary); s_pLibrary = 0; return 0; } s_pLibrary->pUKBD1 = (TUSBKeyboardDevice *) DeviceNameServiceGetDevice (DeviceNameServiceGet (), "ukbd1", FALSE); s_pLibrary->pUMouse1 = (TUSBMouseDevice *) DeviceNameServiceGetDevice (DeviceNameServiceGet (), "umouse1", FALSE); s_pLibrary->pMIDI1 = (TUSBMIDIDevice *) DeviceNameServiceGetDevice (DeviceNameServiceGet (), "umidi1", FALSE); for (unsigned i = 0; i < MAX_DEVICES; i++) { TString DeviceName; String (&DeviceName); StringFormat (&DeviceName, "umsd%u", i+1); s_pLibrary->pUMSD[i] = (TUSBBulkOnlyMassStorageDevice *) DeviceNameServiceGetDevice (DeviceNameServiceGet (), StringGet (&DeviceName), TRUE); _String (&DeviceName); } s_pLibrary->pEth0 = (TSMSC951xDevice *) DeviceNameServiceGetDevice (DeviceNameServiceGet (), "eth0", FALSE); for (unsigned i = 0; i < MAX_DEVICES; i++) { TString DeviceName; String (&DeviceName); StringFormat (&DeviceName, "upad%u", i+1); s_pLibrary->pUPAD[i] = (TUSBGamePadDevice *) DeviceNameServiceGetDevice (DeviceNameServiceGet (), StringGet (&DeviceName), FALSE); _String (&DeviceName); } LogWrite (FromUSPi, LOG_DEBUG, "USPi library successfully initialized"); return 1; }
TString *USBStandardHubGetDeviceNames (TUSBDevice *pDevice) { assert (pDevice != 0); TString *pResult = (TString *) malloc (sizeof (TString)); assert (pResult != 0); String (pResult); for (unsigned nSelector = DeviceNameVendor; nSelector < DeviceNameUnknown; nSelector++) { TString *pName = USBDeviceGetName (pDevice, (TDeviceNameSelector) nSelector); assert (pName != 0); if (StringCompare (pName, "unknown") != 0) { if (StringGetLength (pResult) > 0) { StringAppend (pResult, ", "); } StringAppend (pResult, StringGet (pName)); } _String (pName); free (pName); } if (StringGetLength (pResult) == 0) { StringSet (pResult, "unknown"); } return pResult; }
static void GamePadStatusHandler (unsigned int nDeviceIndex, const USPiGamePadState *pState) { TString Msg; String (&Msg); StringFormat (&Msg, "GamePad %u: Buttons 0x%X", nDeviceIndex + 1, pState->buttons); TString Value; String (&Value); if (pState->naxes > 0) { StringAppend (&Msg, " Axes"); for (unsigned i = 0; i < pState->naxes; i++) { StringFormat (&Value, " %d", pState->axes[i].value); StringAppend (&Msg, StringGet (&Value)); } } if (pState->nhats > 0) { StringAppend (&Msg, " Hats"); for (unsigned i = 0; i < pState->nhats; i++) { StringFormat (&Value, " %d", pState->hats[i]); StringAppend (&Msg, StringGet (&Value)); } } LogWrite (FromSample, LOG_NOTICE, StringGet (&Msg)); _String (&Value); _String (&Msg); }
boolean USBKeyboardDeviceConfigure (TUSBDevice *pUSBDevice) { TUSBKeyboardDevice *pThis = (TUSBKeyboardDevice *) pUSBDevice; assert (pThis != 0); TUSBConfigurationDescriptor *pConfDesc = (TUSBConfigurationDescriptor *) USBDeviceGetDescriptor (&pThis->m_USBDevice, DESCRIPTOR_CONFIGURATION); if ( pConfDesc == 0 || pConfDesc->bNumInterfaces < 1) { USBDeviceConfigurationError (&pThis->m_USBDevice, FromUSBKbd); return FALSE; } TUSBInterfaceDescriptor *pInterfaceDesc; while ((pInterfaceDesc = (TUSBInterfaceDescriptor *) USBDeviceGetDescriptor (&pThis->m_USBDevice, DESCRIPTOR_INTERFACE)) != 0) { if ( pInterfaceDesc->bNumEndpoints < 1 || pInterfaceDesc->bInterfaceClass != 0x03 // HID Class || pInterfaceDesc->bInterfaceSubClass != 0x01 // Boot Interface Subclass || pInterfaceDesc->bInterfaceProtocol != 0x01) // Keyboard { continue; } pThis->m_ucInterfaceNumber = pInterfaceDesc->bInterfaceNumber; pThis->m_ucAlternateSetting = pInterfaceDesc->bAlternateSetting; TUSBEndpointDescriptor *pEndpointDesc = (TUSBEndpointDescriptor *) USBDeviceGetDescriptor (&pThis->m_USBDevice, DESCRIPTOR_ENDPOINT); if ( pEndpointDesc == 0 || (pEndpointDesc->bEndpointAddress & 0x80) != 0x80 // Input EP || (pEndpointDesc->bmAttributes & 0x3F) != 0x03) // Interrupt EP { continue; } assert (pThis->m_pReportEndpoint == 0); pThis->m_pReportEndpoint = malloc (sizeof (TUSBEndpoint)); assert (pThis->m_pReportEndpoint != 0); USBEndpoint2 (pThis->m_pReportEndpoint, &pThis->m_USBDevice, pEndpointDesc); break; } if (pThis->m_pReportEndpoint == 0) { USBDeviceConfigurationError (&pThis->m_USBDevice, FromUSBKbd); return FALSE; } if (!USBDeviceConfigure (&pThis->m_USBDevice)) { LogWrite (FromUSBKbd, LOG_ERROR, "Cannot set configuration"); return FALSE; } if (pThis->m_ucAlternateSetting != 0) { if (DWHCIDeviceControlMessage (USBDeviceGetHost (&pThis->m_USBDevice), USBDeviceGetEndpoint0 (&pThis->m_USBDevice), REQUEST_OUT | REQUEST_TO_INTERFACE, SET_INTERFACE, pThis->m_ucAlternateSetting, pThis->m_ucInterfaceNumber, 0, 0) < 0) { LogWrite (FromUSBKbd, LOG_ERROR, "Cannot set interface"); return FALSE; } } if (DWHCIDeviceControlMessage (USBDeviceGetHost (&pThis->m_USBDevice), USBDeviceGetEndpoint0 (&pThis->m_USBDevice), REQUEST_OUT | REQUEST_CLASS | REQUEST_TO_INTERFACE, SET_PROTOCOL, BOOT_PROTOCOL, pThis->m_ucInterfaceNumber, 0, 0) < 0) { LogWrite (FromUSBKbd, LOG_ERROR, "Cannot set boot protocol"); return FALSE; } TString DeviceName; String (&DeviceName); StringFormat (&DeviceName, "ukbd%u", s_nDeviceNumber++); DeviceNameServiceAddDevice (DeviceNameServiceGet (), StringGet (&DeviceName), pThis, FALSE); _String (&DeviceName); return USBKeyboardDeviceStartRequest (pThis); }
boolean USBStandardHubEnumeratePorts (TUSBStandardHub *pThis) { assert (pThis != 0); TUSBHostController *pHost = USBDeviceGetHost (&pThis->m_USBDevice); assert (pHost != 0); TUSBEndpoint *pEndpoint0 = USBDeviceGetEndpoint0 (&pThis->m_USBDevice); assert (pEndpoint0 != 0); assert (pThis->m_nPorts > 0); // first power on all ports for (unsigned nPort = 0; nPort < pThis->m_nPorts; nPort++) { if (DWHCIDeviceControlMessage (pHost, pEndpoint0, REQUEST_OUT | REQUEST_CLASS | REQUEST_TO_OTHER, SET_FEATURE, PORT_POWER, nPort+1, 0, 0) < 0) { LogWrite (FromHub, LOG_ERROR, "Cannot power port %u", nPort+1); return FALSE; } } // pThis->m_pHubDesc->bPwrOn2PwrGood delay seems to be not enough // for some low speed devices, so we use the maximum here MsDelay (510); // now detect devices, reset and initialize them for (unsigned nPort = 0; nPort < pThis->m_nPorts; nPort++) { assert (pThis->m_pStatus[nPort] == 0); pThis->m_pStatus[nPort] = malloc (sizeof (TUSBPortStatus)); assert (pThis->m_pStatus[nPort] != 0); if (DWHCIDeviceControlMessage (pHost, pEndpoint0, REQUEST_IN | REQUEST_CLASS | REQUEST_TO_OTHER, GET_STATUS, 0, nPort+1, pThis->m_pStatus[nPort], 4) != 4) { LogWrite (FromHub, LOG_ERROR, "Cannot get status of port %u", nPort+1); continue; } assert (pThis->m_pStatus[nPort]->wPortStatus & PORT_POWER__MASK); if (!(pThis->m_pStatus[nPort]->wPortStatus & PORT_CONNECTION__MASK)) { continue; } if (DWHCIDeviceControlMessage (pHost, pEndpoint0, REQUEST_OUT | REQUEST_CLASS | REQUEST_TO_OTHER, SET_FEATURE, PORT_RESET, nPort+1, 0, 0) < 0) { LogWrite (FromHub, LOG_ERROR, "Cannot reset port %u", nPort+1); continue; } MsDelay (100); if (DWHCIDeviceControlMessage (pHost, pEndpoint0, REQUEST_IN | REQUEST_CLASS | REQUEST_TO_OTHER, GET_STATUS, 0, nPort+1, pThis->m_pStatus[nPort], 4) != 4) { return FALSE; } //LogWrite (FromHub, LOG_DEBUG, "Port %u status is 0x%04X", nPort+1, (unsigned) pThis->m_pStatus[nPort]->wPortStatus); if (!(pThis->m_pStatus[nPort]->wPortStatus & PORT_ENABLE__MASK)) { LogWrite (FromHub, LOG_ERROR, "Port %u is not enabled", nPort+1); continue; } // check for over-current if (pThis->m_pStatus[nPort]->wPortStatus & PORT_OVER_CURRENT__MASK) { DWHCIDeviceControlMessage (pHost, pEndpoint0, REQUEST_OUT | REQUEST_CLASS | REQUEST_TO_OTHER, CLEAR_FEATURE, PORT_POWER, nPort+1, 0, 0); LogWrite (FromHub, LOG_ERROR, "Over-current condition on port %u", nPort+1); return FALSE; } TUSBSpeed Speed = USBSpeedUnknown; if (pThis->m_pStatus[nPort]->wPortStatus & PORT_LOW_SPEED__MASK) { Speed = USBSpeedLow; } else if (pThis->m_pStatus[nPort]->wPortStatus & PORT_HIGH_SPEED__MASK) { Speed = USBSpeedHigh; } else { Speed = USBSpeedFull; } // first create default device assert (pThis->m_pDevice[nPort] == 0); pThis->m_pDevice[nPort] = malloc (sizeof (TUSBDevice)); assert (pThis->m_pDevice[nPort] != 0); USBDevice (pThis->m_pDevice[nPort], pHost, Speed, USBDeviceGetAddress (&pThis->m_USBDevice), nPort+1); if (!USBDeviceInitialize (pThis->m_pDevice[nPort])) { _USBDevice (pThis->m_pDevice[nPort]); free (pThis->m_pDevice[nPort]); pThis->m_pDevice[nPort] = 0; continue; } TString *pNames = USBStandardHubGetDeviceNames (pThis->m_pDevice[nPort]); assert (pNames != 0); LogWrite (FromHub, LOG_NOTICE, "Port %u: Device %s found", nPort+1, StringGet (pNames)); _String (pNames); free (pNames); } // now configure devices for (unsigned nPort = 0; nPort < pThis->m_nPorts; nPort++) { if (pThis->m_pDevice[nPort] == 0) { continue; } // now create specific device from default device TUSBDevice *pChild = USBDeviceFactoryGetDevice (pThis->m_pDevice[nPort]); if (pChild != 0) { _USBDevice (pThis->m_pDevice[nPort]); // delete default device free (pThis->m_pDevice[nPort]); pThis->m_pDevice[nPort] = pChild; // assign specific device if (!(*pThis->m_pDevice[nPort]->Configure) (pThis->m_pDevice[nPort])) { LogWrite (FromHub, LOG_ERROR, "Port %u: Cannot configure device", nPort+1); continue; } LogWrite (FromHub, LOG_DEBUG, "Port %u: Device configured", nPort+1); } else { LogWrite (FromHub, LOG_NOTICE, "Port %u: Device is not supported", nPort+1); _USBDevice (pThis->m_pDevice[nPort]); free (pThis->m_pDevice[nPort]); pThis->m_pDevice[nPort] = 0; } } // again check for over-current TUSBHubStatus *pHubStatus = malloc (sizeof (TUSBHubStatus)); assert (pHubStatus != 0); if (DWHCIDeviceControlMessage (pHost, pEndpoint0, REQUEST_IN | REQUEST_CLASS, GET_STATUS, 0, 0, pHubStatus, sizeof *pHubStatus) != (int) sizeof *pHubStatus) { LogWrite (FromHub, LOG_ERROR, "Cannot get hub status"); free (pHubStatus); return FALSE; } if (pHubStatus->wHubStatus & HUB_OVER_CURRENT__MASK) { for (unsigned nPort = 0; nPort < pThis->m_nPorts; nPort++) { DWHCIDeviceControlMessage (pHost, pEndpoint0, REQUEST_OUT | REQUEST_CLASS | REQUEST_TO_OTHER, CLEAR_FEATURE, PORT_POWER, nPort+1, 0, 0); } LogWrite (FromHub, LOG_ERROR, "Hub over-current condition"); free (pHubStatus); return FALSE; } free (pHubStatus); pHubStatus = 0; boolean bResult = TRUE; for (unsigned nPort = 0; nPort < pThis->m_nPorts; nPort++) { if (DWHCIDeviceControlMessage (pHost, pEndpoint0, REQUEST_IN | REQUEST_CLASS | REQUEST_TO_OTHER, GET_STATUS, 0, nPort+1, pThis->m_pStatus[nPort], 4) != 4) { continue; } if (pThis->m_pStatus[nPort]->wPortStatus & PORT_OVER_CURRENT__MASK) { DWHCIDeviceControlMessage (pHost, pEndpoint0, REQUEST_OUT | REQUEST_CLASS | REQUEST_TO_OTHER, CLEAR_FEATURE, PORT_POWER, nPort+1, 0, 0); LogWrite (FromHub, LOG_ERROR, "Over-current condition on port %u", nPort+1); bResult = FALSE; } } return bResult; }
boolean SMSC951xDeviceConfigure (TUSBDevice *pUSBDevice) { TSMSC951xDevice *pThis = (TSMSC951xDevice *) pUSBDevice; assert (pThis != 0); u8 MACAddress[MAC_ADDRESS_SIZE]; if (GetMACAddress (MACAddress)) { MACAddressSet (&pThis->m_MACAddress, MACAddress); } else { LogWrite (FromSMSC951x, LOG_ERROR, "Cannot get MAC address"); return FALSE; } TString MACString; String (&MACString); MACAddressFormat (&pThis->m_MACAddress, &MACString); LogWrite (FromSMSC951x, LOG_DEBUG, "MAC address is %s", StringGet (&MACString)); const TUSBConfigurationDescriptor *pConfigDesc = (TUSBConfigurationDescriptor *) USBDeviceGetDescriptor (&pThis->m_USBDevice, DESCRIPTOR_CONFIGURATION); if ( pConfigDesc == 0 || pConfigDesc->bNumInterfaces != 1) { USBDeviceConfigurationError (&pThis->m_USBDevice, FromSMSC951x); _String (&MACString); return FALSE; } const TUSBInterfaceDescriptor *pInterfaceDesc = (TUSBInterfaceDescriptor *) USBDeviceGetDescriptor (&pThis->m_USBDevice, DESCRIPTOR_INTERFACE); if ( pInterfaceDesc == 0 || pInterfaceDesc->bInterfaceNumber != 0x00 || pInterfaceDesc->bAlternateSetting != 0x00 || pInterfaceDesc->bNumEndpoints != 3) { USBDeviceConfigurationError (&pThis->m_USBDevice, FromSMSC951x); _String (&MACString); return FALSE; } const TUSBEndpointDescriptor *pEndpointDesc; while ((pEndpointDesc = (TUSBEndpointDescriptor *) USBDeviceGetDescriptor (&pThis->m_USBDevice, DESCRIPTOR_ENDPOINT)) != 0) { if ((pEndpointDesc->bmAttributes & 0x3F) == 0x02) // Bulk { if ((pEndpointDesc->bEndpointAddress & 0x80) == 0x80) // Input { if (pThis->m_pEndpointBulkIn != 0) { USBDeviceConfigurationError (&pThis->m_USBDevice, FromSMSC951x); _String (&MACString); return FALSE; } pThis->m_pEndpointBulkIn = (TUSBEndpoint *) malloc (sizeof (TUSBEndpoint)); assert (pThis->m_pEndpointBulkIn); USBEndpoint2 (pThis->m_pEndpointBulkIn, &pThis->m_USBDevice, pEndpointDesc); } else // Output { if (pThis->m_pEndpointBulkOut != 0) { USBDeviceConfigurationError (&pThis->m_USBDevice, FromSMSC951x); _String (&MACString); return FALSE; } pThis->m_pEndpointBulkOut = (TUSBEndpoint *) malloc (sizeof (TUSBEndpoint)); assert (pThis->m_pEndpointBulkOut); USBEndpoint2 (pThis->m_pEndpointBulkOut, &pThis->m_USBDevice, pEndpointDesc); } } } if ( pThis->m_pEndpointBulkIn == 0 || pThis->m_pEndpointBulkOut == 0) { USBDeviceConfigurationError (&pThis->m_USBDevice, FromSMSC951x); _String (&MACString); return FALSE; } if (!USBDeviceConfigure (&pThis->m_USBDevice)) { LogWrite (FromSMSC951x, LOG_ERROR, "Cannot set configuration"); _String (&MACString); return FALSE; } u8 MACAddressBuffer[MAC_ADDRESS_SIZE]; MACAddressCopyTo (&pThis->m_MACAddress, MACAddressBuffer); u16 usMACAddressHigh = *(u16 *) &MACAddressBuffer[4]; u32 nMACAddressLow = *(u32 *) &MACAddressBuffer[0]; if ( !SMSC951xDeviceWriteReg (pThis, ADDRH, usMACAddressHigh) || !SMSC951xDeviceWriteReg (pThis, ADDRL, nMACAddressLow)) { LogWrite (FromSMSC951x, LOG_ERROR, "Cannot set MAC address"); _String (&MACString); return FALSE; } if ( !SMSC951xDeviceWriteReg (pThis, LED_GPIO_CFG, LED_GPIO_CFG_SPD_LED | LED_GPIO_CFG_LNK_LED | LED_GPIO_CFG_FDX_LED) || !SMSC951xDeviceWriteReg (pThis, MAC_CR, MAC_CR_RCVOWN //| MAC_CR_PRMS // promiscous mode | MAC_CR_TXEN | MAC_CR_RXEN) || !SMSC951xDeviceWriteReg (pThis, TX_CFG, TX_CFG_ON)) { LogWrite (FromSMSC951x, LOG_ERROR, "Cannot start device"); _String (&MACString); return FALSE; } // TODO: check if PHY is up (wait for it) TString DeviceName; String (&DeviceName); StringFormat (&DeviceName, "eth%u", s_nDeviceNumber++); DeviceNameServiceAddDevice (DeviceNameServiceGet (), StringGet (&DeviceName), pThis, FALSE); _String (&DeviceName); _String (&MACString); return TRUE; }
int Ardb::GetValueByPattern(Context& ctx, const Slice& pattern, Data& subst, Data& value, ValueObjectMap* meta_cache) { const char *p, *f; const char* spat; /* If the pattern is "#" return the substitution object itself in order * to implement the "SORT ... GET #" feature. */ spat = pattern.data(); if (spat[0] == '#' && spat[1] == '\0') { value = subst; return 0; } /* If we can't find '*' in the pattern we return NULL as to GET a * fixed key does not make sense. */ p = strchr(spat, '*'); if (!p) { return -1; } std::string vstr; subst.GetDecodeString(vstr); f = strstr(spat, "->"); if (NULL != f && (uint32) (f - spat) == (pattern.size() - 2)) { f = NULL; } std::string keystr(pattern.data(), pattern.size()); string_replace(keystr, "*", vstr); if (f == NULL) { /* * keystr = "len(...)" */ if (keystr.find("len(") == 0 && keystr.rfind(")") == keystr.size() - 1) { keystr = keystr.substr(4, keystr.size() - 5); KeyType keytype = KEY_END; GetType(ctx, keystr, keytype); switch (keytype) { case SET_META: { SetLen(ctx, keystr); break; } case LIST_META: { ListLen(ctx, keystr); break; } case ZSET_META: { ZSetLen(ctx, keystr); break; } default: { return -1; } } value.SetInt64(ctx.reply.integer); value.ToString(); return 0; } ValueObject vv; int ret = StringGet(ctx, keystr, vv); if (0 == ret) { value = vv.meta.str_value; //value.ToString(); } return ret; } else { size_t pos = keystr.find("->"); std::string field = keystr.substr(pos + 2); keystr = keystr.substr(0, pos); int ret = 0; if (NULL == meta_cache) { ret = HashGet(ctx, keystr, field, value); } else { ValueObjectMap::iterator fit = meta_cache->find(keystr); if (fit == meta_cache->end()) { ValueObject meta; GetMetaValue(ctx, keystr, HASH_META, meta); fit = meta_cache->insert(ValueObjectMap::value_type(keystr, meta)).first; } Data ff; ff.SetString(field, true); ret = HashGet(ctx, fit->second, ff, value); } //value.ToString(); return ret; } }