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: