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

Nus profile seems to cause system reset if the data length too long.

iphone5_b.psdm370_android6_b.psdlong_write_error.pngI using SDK11. I porting nus profile to my system and make a customer's UUID. I use Lightblue on iPhone 5 to connect my system. I sent a data through my customer's UUID. My system work fine when the data length is less than or equal 20 bytes. It will cause system reset if the data length is great than 20 bytes. Was the softdevice error, or I made something wrong?

  • So you are triggering long write/queued write by trying to write more than 20 bytes, which is not supported by nus, see this for more information. You get event 2, which is BLE_EVT_USER_MEM_REQUEST. If you want to support long writes you need to modify the example. You need to handle the events and increase the maximum length of the TX characteristic value. In most cases it is better to split your data into 20 bytes pieces and reassemble the data in the peer application.

  • I don't want to support long writes. I just want to protect my project against system reset. Do you have easy way to do it?

  • I am using ble_uart example. I'll get the event of BLE_EVT_USER_MEM_REQUEST at the function of on_ble_evt(ble_evt_t * p_ble_evt) if I send 22 characters at iPhone5 using LightBlue. It will cause to system reset after 30 seconds if I don't process it at the event of BLE_EVT_USER_MEM_REQUEST. It will also cause to system reset after 30 seconds if I call the function of sd_ble_user_mem_reply(p_ble_evt->evt.gap_evt.conn_handle, NULL) at the event of BLE_EVT_USER_MEM_REQUEST. I cannot protect my project against causing to system reset if I send over 20 characters at iPhone5 using LightBlue. Can anyone do me a faver? I don't need to support long writes.

  • I want to help you, but I don't have an iOS device here to test with, so I'm not 100% sure what iOS is doing. Providing a sniffer trace would really help, you can use the nRF Sniffer. If you respond with sd_ble_user_mem_reply(), you should receive a BLE_GATTS_EVT_RW_AUTHORIZE_REQUEST event, as you see here. Are you receiving this event? If you do, you can try to call sd_ble_gatts_rw_authorize_reply() with gatt_status set to something else than BLE_GATT_STATUS_SUCCESS, for example BLE_GATT_STATUS_ATTERR_INVALID_ATT_VAL_LENGTH or BLE_GATT_STATUS_ATTERR_REQUEST_NOT_SUPPORTED. However, I do not know how iOS will respond to this.

  • Yes, If I respond with sd_ble_user_mem_reply( p_ble_evt->evt.gap_evt.conn_handle, NULL), I receive a BLE_GATTS_EVT_RW_AUTHORIZE_REQUEST event. If I respond with auth_reply.params.write.gatt_status = BLE_GATT_STATUS_ATTERR_REQUEST_NOT_SUPPORTED and auth_reply.type = BLE_GATTS_AUTHORIZE_TYPE_WRITE. Then I call the function of sd_ble_gatts_rw_authorize_reply(p_ble_evt->evt.gatts_evt.conn_handle, &auth_reply) like I post on 3rd Nov, and it will return error code = 7 (NRF_ERROR_INVALID_PARAM, cause system reset).

    If I change the code as follows, the system won't cause system reset. I want to know it is correct or not? How may bytes I need to use? Which event I will get at each message segmentation to get data? LightBlue on BlueiPhone and nRFConnect on Android phone have the same result.

    case BLE_EVT_USER_MEM_REQUEST:
    {
        static ble_user_mem_block_t mem_block;
        static uint8_t buffer[40];
        mem_block.len = 40;
        mem_block.p_mem = &buffer[0];
        err_code = sd_ble_user_mem_reply(m_conn_handle, &mem_block);
        break;
    }
    case BLE_EVT_USER_MEM_RELEASE:
    {
        // call an error respond function.
        break;
    }
    
Related