ERROR: gattServerWriteCallBack called twice with same data


#1

the gattServerWriteCallBack (sometimes) called twice with same data
The Bluefruit LE Sniffer confirms that the app only sends the msg once, but BLE Nano 2 (and BLE Nano V1.5) process the message twice and pass it back to the call back routine twice.

// Initialize value of chars
GattCharacteristic characteristicTX(UARTServiceTXCharacteristicUUID, tx_value, 1, TXRX_BUF_LEN, GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_WRITE | GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_WRITE_WITHOUT_RESPONSE );
GattCharacteristic characteristicRX(UARTServiceRXCharacteristicUUID, rx_value, 1, TXRX_BUF_LEN, GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_NOTIFY);
GattCharacteristic *uartChars[] = {&characteristicTX, &characteristicRX};
GattService uartService(UARTServiceUUID, uartChars, sizeof(uartChars) / sizeof(GattCharacteristic *));

in setup () {
  ble.init();
  ble.onDisconnection(disconnectionCallBack);
  ble.onConnection(connectionCallBack);
  ble.onDataWritten(gattServerWriteCallBack);

  // setup adv_data and srp_data
  ble.accumulateAdvertisingPayload(GapAdvertisingData::BREDR_NOT_SUPPORTED);
  ble.accumulateAdvertisingPayload(GapAdvertisingData::SHORTENED_LOCAL_NAME,
                                   (const uint8_t *)DEVICE_NAME, sizeof(DEVICE_NAME) - 1);
  ble.accumulateAdvertisingPayload(GapAdvertisingData::COMPLETE_LIST_128BIT_SERVICE_IDS,
                                   (const uint8_t *)UARTServiceUUID_reversed, sizeof(UARTServiceUUID_reversed));
  // set adv_type
  ble.setAdvertisingType(GapAdvertisingParams::ADV_CONNECTABLE_UNDIRECTED);
  // add service
  ble.addService(uartService);
  // set device name
  ble.setDeviceName((const uint8_t *)DEVICE_NAME);
  // set tx power,valid values are -40, -20, -16, -12, -8, -4, 0, 4
  ble.setTxPower(4);
  // set adv_interval, 100ms in multiples of 0.625ms.
  ble.setAdvertisingInterval(160);
  // set adv_timeout, in seconds
  ble.setAdvertisingTimeout(0);
  // start advertising
  ble.startAdvertising();

// this method is called twice (sometimes) with the same data.  
void gattServerWriteCallBack(const GattWriteCallbackParams *Handler) {
  uint8_t buf[TXRX_BUF_LEN];
  uint16_t bytesRead = TXRX_BUF_LEN;  // pass in buffer size

  if (Handler->handle == characteristicTX.getValueAttribute().getHandle()) {
    int readError =  ble.readCharacteristicValue(characteristicTX.getValueAttribute().getHandle(), buf, &bytesRead);
  }
  pfodBLESerial::receiveHandler(buf, bytesRead);
}

#2

I have ‘fixed’ this problem in pfodApp by adding a cmd seqNo to each command e.g.
3{A}
and changing the receive library to ignore cmds with the same seqNo
works well
However it depends on having well defined cmd delimiters, in pfodApp case { }