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

Can I create Characteristic with Notification only, no Read, no Write

Can I create Characteristic with Notification only, no Read, no Write

I can remove the //char_md.char_props.write = 1; and only the Read and Notify Properties show up in MCP (or the iPhone)

When I comment out the char_md.char_props.read = 1;

Advertising stops and I can not connect to the device.

All I need is a Notification. The server collects data on three (3) sensors, and sends the data using three (3) services. 6-bytes per service, nonstop.

So actually one characteristic with a Notification per service.

Note: I guess eventually with a client app, one would Enable the Notification, and then ignore the Read property.

Any help appreciated

Parents
  • Bjørn

    I have it working. It seems than with no delay between CCCD updates, the code freezes. So it seems with both write and read out, the Notification keeps the code busy. I now have a 2sec delay between updates, and removed write and read, and it works fine.

    static uint32_t our_char_add(ble_os_t * p_our_service) { uint32_t err_code = 0; // Variable to hold return codes from library and softdevice functions

    // OUR_JOB: Step 2.A, Add a custom characteristic UUID
    ble_uuid_t          char_uuid;
    ble_uuid128_t       base_uuid = BLE_UUID_OUR_BASE_UUID;
    char_uuid.uuid      = BLE_UUID_OUR_CHARACTERISTC_UUID;
    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));
    //GvR
    //char_md.char_props.read = 1;
    //GvR
    //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));
    //GvR
    //BLE_GAP_CONN_SEC_MODE_SET_ENC_NO_MITM(&cccd_md.read_perm);
    //BLE_GAP_CONN_SEC_MODE_SET_ENC_NO_MITM(&cccd_md.write_perm);
    
    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;
    
    
    // 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     = 3;
    //attr_char_value.init_len    = 3;
    //uint8_t value[3]            = {0x00, 0x73, 0xCF};
    attr_char_value.max_len     = 6;
    attr_char_value.init_len    = 6;
    uint8_t value[6]            = {0x16, 0x15, 0x14, 0x13, 0x12, 0x11};
    //uint8_t value[4]            = {0xA0,0xB1,0xC2,0xD3};
    //uint8_t value[4]            = {0x00, 0x73,0x63,0x63};
    
    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);
    APP_ERROR_CHECK(err_code);
    
    NRF_LOG_INFO("\r\nService handle: %#x\n\r", p_our_service->service_handle);
    NRF_LOG_INFO("Char value handle: %#x\r\n", p_our_service->char_handles.value_handle);
    NRF_LOG_INFO("Char cccd handle: %#x\r\n\r\n", p_our_service->char_handles.cccd_handle);
    
    return NRF_SUCCESS;
    

    }

Reply
  • Bjørn

    I have it working. It seems than with no delay between CCCD updates, the code freezes. So it seems with both write and read out, the Notification keeps the code busy. I now have a 2sec delay between updates, and removed write and read, and it works fine.

    static uint32_t our_char_add(ble_os_t * p_our_service) { uint32_t err_code = 0; // Variable to hold return codes from library and softdevice functions

    // OUR_JOB: Step 2.A, Add a custom characteristic UUID
    ble_uuid_t          char_uuid;
    ble_uuid128_t       base_uuid = BLE_UUID_OUR_BASE_UUID;
    char_uuid.uuid      = BLE_UUID_OUR_CHARACTERISTC_UUID;
    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));
    //GvR
    //char_md.char_props.read = 1;
    //GvR
    //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));
    //GvR
    //BLE_GAP_CONN_SEC_MODE_SET_ENC_NO_MITM(&cccd_md.read_perm);
    //BLE_GAP_CONN_SEC_MODE_SET_ENC_NO_MITM(&cccd_md.write_perm);
    
    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;
    
    
    // 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     = 3;
    //attr_char_value.init_len    = 3;
    //uint8_t value[3]            = {0x00, 0x73, 0xCF};
    attr_char_value.max_len     = 6;
    attr_char_value.init_len    = 6;
    uint8_t value[6]            = {0x16, 0x15, 0x14, 0x13, 0x12, 0x11};
    //uint8_t value[4]            = {0xA0,0xB1,0xC2,0xD3};
    //uint8_t value[4]            = {0x00, 0x73,0x63,0x63};
    
    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);
    APP_ERROR_CHECK(err_code);
    
    NRF_LOG_INFO("\r\nService handle: %#x\n\r", p_our_service->service_handle);
    NRF_LOG_INFO("Char value handle: %#x\r\n", p_our_service->char_handles.value_handle);
    NRF_LOG_INFO("Char cccd handle: %#x\r\n\r\n", p_our_service->char_handles.cccd_handle);
    
    return NRF_SUCCESS;
    

    }

Children
No Data
Related