This post is older than 2 years and might not be relevant anymore
More Info: Consider searching for newer posts

I can't figure out how to read changes in BLE attributes (Central->Peripheral) BASIC question

Hi, I've completed the first 3 BLE tutorials (about advertising and Services).

I've got notifications up and running on the peripheral by using a timer and hvx as in the attribute tutorial.

What i now whant to do is read from another attribute, updated using  the connector software. I'm not even sure about whether my approach is even close to correct. nevertheless this is what i did.

defining my attribute:

- i've allowed read/write

- notify isn't enabled

static uint32_t our_char_add_2(ble_os_t *p_our_service) {
  // OUR_JOB: Step 2.A, Add a custom characteristic UUID

  uint32_t err_code;
  ble_uuid_t char_uuid;
  ble_uuid128_t base_uuid = BLE_UUID_OUR_BASE_UUID;
  char_uuid.uuid = BLE_UUID_OUR_CHARACTERISTC_UUID_2;
  err_code = sd_ble_uuid_vs_add(&base_uuid, &char_uuid.type);
  APP_ERROR_CHECK(err_code);

  // OUR_JOB: Step 2.F Add read/write properties to our characteristic
  ble_gatts_char_md_t char_md;
  memset(&char_md, 0, sizeof(char_md));
  char_md.char_props.read = 1;
  char_md.char_props.write = 1;

  // OUR_JOB: Step 3.A, Configuring Client Characteristic Configuration Descriptor metadata and add to char_md structure

  ble_gatts_attr_md_t cccd_md;
  memset(&cccd_md, 0, sizeof(cccd_md));
  BLE_GAP_CONN_SEC_MODE_SET_OPEN(&cccd_md.read_perm);
  BLE_GAP_CONN_SEC_MODE_SET_OPEN(&cccd_md.write_perm);
  cccd_md.vloc = BLE_GATTS_VLOC_STACK;
  char_md.p_cccd_md = &cccd_md;
  //char_md.char_props.notify = 1;
  //char_md.char_props.indicate = 1;

  // OUR_JOB: Step 2.B, Configure the attribute metadata
  ble_gatts_attr_md_t attr_md;
  memset(&attr_md, 0, sizeof(attr_md));
  attr_md.vloc = BLE_GATTS_VLOC_STACK;

  // OUR_JOB: Step 2.G, Set read/write security levels to our characteristic
  BLE_GAP_CONN_SEC_MODE_SET_OPEN(&attr_md.read_perm);
  BLE_GAP_CONN_SEC_MODE_SET_OPEN(&attr_md.write_perm);

  // OUR_JOB: Step 2.C, Configure the characteristic value attribute

  ble_gatts_attr_t attr_char_value;
  memset(&attr_char_value, 0, sizeof(attr_char_value));
  attr_char_value.p_uuid = &char_uuid;
  attr_char_value.p_attr_md = &attr_md;

  // OUR_JOB: Step 2.H, Set characteristic length in number of bytes
  attr_char_value.max_len = 1;
  attr_char_value.init_len = 1;
  uint8_t value[1] = {0xFF};
  attr_char_value.p_value = value;

  // OUR_JOB: Step 2.E, Add our new characteristic to the service
  err_code = sd_ble_gatts_characteristic_add(p_our_service->service_handle,
      &char_md,
      &attr_char_value,
      &p_our_service->char_handles_2);
  APP_ERROR_CHECK(err_code);

  return NRF_SUCCESS;
}

my read routine:

 void LED_update(ble_os_t * p_our_service, int *gpio_val) {
 
    
 if (p_our_service->conn_handle != BLE_CONN_HANDLE_INVALID ) {

    ret_code_t err_code;
    ble_gatts_value_t read_val;
    memset(&read_val, 0, sizeof(read_val));

    read_val.len=sizeof(*gpio_val);
    read_val.offset=0;

    sd_ble_gatts_value_get(p_our_service->conn_handle,p_our_service->char_handles_2.value_handle,&read_val);


     if(err_code!=NRF_SUCCESS)
   {
   printf("error:");
   printf(" %d",err_code);
   }
    APP_ERROR_CHECK(err_code);
    printf("%d\n",*read_val.p_value);
    *gpio_val=*read_val.p_value;
    }

    }

this is called using my timer:

static void timer_timeout_handler(void *p_context) {
  int SW_status = 0;
  int LED_status = 0;
  SW_status = nrf_gpio_pin_read(SW1);

 button_press_update(&m_our_service, &SW_status);

 LED_update(&m_our_service, &LED_status);

 nrf_gpio_pin_write(LED1, LED_status);
}

I would think that reading from the attribute wouldn't do any harm, but is crashes with this error code

 err_code=0x00010000

also if this is the approach, why wouldn't you just use sd_ble_gatts_value_set () when writing to a peripheral ?

EDIT: error code might be wrong, i now get this, and don't know how to get a readable code:

Parents Reply Children
No Data
Related