I would like to bond the Watchy via BLE to my Android phone to support Android Smart Lock.

ask-it
Posts: 1
Joined: Sun Jun 18, 2023 10:50 am

I would like to bond the Watchy via BLE to my Android phone to support Android Smart Lock.

Postby ask-it » Sun Jun 18, 2023 11:06 am

I would like to bond my Watchy via BLE to my Android phone to support Android Smart Lock. After bonding the Watch could advertise simply to keep the Smart Lock active on the phone.

Created a BLE method:

Code: Select all

bool BLE_Bond::begin(const char localName = "Watchy") {
  BLEDevice::setCustomGattcHandler(gattcEventHandler);

  // Create the BLE Device
  BLEDevice::init(localName);
  BLEDevice::setCustomGapHandler(my_gap_event_handler);

  // Create the BLE Server
  pServer = BLEDevice::createServer();

  BLEDevice::setEncryptionLevel(ESP_BLE_SEC_ENCRYPT);
  BLEDevice::setSecurityCallbacks(new MySecurity());

  pServer->setCallbacks(new BLECustomServerCallbacks());

  // Create the BLE Service
  pService       = pServer->createService(SERVICE_UUID);

  // Create a BLE Characteristic
  pCharacteristic = pService->createCharacteristic(
                     CHARACTERISTIC_UUID,
                     BLECharacteristic::PROPERTY_READ   |
                     BLECharacteristic::PROPERTY_WRITE
                   );

  pCharacteristic->setAccessPermissions(ESP_GATT_PERM_READ_ENCRYPTED | ESP_GATT_PERM_WRITE_ENCRYPTED);
    pCharacteristic->setValue("Hello World says Watchy");

  pCharacteristic->addDescriptor(new BLE2902());
  pCharacteristic->setCallbacks(new bondCallback(this));

  // Start the service(s)
  pService->start();

  // Start advertising
  BLEAdvertisingpAdvertising = BLEDevice::getAdvertising();
  pAdvertising->addServiceUUID(SERVICE_UUID);
  pAdvertising->setScanResponse(true);
  pAdvertising->setMinPreferred(0x12);  // set value to 0x00 to not advertise this parameter
  pAdvertising->start();

  BLESecurity *pSecurity = new BLESecurity();
  pSecurity->setAuthenticationMode(ESP_LE_AUTH_REQ_SC_BOND);
  pSecurity->setCapability(ESP_IO_CAP_NONE);
  uint8_t init_key = ESP_BLE_ENC_KEY_MASK | ESP_BLE_ID_KEY_MASK;
  esp_ble_gap_set_security_param(ESP_BLE_SM_SET_INIT_KEY, &init_key, sizeof(uint8_t));
  pSecurity->setInitEncryptionKey(ESP_BLE_ENC_KEY_MASK | ESP_BLE_ID_KEY_MASK);

  return true;
}
GATT Event Handler:

Code: Select all

void gattcEventHandler(esp_gattc_cb_event_t event, esp_gatt_if_t gattc_if, esp_ble_gattc_cb_param_t *param)
{
    if (event == ESP_GATTC_DISCONNECT_EVT) {
      bondStatus = BOND_STATUS_GATTDISCONNECT; 
    } else
    if (event == ESP_GATTC_CONNECT_EVT) {
        esp_ble_set_encryption(param->connect.remote_bda, ESP_BLE_SEC_ENCRYPT);
        bondStatus = BOND_STATUS_GATTCONNECT; 
    }
}
GAP Event Handler:

Code: Select all

static void my_gap_event_handler(esp_gap_ble_cb_event_t event, esp_ble_gap_cb_param_t* param) {
switch(event){
    case ESP_GAP_BLE_AUTH_CMPL_EVT:{                                            // last called
      BLEAddress address = BLEAddress(param->ble_security.auth_cmpl.bd_addr);
      BLEDevice::whiteListAdd(address);
      bondStatus = BOND_STATUS_AUTHCOMPLETE; 
      break;
    }
    case ESP_GAP_BLE_SEC_REQ_EVT:{
      esp_ble_gap_security_rsp(param->ble_security.ble_req.bd_addr, true);
      bondStatus = BOND_STATUS_SECURITYEVT; 
      break;
    }
    case ESP_GAP_BLE_UPDATE_CONN_PARAMS_EVT:{
      bondStatus = BOND_STATUS_UPDATECONNPARAMS; 
      break;
    }
  }
}
Security Callback Handler:

Code: Select all

class MySecurity : public BLESecurityCallbacks {
  bool onConfirmPIN(uint32_t pin){
    return true;
  }

  uint32_t onPassKeyRequest(){
    return 0;
  }

  void onPassKeyNotify(uint32_t pass_key){
  }

  bool onSecurityRequest(){
    return true;
  }

  // called with failed
  void onAuthenticationComplete(esp_ble_auth_cmpl_t cmpl){
    if(cmpl.success){
        bondStatus = BOND_STATUS_BONDED; 
    }
    else{
        bondStatus = BOND_STATUS_FAILED; 
    }
    bondErrorCode = cmpl.fail_reason;
  }
};
Callback to catch the BLE Characteristic:

Code: Select all

class bondCallback : public BLECharacteristicCallbacks {
public:
  bondCallback(BLE_Bond ble) { 
    _p_ble = ble; 
  }

  BLE_Bond_p_ble;
};
BLE Server Callback:

Code: Select all

class BLECustomServerCallbacks : public BLEServerCallbacks {
  void onConnect(BLEServer pServer) { 
    bondStatus = BOND_STATUS_CONNECTED; 
    pServer->getAdvertising()->start();
  }

  void onDisconnect(BLEServerpServer) { 
    bondStatus = BOND_STATUS_DISCONNECTED; 
  }
};
At the end the Android phone requests the user to confirm pairing.
But afterwards the BLE trace in nrfConnect shown GATT Insufficient Authorization when trying to update the BLE connection after previous successful connect and characteristics discovery.
Any experiences with bonding the Watchy to Android smartphone?

Who is online

Users browsing this forum: No registered users and 67 guests