KKopyscinski commented on code in PR #1426:
URL: https://github.com/apache/mynewt-nimble/pull/1426#discussion_r1284007335


##########
nimble/host/src/ble_gattc.c:
##########
@@ -4212,6 +4223,131 @@ ble_gatts_notify_custom(uint16_t conn_handle, uint16_t 
chr_val_handle,
     return rc;
 }
 
+int
+ble_gatts_multi_notify_custom(uint16_t conn_handle,
+                              struct ble_gatt_hv * tuples, uint16_t num_tuples)
+{
+#if !MYNEWT_VAL(BLE_GATT_MULTI_NOTIFY)
+    return BLE_HS_ENOTSUP;
+#endif
+
+    int i;
+    int rc;
+    uint16_t mtu;
+    uint16_t pdu_size;
+    int split_at;
+    struct os_mbuf *om = NULL;
+
+    STATS_INC(ble_gattc_stats, multi_notify);
+    ble_gattc_log_multi_notify(tuples, num_tuples);
+
+    for (i = 0; i < num_tuples; i++) {
+        if (tuples[i].value == NULL) {
+            /* No custom attribute data; read the value from the specified
+             * attribute
+             */
+            tuples[i].value = ble_hs_mbuf_att_pkt();
+            if (tuples[i].value == NULL) {
+                rc = BLE_HS_ENOMEM;
+                goto done;
+            }
+            rc = ble_att_svr_read_handle(BLE_HS_CONN_HANDLE_NONE,
+                                         tuples[i].handle, 0, tuples[i].value, 
NULL);
+            if (rc != 0) {
+                /* Fatal error; application disallowed attribute read. */
+                rc = BLE_HS_EAPP;
+                goto done;
+            }
+        }
+    }
+
+    mtu = ble_att_mtu(conn_handle);
+    pdu_size = sizeof(uint8_t); /* Opcode */
+    split_at = 0;
+
+    for (i = 0; i < num_tuples; i++) {
+        pdu_size += (2 * sizeof(uint16_t)) + OS_MBUF_PKTLEN(tuples[i].value);
+        if (pdu_size > mtu) {
+            /* The notification will need to be split */
+            if (i == split_at) {
+                /* Single notification too large for server,
+                 * cannot send notify without truncating.
+                 */
+                rc = BLE_HS_ENOMEM;
+                goto done;
+            }
+            split_at = i;
+            /* Reinitialize loop */
+            i--;
+            pdu_size = sizeof(uint8_t);
+        }
+    }
+
+    pdu_size = sizeof(uint8_t);
+    split_at = 0;
+    om = ble_hs_mbuf_att_pkt();
+    if(om == NULL) {
+        rc = BLE_HS_ENOMEM;
+        goto done;
+    }
+    for (i = 0; i < num_tuples; i++) {
+        pdu_size += (2 * sizeof(uint16_t)) + OS_MBUF_PKTLEN(tuples[i].value);
+        if (pdu_size > mtu) {
+            rc = ble_att_clt_tx_multi_notify(conn_handle, om);
+            if (rc != 0) {
+                goto done;
+            }
+            split_at = i;
+            i--;
+            pdu_size = sizeof(uint8_t);
+            om = ble_hs_mbuf_att_pkt();
+            if(om == NULL) {
+                rc = BLE_HS_ENOMEM;
+                goto done;
+            }
+            continue;
+        }
+        /* Handle */
+        rc = os_mbuf_copyinto(om, OS_MBUF_PKTLEN(om),
+                              &tuples[i].handle, sizeof tuples[i].handle);
+        if (rc != 0) {
+            rc = BLE_HS_ENOMEM;
+            os_mbuf_free_chain(om);
+            goto done;
+        }
+        /* Length */
+        rc = os_mbuf_copyinto(om, OS_MBUF_PKTLEN(om),
+                              &(OS_MBUF_PKTLEN(tuples[i].value)),
+                              sizeof(OS_MBUF_PKTLEN(tuples[i].value)));
+        if (rc != 0) {
+            rc = BLE_HS_ENOMEM;
+            os_mbuf_free_chain(om);
+            goto done;
+        }
+        /* Value */
+        rc = os_mbuf_appendfrom(om, tuples[i].value,
+                                0, OS_MBUF_PKTLEN(tuples[i].value));
+        if (rc != 0) {
+            rc = BLE_HS_ENOMEM;
+            os_mbuf_free_chain(om);
+            goto done;
+        }
+    }
+    rc = ble_att_clt_tx_multi_notify(conn_handle, om);

Review Comment:
   `int attr_in_cur_pdu_cnt = 0;` should be added on top, and then
   ```suggestion
       for (i = 0; i < num_tuples; i++) {
           pdu_size += (2 * sizeof(uint16_t)) + OS_MBUF_PKTLEN(tuples[i].value);
           /* Multiple handle notification can only be sent with two or more 
handles */
           if (pdu_size > mtu && attr_in_cur_pdu_cnt > 2) {
               rc = ble_att_clt_tx_multi_notify(conn_handle, om);
               if (rc != 0) {
                   goto done;
               }
               attr_in_cur_pdu_cnt = 0;
               pdu_size = sizeof(uint8_t);
               om = ble_hs_mbuf_att_pkt();
               if(om == NULL) {
                   rc = BLE_HS_ENOMEM;
                   goto done;
               }
               if (num_tuples - i < 2) {
                   BLE_HS_LOG(DEBUG, "Notifications partially sent (%d/%d)", i, 
num_tuples);
                   i--;
                   goto done;
               }
           }
           /* Handle */
           rc = os_mbuf_copyinto(om, OS_MBUF_PKTLEN(om),
                                 &tuples[i].handle, sizeof tuples[i].handle);
           if (rc != 0) {
               rc = BLE_HS_ENOMEM;
               os_mbuf_free_chain(om);
               goto done;
           }
           /* Length */
           rc = os_mbuf_copyinto(om, OS_MBUF_PKTLEN(om),
                                 &(OS_MBUF_PKTLEN(tuples[i].value)),
                                 sizeof(OS_MBUF_PKTLEN(tuples[i].value)));
           if (rc != 0) {
               rc = BLE_HS_ENOMEM;
               os_mbuf_free_chain(om);
               goto done;
           }
           /* Value */
           rc = os_mbuf_appendfrom(om, tuples[i].value,
                                   0, OS_MBUF_PKTLEN(tuples[i].value));
           if (rc != 0) {
               rc = BLE_HS_ENOMEM;
               os_mbuf_free_chain(om);
               goto done;
           }
           attr_in_pdu_cnt++;
       }
       rc = ble_att_clt_tx_multi_notify(conn_handle, om);
   ```
   plus what in other comments



-- 
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-unsubscr...@mynewt.apache.org

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

Reply via email to