@@ -58,6 +58,10 @@ void BLECharacteristic::_init(void)
5858 _handles.sccd_handle = BLE_GATT_HANDLE_INVALID;
5959 _handles.cccd_handle = BLE_GATT_HANDLE_INVALID;
6060
61+ _long_wr.buffer = NULL ;
62+ _long_wr.bufsize = 0 ;
63+ _long_wr.count = 0 ;
64+
6165 _rd_authorize_cb = NULL ;
6266 _wr_authorize_cb = NULL ;
6367 _wr_cb = NULL ;
@@ -337,15 +341,84 @@ err_t BLECharacteristic::addDescriptor(BLEUuid bleuuid, void const * content, ui
337341 */
338342void BLECharacteristic::_eventHandler (ble_evt_t * event)
339343{
344+ uint16_t const conn_hdl = event->evt .common_evt .conn_handle ;
345+
340346 switch (event->header .evt_id )
341347 {
342348 case BLE_GATTS_EVT_RW_AUTHORIZE_REQUEST:
343349 {
344350 ble_gatts_evt_rw_authorize_request_t * request = &event->evt .gatts_evt .params .authorize_request ;
345351
346- if ( ( request->type == BLE_GATTS_AUTHORIZE_TYPE_WRITE) && (_wr_authorize_cb != NULL ) )
352+ if (request->type == BLE_GATTS_AUTHORIZE_TYPE_WRITE)
347353 {
348- _wr_authorize_cb (*this , &request->request .write );
354+ ble_gatts_evt_write_t * wr_req = &request->request .write ;
355+
356+ switch (wr_req->op )
357+ {
358+ case BLE_GATTS_OP_PREP_WRITE_REQ:
359+ {
360+ // Prepare Long Write
361+ if ( !_long_wr.buffer )
362+ {
363+ // Allocate long write buffer if not previously
364+ _long_wr.bufsize = 1024 ; // TODO bufsize is 10x MTU
365+ _long_wr.buffer = (uint8_t *) rtos_malloc (_long_wr.bufsize );
366+ _long_wr.count = 0 ;
367+ }
368+
369+ ble_gatts_rw_authorize_reply_params_t reply = { .type = BLE_GATTS_AUTHORIZE_TYPE_WRITE };
370+
371+ if ( wr_req->offset + wr_req->len > _long_wr.bufsize )
372+ {
373+ reply.params .write .gatt_status = BLE_GATT_STATUS_ATTERR_PREPARE_QUEUE_FULL;
374+ }else
375+ {
376+ reply.params .write = ((ble_gatts_authorize_params_t ) {
377+ .gatt_status = BLE_GATT_STATUS_SUCCESS,
378+ .update = 1 ,
379+ .offset = wr_req->offset ,
380+ .len = wr_req->len ,
381+ .p_data = wr_req->data
382+ });
383+
384+ memcpy (_long_wr.buffer +wr_req->offset , wr_req->data , wr_req->len );
385+ _long_wr.count = max16 (_long_wr.count , wr_req->offset + wr_req->len );
386+ }
387+
388+ sd_ble_gatts_rw_authorize_reply (conn_hdl, &reply);
389+ }
390+ break ;
391+
392+ case BLE_GATTS_OP_EXEC_WRITE_REQ_NOW:
393+ // Execute Long Write
394+ if ( _long_wr.buffer )
395+ {
396+ ble_gatts_rw_authorize_reply_params_t reply = { .type = BLE_GATTS_AUTHORIZE_TYPE_WRITE };
397+ reply.params .write .gatt_status = BLE_GATT_STATUS_SUCCESS;
398+
399+ sd_ble_gatts_rw_authorize_reply (conn_hdl, &reply);
400+
401+ // Long write complete, call write callback if set
402+ if (_wr_cb) _wr_cb (*this , _long_wr.buffer , _long_wr.count , 0 );
403+
404+ // free up memory
405+ rtos_free (_long_wr.buffer );
406+ _long_wr.buffer = NULL ;
407+ _long_wr.bufsize = _long_wr.count = 0 ;
408+ }
409+ break ;
410+
411+ case BLE_GATTS_OP_EXEC_WRITE_REQ_CANCEL:
412+ // Cancel Long Write
413+ break ;
414+
415+ case BLE_GATTS_OP_WRITE_REQ:
416+ // Write Request with authorization
417+ if (_wr_authorize_cb != NULL ) _wr_authorize_cb (*this , &request->request .write );
418+ break ;
419+
420+ default : break ;
421+ }
349422 }
350423
351424 if ( (request->type == BLE_GATTS_AUTHORIZE_TYPE_READ) && (_rd_authorize_cb != NULL ))
@@ -359,12 +432,12 @@ void BLECharacteristic::_eventHandler(ble_evt_t* event)
359432 {
360433 ble_gatts_evt_write_t * request = &event->evt .gatts_evt .params .write ;
361434
435+ LOG_LV2_BUFFER (NULL , request->data , request->len );
436+
362437 // Value write
363438 if (request->handle == _handles.value_handle )
364439 {
365440 LOG_LV2 (" GATTS" , " attr's value, uuid = 0x%04X" , request->uuid .uuid );
366- LOG_LV2_BUFFER (NULL , request->data , request->len );
367-
368441 // TODO Ada callback
369442 if (_wr_cb)
370443 {
@@ -385,7 +458,6 @@ void BLECharacteristic::_eventHandler(ble_evt_t* event)
385458 if ( request->handle == _handles.cccd_handle )
386459 {
387460 LOG_LV2 (" GATTS" , " attr's cccd" );
388- LOG_LV2_BUFFER (NULL , request->data , request->len );
389461
390462 // Invoke callback if set
391463 if (_cccd_wr_cb)
0 commit comments