cancel
Showing results for 
Search instead for 
Did you mean: 

Wrong event structure definition in library BLE1_V4.4.0

KeM.
Associate

HI, while learning how to use IDB05A1 shield with nucleo n053r8 I've stumbled over a problem. I've modified SensorDemo_BLESensor-App (from package X-CUBE-BLE 1.4.40) code to create my own server with 2 characteristics:

/**
 * @brief  Add the SW Feature service using a vendor specific profile
 * @param  None
 * @retval tBleStatus Status
 */
tBleStatus Add_RX_TX_service(void)
{
  tBleStatus ret;
  int32_t NumberOfRecords=1;
  uint8_t uuid[16];
 
  COPY_NOYAK_SERVICE_UUID(uuid);
  BLUENRG_memcpy(&service_uuid.Service_UUID_128, uuid, 16);
  ret = aci_gatt_add_serv(
                          UUID_TYPE_128,
                          service_uuid.Service_UUID_128,
                          PRIMARY_SERVICE,
                          6, // liczba rekordow (3 * liczba charakterystyk ?)
                          &RXTX_Service_handle);
 
  if (ret != BLE_STATUS_SUCCESS) {
    goto fail;
  }
 
  COPY_TX_UUID(uuid);
  BLUENRG_memcpy(&char_uuid.Char_UUID_128, uuid, 16);
  ret =  aci_gatt_add_char(
                           RXTX_Service_handle,
                           UUID_TYPE_128, char_uuid.Char_UUID_128,
                           20,
                           CHAR_PROP_READ,
                           ATTR_PERMISSION_NONE | CHAR_PROP_NOTIFY,
                           GATT_NOTIFY_READ_REQ_AND_WAIT_FOR_APPL_RESP,
                           20,
                           0,
                           &TX_handle);
 
 
  if (ret != BLE_STATUS_SUCCESS) {
    goto fail;
  }
 
  PRINTF("TX characteristick initialized\n");
 
  COPY_RX_UUID(uuid);
  BLUENRG_memcpy(&char_uuid.Char_UUID_128, uuid, 16);
  ret =  aci_gatt_add_char(
                           RXTX_Service_handle,
                           UUID_TYPE_128, char_uuid.Char_UUID_128,
                           20,
                           CHAR_PROP_WRITE | CHAR_PROP_WRITE_WITHOUT_RESP,
                           ATTR_PERMISSION_NONE,
                           GATT_NOTIFY_ATTRIBUTE_WRITE,
                           20,
                           1,
                           &RX_handle);
 
 
  if (ret != BLE_STATUS_SUCCESS) {
      PRINTF("ret error: %02X", ret);
    goto fail;
  }
  PRINTF("RX characteristick initialized\n");
 
  return BLE_STATUS_SUCCESS;
 
fail:  
  return BLE_STATUS_ERROR;
}

And that works fine.

Next, I've started working on RX characteristic - first simple task was to print everything received from the PC to uart debug console:

Event callback:

/**
 * @brief  Callback processing the ACI events.
 * @note   Inside this function each event must be identified and correctly
 *         parsed.
 * @param  void* Pointer to the ACI packet
 * @retval None
 */
void user_notify(void * pData)
{
  hci_uart_pckt *hci_pckt = pData;
  /* obtain event packet */
  hci_event_pckt *event_pckt = (hci_event_pckt*)hci_pckt->data;
  
  if(hci_pckt->type != HCI_EVENT_PKT)
    return;
  PRINTF("HCI EVENT: 0x%02X\n", event_pckt->evt);
  switch(event_pckt->evt){
    
  case EVT_DISCONN_COMPLETE:
    {
      GAP_DisconnectionComplete_CB();
    }
    break;
    
  case EVT_LE_META_EVENT:
    {
      evt_le_meta_event *evt = (void *)event_pckt->data;
      
      switch(evt->subevent){
      case EVT_LE_CONN_COMPLETE:
        {
          evt_le_connection_complete *cc = (void *)evt->data;
          GAP_ConnectionComplete_CB(cc->peer_bdaddr, cc->handle);
        }
        break;
      }
    }
    break;
    
  case EVT_VENDOR:
    {
      evt_blue_aci *blue_evt = (void*)event_pckt->data;
      PRINTF("event code 0x%04X\n", blue_evt->ecode);
      switch(blue_evt->ecode){
      case EVT_BLUE_GATT_READ_PERMIT_REQ:
        {
          PRINTF("EVENT notify");
          evt_gatt_read_permit_req *pr = (void*)blue_evt->data;                    
          Read_Request_CB(pr->attr_handle);                    
        }
        break;        
/*********************** MY CODE ***********************/
      case EVT_BLUE_GATT_ATTRIBUTE_MODIFIED:
      {
          evt_gatt_attr_modified_IDB05A1 *event = (evt_gatt_attr_modified_IDB05A1*)event_pckt->data;
          PRINTF("connection handle: %04X\n"
                 "attribute handle : %04X\n"
                 "data lenth :     : %02X\n"
                 "offset : %04X\n",
                 event->conn_handle,
                 event->attr_handle,
                 event->data_length,
                 event->offset);
          PRINTF("RX <-");
          for(int i=0; i< event->data_length + 6; i++){
              PRINTF(" %02X", event->att_data[i]);
          }
          PRINTF("\n");
          break;
      }
/***********************end of  MY CODE ***********************/
      }
      
    }
    break;
  }    
}

problems: :

  1. this code always prints '00 00' prefix before the proper data
  2. event->data_length is always 16 (0x10)
  3. event->offset - contains real length of the data sent from the PC (eg. for 0xdeadbeef its 4, for 0xdeadbeefdeadbeef its 8, and for 20 bytes its 20)
  4. in order to read 20 bytes of data sent from the PC i have to read buffer starting from event->att_data[2] to event->att_data[22]
  5. event->offset contains data with bytes reversed : 0x0400 means 4 , and 0x1400 means 20.

I use GNU Arm Embedded Toolchain on windows 10 with makefile generated from CubeMx for compiling my source code. CubeMX project attached.

Can someone confirm if all those things are bugs to be reported

2 REPLIES 2
KeM.
Associate
Winfred LU
ST Employee

Hi Kayon,

This is interesting.

I think probably the stack has been updated and ACI_GATT_ATTRIBUTE_MODIFIED_EVENT format shall be the same as BlueNRG-1/2:

0690X000009YrGPQA0.png

In this case, please try to modify evt_gatt_attr_modified_IDB05A1 structure like:

typedef __packed struct _evt_gatt_attr_modified_IDB05A1{
  uint16_t conn_handle;
  uint16_t attr_handle;
  uint16_t offset; //4th 5th byte
  uint8_t  data_length; //6th byte
  uint8_t  att_data[VARIABLE_SIZE];
} PACKED evt_gatt_attr_modified_IDB05A1;

When you saw event->data_length always being 0x10, i guess it was because bit 15 in real offset was 1 to indicate other events will follow for the remaining value.

And you saw event->offset having data length, because low byte in real offset (5th byte) is 0, which accidentally makes your offset having high byte equal to 0 and low byte equal to real data_length (6th byte).

These shall explain the length and offset fields.

Although it is still tricky because high byte of offset is supposed to be at 5th byte not 4th byte, which instead shall make your offset 0x0410 meaning 4 , and 0x1410 meaning 20.

But i cannot explain the dummy 2 bytes (00 00) in front of the data. I think it is probably safe to just ignore the 2 bytes.

Thus in the end, the structure will need to be:

typedef __packed struct _evt_gatt_attr_modified_IDB05A1{
  uint16_t conn_handle;
  uint16_t attr_handle;
  uint16_t offset;
  uint8_t  data_length;
  uint16_t dummy;
  uint8_t  att_data[VARIABLE_SIZE];
} PACKED evt_gatt_attr_modified_IDB05A1;

Thank you.

Best Regards,

Winfred