You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@mynewt.apache.org by GitBox <gi...@apache.org> on 2022/03/14 12:42:34 UTC

[GitHub] [mynewt-nimble] KristjanB opened a new issue #1206: BLE Nimble SPP packet fragmentation (packet > MTU)

KristjanB opened a new issue #1206:
URL: https://github.com/apache/mynewt-nimble/issues/1206


   ## Problem Description
   MTU size: 120
   Sent packet size from server: 130
   Received size on client: 117
   
   Using two ESP32, one acts as client and the other as server. The client subscribes to the servers notify characteristics, and server sends a package that is larger than exchanged MTU. 
   On client side, the packet is received, however it's always truncated to the MTU-3 size. 
   Weird thing is, if I send similar packet to the server, GATT callback BLE_GATT_ACCESS_OP_WRITE_CHR gets called as many time as necessary for the whole packet to be received.
   
   So my question is, does client handle packet fragmentation automatically just like GATT server, or do I have to implement my own algorithm?
   
   Thanks!
   Kristjan
   
   Please check the code below:
   
   ### Expected Behavior
   
   Callback gets called as many times as it takes to receive the whole packet.
   
   ### Actual Behavior
   
   Callback is called only once with MTU-3 size, regardless of the actual packet size.
   
   ### Code to reproduce this issue
   
   This snippet is from CLIENT when gap event is called with BLE_GAP_EVENT_NOTIFY_RX 
   ```cpp
   esp_err_t ble_spp_get_notification(struct ble_gap_event *event)
   {
       // Flatten the buffer to get the full data
       uint16_t fullLength = OS_MBUF_PKTLEN(event->notify_rx.om);
       uint8_t fullData[fullLength];
       if (ble_hs_mbuf_to_flat(event->notify_rx.om, &fullData, fullLength, NULL) != 0) {
           ESP_LOGE(tag, "Failed to get all write data");
           return 0;
       }
       printf("Flat buffer size: %d\n", fullLength);
       for(int i = 0; i < fullLength; i++) {
           printf("%d ", fullData[i]);
       }
       return ESP_OK;
   }
   
   ```
   This is how packet is constructed on SERVER. As you can see the size of packet is 130 bytes of 1's.
   ```cpp
           uint8_t send[130] = {0};
           for(int i = 0; i < sizeof(send); i++) {
               send[i] = 1;
           }
           // allocate MTU size
           packet = calloc(130, sizeof(uint8_t));
           if(!packet) {
               return ESP_ERR_NO_MEM;
           }
           txom = ble_hs_mbuf_from_flat(send, 130);
           ESP_LOGI("SPP", "packet size: %d, val_handle: %d", sizeof(send), ble_spp_svc_gatt_read_val_handle);
           ret = ble_gattc_notify_custom(get_conn_handle(),ble_spp_svc_gatt_read_val_handle,txom);
           ESP_ERROR_CHECK_WITHOUT_ABORT(ret);
           free(packet);
           packet = NULL;
   
   ```
   // If your code is longer than 30 lines, [GIST](https://gist.github.com) is preferred.
   
   ## Debug Logs
   CLIENT
   ```
   I (00:00:01.979) NimBLE: Connection established
   I (00:00:01.981) NimBLE:
   
   I (00:00:01.982) NimBLE: GATT procedure initiated: discover all services
   
   I (00:00:01.998) NimBLE: GATT procedure initiated: exchange mtu
   
   I (00:00:02.087) NimBLE: mtu update event; conn_handle=0 cid=4 mtu=120
   
   I (00:00:02.282) NimBLE: GATT procedure initiated: discover all characteristics;
   I (00:00:02.285) NimBLE: start_handle=1 end_handle=5
   
   I (00:00:02.482) NimBLE: GATT procedure initiated: discover all characteristics;
   I (00:00:02.484) NimBLE: start_handle=6 end_handle=9
   
   I (00:00:02.682) NimBLE: GATT procedure initiated: discover all characteristics;
   I (00:00:02.684) NimBLE: start_handle=10 end_handle=17
   
   I (00:00:02.882) NimBLE: GATT procedure initiated: discover all characteristics;
   I (00:00:02.884) NimBLE: start_handle=18 end_handle=21
   
   I (00:00:03.082) NimBLE: GATT procedure initiated: discover all characteristics;
   I (00:00:03.084) NimBLE: start_handle=22 end_handle=65535
   
   I (00:00:03.282) NimBLE: GATT procedure initiated: discover all descriptors;
   I (00:00:03.284) NimBLE: chr_val_handle=8 end_handle=9
   
   I (00:00:03.383) NimBLE: GATT procedure initiated: discover all descriptors;
   I (00:00:03.385) NimBLE: chr_val_handle=12 end_handle=13
   
   I (00:00:03.482) NimBLE: GATT procedure initiated: discover all descriptors;
   I (00:00:03.485) NimBLE: chr_val_handle=20 end_handle=21
   
   I (00:00:03.583) NimBLE: GATT procedure initiated: discover all descriptors;
   I (00:00:03.585) NimBLE: chr_val_handle=24 end_handle=65535
   
   I (00:00:03.782) NimBLE: Service discovery complete; status=0 conn_handle=0
   
   I (00:00:03.785) NimBLE: GATT procedure initiated: write;
   I (00:00:03.786) NimBLE: att_handle=25 len=2
   
   I (00:00:03.882) NimBLE: Subscribe complete; status=0 conn_handle=0 attr_handle=25
   
   I (00:00:08.035) NimBLE: received notification; conn_handle=0 attr_handle=24 attr_len=117
   
   Flat buffer size: 117
   1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
   ```
   SERVER
   ```
   I (00:40:19.584) BLE: BLE Connection Successful!
   I (00:40:19.586) BLE: handle=0 our_ota_addr_type=0 our_ota_addr=
   I (00:40:19.589) BLE: 10:52:1c:5d:d9:32
   I (00:40:19.600) BLE:  our_id_addr_type=0 our_id_addr=
   I (00:40:19.601) BLE: 10:52:1c:5d:d9:32
   I (00:40:19.602) BLE:  peer_ota_addr_type=0 peer_ota_addr=
   I (00:40:19.614) BLE: 24:0a:c4:8e:0e:ce
   I (00:40:19.615) BLE:  peer_id_addr_type=0 peer_id_addr=
   I (00:40:19.626) BLE: 24:0a:c4:8e:0e:ce
   I (00:40:19.627) BLE:  conn_itvl=40 conn_latency=0 supervision_timeout=256 encrypted=0 authenticated=0 bonded=0
   
   I (00:40:19.639) NimBLE: GAP procedure initiated: stop advertising.
   
   I (00:40:19.656) BLE: mtu update event; conn_handle=0 cid=4 mtu=120
   
   I (00:40:21.438) BLE: subscribe event; conn_handle=0 attr_handle=24 reason=1 prevn=0 curn=1 previ=0 curi=0
   I (00:40:21.441) BLE: subscribe event; cur_notify=1
    value handle; val_handle=12
   
   I (00:40:21.452) BLE_GAP_SUBSCRIBE_EVENT: conn_handle from subscribe=0
   esp32> ble --send 1
   I (00:40:25.594) SPP: packet size: 130, val_handle: 24
   I (00:40:25.596) NimBLE: GATT procedure initiated: notify;
   I (00:40:25.597) NimBLE: att_handle=24
   
   ```


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: commits-unsubscribe@mynewt.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [mynewt-nimble] sjanc commented on issue #1206: BLE Nimble SPP packet fragmentation (packet > MTU)

Posted by GitBox <gi...@apache.org>.
sjanc commented on issue #1206:
URL: https://github.com/apache/mynewt-nimble/issues/1206#issuecomment-1067669425


   Hi,
   
   This is defined in Bluetooth specification:
   "If the attribute value is longer than (ATT_MTU-3) octets, then only the first (ATT_MTU-3) octets of this attributes value can be sent in a notification.
   
   Note: For a client to get a long attribute, it must use the ATT_READ_BLOB_REQ PDU (see Section 3.4.4.5) following the receipt of this notification."


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: commits-unsubscribe@mynewt.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [mynewt-nimble] KristjanB commented on issue #1206: BLE Nimble SPP packet fragmentation (packet > MTU)

Posted by GitBox <gi...@apache.org>.
KristjanB commented on issue #1206:
URL: https://github.com/apache/mynewt-nimble/issues/1206#issuecomment-1066818601


   Yes, the header size is not the issue here. 
   
   Ok, thank you for this insight. But could you give me some more information? How can I know that there are more chunks to be read? I know that for example OS_MBUF_PKTLEN(event->notify_rx.om) returns size of the whole buffer, but the issue is that I get 117 bytes instead of 130 and the last 10 bytes are lost somewhere (MTU size is 120 in this case).


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: commits-unsubscribe@mynewt.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [mynewt-nimble] sjanc commented on issue #1206: BLE Nimble SPP packet fragmentation (packet > MTU)

Posted by GitBox <gi...@apache.org>.
sjanc commented on issue #1206:
URL: https://github.com/apache/mynewt-nimble/issues/1206#issuecomment-1066771683


   this is expected, ATT MTU includes ATT header (opcode [1byte]+ handle [2 bytes])
   
   regarding fragmentation,   when writing >MTU bytes of data to serwer client is doing long write operation, which consists on multiple att prepare writes.  On notification this is not automated,  ie server sends notification up to MTU bytes, and then it is client responsibility to do read blob with proper offset to read remaining data (and I think that in NimBLE it is up to application to decide if it wants to read the rest or not)


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: commits-unsubscribe@mynewt.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org