Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Display Photon 2 instead of P2, dont allow extended advertising data on rtl platforms #2779

Merged
merged 7 commits into from
Jun 5, 2024

Conversation

scott-brust
Copy link
Member

@scott-brust scott-brust commented May 31, 2024

Problem

  1. Photon 2 devices show "P2" as the platform name in USB and in BLE advertising names by default
  2. RTL platforms allow buffering of advertising data > 31 bytes, but truncate that data when starting advertisement, resulting in undefined behavior

Solution

  • Photon 2 naming
    • USB/BLE: Check hardware platform variant when deciding which string to report
  • BLE Advertising data
    • Dont allow buffering data of advertising data > 31 bytes, return SYSTEM_ERROR_TOO_LARGE when attempting and ignore that data

Steps to Test

run example app

Example App

// Include Particle Device OS APIs
#include "Particle.h"

// Let Device OS manage the connection to the Particle Cloud
SYSTEM_MODE(SEMI_AUTOMATIC);

// Run the application and system concurrently in separate threads
SYSTEM_THREAD(ENABLED);

// Show system, cloud connectivity, and application logs over USB
// View logs with CLI using 'particle serial monitor --follow'
SerialLogHandler logHandler(LOG_LEVEL_INFO,{
    { "app", LOG_LEVEL_ALL },
    { "hal.ble", LOG_LEVEL_ALL },
});

const char* serviceUuid = "6E400001-B5A3-F393-E0A9-E50E24DCCA9E";
const char* rxUuid = "6E400002-B5A3-F393-E0A9-E50E24DCCA9E";
const char* txUuid = "6E400003-B5A3-F393-E0A9-E50E24DCCA9E";

uint32_t rainbowLEDTimer = 0;

void onDataReceived(const uint8_t* data, size_t len, const BlePeerDevice& peer, void* context) {
    Log.info("Data (%d bytes):", len);
    Log.info("%.*s", len, data);

    //we ignore the data - you can do what you want with it here however
    RGB.control(true);
    //set the color to something random
    RGB.color(random(0, 255), random(0, 255), random(0, 255));
    //set the timer for 3 seconds from now
    rainbowLEDTimer = millis() + 3000;
}

BleCharacteristic txCharacteristic("tx", BleCharacteristicProperty::NOTIFY, txUuid, serviceUuid);
BleCharacteristic rxCharacteristic("rx", BleCharacteristicProperty::WRITE_WO_RSP, rxUuid, serviceUuid, onDataReceived, NULL);

//STARTUP(System.enableFeature(FEATURE_DISABLE_LISTENING_MODE));

void setup() {
    //turn on BLE and configure a device to have two characteristics.
    // 1. is a read characteristic that contains max available payload size
    // 2. is a write characteristic that can be used to send data to the device

    //log to say hello
    Log.info("Starting BLE peripheral");
    BLE.provisioningMode(false);

    BLE.on();
    WiFi.on();
    Particle.connect();

    //advertise using the service UUID and include the characteristics
    BleAdvertisingData advData;
    advData.clear();
    Log.info("advData.length() %d", advData.length());
    auto result = advData.appendServiceUUID(serviceUuid);
    Log.info("appendServiceUUID returns %d Advertising data length: %d", result, advData.length());

    //add the name "particle" to the device and the last 4 digits of the device ID
    char deviceName[20];
    snprintf(deviceName, sizeof(deviceName), "particle-%02X%02X", (char)(System.deviceID()[10]), (char)(System.deviceID()[11]));
    Log.info("Attempting to add name \"%s\" of length %d", deviceName, strlen(deviceName));
    result = advData.appendLocalName(deviceName);
    //advData.appendLocalName("particle");

    Log.info("appendLocalName %d Advertising data length: %d strlen %d", result, advData.length(), strlen(deviceName));

    BLE.addCharacteristic(txCharacteristic);
    BLE.addCharacteristic(rxCharacteristic);

    // Set up advertising parameters
    BleAdvertisingParams advParams;
    BLE.getAdvertisingParameters(advParams); 
    advParams.interval *= 4;
    BLE.setAdvertisingParameters(&advParams);
    Log.info("Advertising interval: %d", advParams.interval);

    const int err = BLE.advertise(&advData);
    if (err == 0) {
        Log.info("BLE advertising started");
    } else {
        Log.info("BLE advertising failed to start %d", err);
    }

    Log.info("BLE peripheral started");
}

uint32_t printLoop = 0;

void loop() {
  if (millis() - printLoop > 10000) {
    printLoop = millis();
    Log.info("BLE status: %d", BLE.connected());
    Log.info("WiFi Listening: %d", WiFi.listening() );
  }

  //if rainbowLEDTimer is not zero, randomize the LED colour if time is less than the current time
  if (rainbowLEDTimer != 0 && rainbowLEDTimer < millis()) {
    rainbowLEDTimer = 0;
    Log.info("Rainbow LED timer expired");

    //set the RGB LED back to Particle
    RGB.control(false);
  }
}

Example output, rejecting the name as too long:

0000004204 [app] INFO: advData.length() 0
0000004215 [app] INFO: appendServiceUUID returns 18 Advertising data length: 18
0000004266 [app] INFO: Attempting to add name "particle-3231" of length 13
0000004285 [app] INFO: appendLocalName -190 Advertising data length: 18 strlen 13

On Photon2, the device should advertise with a default name starting with "Photon 2"
Screenshot 2024-05-31 at 4 16 12 PM

The device should show up as "Photon 2" in lsusb:

Bus 020 Device 039: ID 2b04:c020 2b04 Photon 2  Serial: 0a10aced202194944a044d38

NOTE: You might need to force your OS to refresh the cache to get the new USB names to display. On windows you can "uninstall the device" in device manager. Mac seems to refresh automatically

@scott-brust scott-brust requested review from avtolstoy and XuGuohui May 31, 2024 23:12
@scott-brust
Copy link
Member Author

scott-brust commented May 31, 2024

[sc-128243]

@scott-brust scott-brust marked this pull request as ready for review May 31, 2024 23:14
@scott-brust scott-brust added this to the 5.8.2 milestone May 31, 2024
@scott-brust
Copy link
Member Author

scott-brust commented Jun 3, 2024

Just for discussion, here are the different methods of setting BLE advertising data. (IE paths that all eventually call hal_ble_gap_set_advertising_data()

  1. Via wiring layer and BleAdvertisingData class append methods. These will use an appropriately sized buffer for the given platform, and return SYSTEM_ERROR_TOO_LARGE if you attempt to append data that wont fit in the buffer (accounting for the Advertising Data header)
  2. Via wiring layer BleAdvertisingData and raw set(const uint8_t* buf, size_t len) method. You can pass in > the platform supported amount of bytes, but the data will be truncated. The user has to check the returned data length matches their passed in buffer length to detect this
  3. Via the ble provisioning mode handler. This uses the BLE local name if one is set via the BLE wiring layer. It also includes other advertising data like the device platform, setup code, etc. I think there is a problem there with the longer platform name on Photon 2. Still need to investigate that

@scott-brust scott-brust force-pushed the sc-128198/p2-photon2-names branch from e2bc222 to fa62bff Compare June 3, 2024 23:03
@scott-brust scott-brust requested a review from avtolstoy June 3, 2024 23:07
@scott-brust scott-brust merged commit 917ed35 into develop Jun 5, 2024
13 checks passed
@scott-brust scott-brust deleted the sc-128198/p2-photon2-names branch June 5, 2024 16:32
@scott-brust scott-brust mentioned this pull request Jun 13, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants