NimBLE-Arduino
NimBLE-Arduino copied to clipboard
NimBLEHIDDevice does not report PNP info and manufacturer string properly
Steps to reproduce
- Create a
NimBLEHIDDeviceinstance. - Call
manufacturer()->setValue(). - Call
pnp() - Start services
Example code:
hid = new NimBLEHIDDevice(pServer);
if (!hid) {
log_e("Unable to create HID device");
abort();
}
hid->manufacturer()->setValue(deviceManufacturer);
hid->pnp(BLE_VENDOR_SOURCE, BLE_VENDOR_ID, BLE_PRODUCT_ID, PRODUCT_REVISION);
hid->hidInfo(0x00, 0x01);
NimBLESecurity *pSecurity = new NimBLESecurity();
pSecurity->setAuthenticationMode(ESP_LE_AUTH_BOND);
hid->reportMap((uint8_t *)hid_descriptor, sizeof(hid_descriptor));
hid->setBatteryLevel(UNKNOWN_BATTERY_LEVEL);
inputGamepad = hid->inputReport(RID_INPUT_GAMEPAD);
configReport = hid->featureReport(RID_FEATURE_CONFIG);
capabilitiesReport = hid->featureReport(RID_FEATURE_CAPABILITIES);
if (!inputGamepad || !configReport || !capabilitiesReport) {
log_e("Unable to create HID report characteristics");
abort();
}
configReport->setCallbacks(&configFRCallbacks);
capabilitiesReport->setCallbacks(&capabilitiesFRCallbacks);
// Start services
hid->startServices();
BLE_VENDOR_ID and the other constants are non-zero.
Expected behavior
At the hosting PC, the PNP device enumeration should show the given VID and PID, along with the manufacturer string.
Actual behavior
The hosting PC show VID=0, PID=0 and an empty manufacturer string.

I'm unsure what is going on here, I'll have a look into it.
Update on this issue:
I found some bugs at NimBLEHIDDevice.cpp. Working on a pull request. Most relevant patch is:
void NimBLEHIDDevice::pnp(uint8_t sig, uint16_t vid, uint16_t pid, uint16_t version)
{
//uint8_t pnp[] = {sig, (uint8_t)(vid >> 8), (uint8_t)vid, (uint8_t)(pid >> 8), (uint8_t)pid, (uint8_t)(version >> 8), (uint8_t)version};
uint8_t pnp[] = {
sig,
((uint8_t *)&vid)[0],
((uint8_t *)&vid)[1],
((uint8_t *)&pid)[0],
((uint8_t *)&pid)[1],
((uint8_t *)&version)[0],
((uint8_t *)&version)[1]
};
m_pnpCharacteristic->setValue(pnp, sizeof(pnp));
}
Manufacturer string seems to be properly set, from my test with nRF Connect on Android.
I found this post that suggests a bug in the Windows API when retrieving the manufacturer string (which seems to extend to model number and revision strings): https://learn.microsoft.com/en-us/answers/questions/401236/hidd-getproductstring-with-ble-hid-device
This should now be resolved.