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 2023/01/13 07:03:47 UTC

[GitHub] [mynewt-nimble] SumeetSingh19 opened a new pull request, #1426: NimBLE/Host: Feature Multi Handle Value Notification

SumeetSingh19 opened a new pull request, #1426:
URL: https://github.com/apache/mynewt-nimble/pull/1426

   Added new feature to send and receive multi handle value notifications.
   Spec: ATT_MULTIPLE_HANDLE_VALUE_NTF (Vol 3, Part F, 3.4.7.4)


-- 
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] apache-mynewt-bot commented on pull request #1426: NimBLE/Host: Feature Multi Handle Value Notification

Posted by GitBox <gi...@apache.org>.
apache-mynewt-bot commented on PR #1426:
URL: https://github.com/apache/mynewt-nimble/pull/1426#issuecomment-1397996704

   
   <!-- style-bot -->
   
   ## Style check summary
   
   #### No suggestions at this time!
   


-- 
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


Re: [PR] NimBLE/Host: Feature Multi Handle Value Notification [mynewt-nimble]

Posted by "SumeetSingh19 (via GitHub)" <gi...@apache.org>.
SumeetSingh19 commented on code in PR #1426:
URL: https://github.com/apache/mynewt-nimble/pull/1426#discussion_r1414940171


##########
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);
+        }
+    }

Review Comment:
   Spec says we cannot truncate multi-notification, and if it is greater than mtu, it needs to be split into smaller multi-notifications.
   The second loop sends a multi-notification in each iteration that is less than the mtu.
   If the multi-notification contains a notification that itself is too large for the mtu, it cannot be split and we cannot send the entire pdu and the operation needs to be aborted.
   this "too-large" notification can be anywhere inside the multi-notification. Hence, we cannot risk splitting and sending a few multi-notifications only to find that the next one has a "too-large" notification and the operation needs to be aborted, cause at this point the client has received the notification that have been sent.
   That is why the first loop is needed to check if there isn't any "too-large" single notifications.
   
   I agree this is a very corner case and the loops look redundant, I will see what I can do about the two loops.
   
   
   
   



-- 
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] KKopyscinski commented on pull request #1426: NimBLE/Host: Feature Multi Handle Value Notification

Posted by "KKopyscinski (via GitHub)" <gi...@apache.org>.
KKopyscinski commented on PR #1426:
URL: https://github.com/apache/mynewt-nimble/pull/1426#issuecomment-1665056816

   @SumeetSingh19 These features are currently worked on in https://github.com/apache/mynewt-nimble/pull/1549, however, merging feature of sending multiple handle notifications would be helpful. I added some comments to this feature. Could you please extract only this one and submit? I think it can be done either here or in separate PR
   FYI @sjanc @rymanluk 


-- 
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 a diff in pull request #1426: NimBLE/Host: Feature Multi Handle Value Notification

Posted by "sjanc (via GitHub)" <gi...@apache.org>.
sjanc commented on code in PR #1426:
URL: https://github.com/apache/mynewt-nimble/pull/1426#discussion_r1095553574


##########
nimble/include/nimble/nimble_opt_auto.h:
##########
@@ -105,6 +105,10 @@ extern "C" {
 #define NIMBLE_BLE_ATT_CLT_INDICATE             \
     (MYNEWT_VAL(BLE_GATT_INDICATE))
 
+#undef NIMBLE_BLE_ATT_CLT_MULTI_NOTIFY
+#define NIMBLE_BLE_ATT_CLT_MULTI_NOTIFY         \
+    (MYNEWT_VAL(BLE_GATT_MULTI_NOTIFY))

Review Comment:
   MYNEWT_VAL(BLE_GATT_MULTI_NOTIFY) is never defined, is syscfg.yml change missing?



##########
nimble/host/include/host/ble_gatt.h:
##########
@@ -473,6 +473,23 @@ int ble_gattc_write_reliable(uint16_t conn_handle,
 int ble_gatts_notify_custom(uint16_t conn_handle, uint16_t att_handle,
                             struct os_mbuf *om);
 
+/**
+ * Sends multiple characteristic notifications on the specified
+ * attribute handles. This function consumes the mbuf of the
+ * notification value after sending notification.
+ *
+ * @param conn_handle       The connection over which to execute the
+ *                              procedure.
+ * @param att_handles       The list of attribute handles to which
+ *                              notifications have to be sent.
+ * @param notif_values      The list of notification value mbufs.
+ * @param num_handles        The number of handles to notify.
+ *
+ * @return                  0 on success; nonzero on failure.
+ */
+int ble_gatts_multi_notify_custom(uint16_t conn_handle, uint16_t * att_handles,

Review Comment:
   So i'd prefer if att_handle and notif_value be combined  eg.
   
   struct ble_gatt_notif {
      uint16_t handle;
     struct os_mbuf * value;
   }
   
   int ble_gatts_multi_notify_custom(uint16_t conn_handle, struct ble_gatt_notif * notif, unsigned int count);



##########
porting/examples/linux/include/syscfg/syscfg.h:
##########
@@ -531,6 +531,10 @@
 #define MYNEWT_VAL_BLE_ATT_SVR_NOTIFY (1)
 #endif
 
+#ifndef MYNEWT_VAL_BLE_ATT_SVR_MULTI_NOTIFY
+#define MYNEWT_VAL_BLE_ATT_SVR_MULTI_NOTIFY (1)

Review Comment:
   hint: ports configuration should be updated with porting/update_generated_files.sh script, not manually



##########
nimble/host/src/ble_gattc.c:
##########
@@ -4212,6 +4223,61 @@ 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, uint16_t * att_handles,
+                              struct os_mbuf ** notif_values, uint16_t num_handles)
+{
+#if !MYNEWT_VAL(BLE_GATT_MULTI_NOTIFY)
+    return BLE_HS_ENOTSUP;
+#endif
+
+    int i;
+    int rc;
+
+    STATS_INC(ble_gattc_stats, multi_notify);
+    ble_gattc_log_multi_notify(att_handles, num_handles);
+
+    for (i = 0; i < num_handles; i++) {
+        if (notif_values[i] == NULL) {
+            /* No custom attribute data; read the value from the specified
+             * attribute
+             */
+            notif_values[i] = ble_hs_mbuf_att_pkt();
+            if (notif_values[i] == NULL) {
+                rc = BLE_HS_ENOMEM;
+                goto done;
+            }
+            rc = ble_att_svr_read_handle(BLE_HS_CONN_HANDLE_NONE,
+                                         att_handles[i], 0, notif_values[i], NULL);
+            if (rc != 0) {
+                /* Fatal error; application disallowed attribute read. */
+                rc = BLE_HS_EAPP;
+                goto done;
+            }
+        }
+    }
+
+    rc = ble_att_clt_tx_multi_notify(conn_handle, att_handles,
+                                     notif_values, num_handles);
+    if (rc != 0) {

Review Comment:
   this check is not needed, done is right below



##########
nimble/host/src/ble_gattc.c:
##########
@@ -4212,6 +4223,61 @@ 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, uint16_t * att_handles,
+                              struct os_mbuf ** notif_values, uint16_t num_handles)
+{
+#if !MYNEWT_VAL(BLE_GATT_MULTI_NOTIFY)
+    return BLE_HS_ENOTSUP;
+#endif
+
+    int i;
+    int rc;
+
+    STATS_INC(ble_gattc_stats, multi_notify);
+    ble_gattc_log_multi_notify(att_handles, num_handles);
+
+    for (i = 0; i < num_handles; i++) {
+        if (notif_values[i] == NULL) {
+            /* No custom attribute data; read the value from the specified

Review Comment:
   this behavior should be documented (as there is on _custom variant for this procedure)



##########
nimble/host/src/ble_att_clt.c:
##########
@@ -907,6 +907,59 @@ ble_att_clt_tx_notify(uint16_t conn_handle, uint16_t handle,
     return rc;
 }
 
+/*****************************************************************************
+* $multi handle value notification                                           *
+*****************************************************************************/
+
+int
+ble_att_clt_tx_multi_notify(uint16_t conn_handle, uint16_t * att_handles,
+                            struct os_mbuf ** notif_values, uint16_t num_handles)
+{
+#if !NIMBLE_BLE_ATT_CLT_MULTI_NOTIFY
+    return BLE_HS_ENOTSUP;
+#endif
+
+    struct os_mbuf * txom;
+    int rc;
+    int i;
+
+    if (ble_att_cmd_get(BLE_ATT_OP_MULTI_NOTIFY_REQ, 0, &txom) == NULL) {
+        rc = BLE_HS_ENOMEM;
+        goto err;
+    }
+
+    for (i = 0; i < num_handles; i++) {
+        /* Handle */
+        rc = os_mbuf_copyinto(txom, OS_MBUF_PKTLEN(txom),
+                              &att_handles[i], sizeof(att_handles[i]));
+        if (rc != 0) {
+            rc = BLE_HS_ENOMEM;
+            goto err;
+        }
+        /* Length */
+        rc = os_mbuf_copyinto(txom, OS_MBUF_PKTLEN(txom),
+                              &(OS_MBUF_PKTLEN(notif_values[i])),
+                              sizeof(OS_MBUF_PKTLEN(notif_values[i])));
+        if (rc != 0) {
+            rc = BLE_HS_ENOMEM;
+            goto err;
+        }
+        /* Value */
+        rc = os_mbuf_copyinto(txom, OS_MBUF_PKTLEN(txom),

Review Comment:
   this may not work if source is chained, maybe os_mbuf_appendfrom should be used instead?



##########
nimble/host/src/ble_att_clt.c:
##########
@@ -907,6 +907,59 @@ ble_att_clt_tx_notify(uint16_t conn_handle, uint16_t handle,
     return rc;
 }
 
+/*****************************************************************************
+* $multi handle value notification                                           *
+*****************************************************************************/
+
+int
+ble_att_clt_tx_multi_notify(uint16_t conn_handle, uint16_t * att_handles,
+                            struct os_mbuf ** notif_values, uint16_t num_handles)
+{
+#if !NIMBLE_BLE_ATT_CLT_MULTI_NOTIFY
+    return BLE_HS_ENOTSUP;
+#endif
+
+    struct os_mbuf * txom;
+    int rc;
+    int i;
+
+    if (ble_att_cmd_get(BLE_ATT_OP_MULTI_NOTIFY_REQ, 0, &txom) == NULL) {
+        rc = BLE_HS_ENOMEM;
+        goto err;
+    }
+
+    for (i = 0; i < num_handles; i++) {
+        /* Handle */
+        rc = os_mbuf_copyinto(txom, OS_MBUF_PKTLEN(txom),
+                              &att_handles[i], sizeof(att_handles[i]));
+        if (rc != 0) {
+            rc = BLE_HS_ENOMEM;
+            goto err;
+        }
+        /* Length */
+        rc = os_mbuf_copyinto(txom, OS_MBUF_PKTLEN(txom),
+                              &(OS_MBUF_PKTLEN(notif_values[i])),
+                              sizeof(OS_MBUF_PKTLEN(notif_values[i])));
+        if (rc != 0) {
+            rc = BLE_HS_ENOMEM;
+            goto err;
+        }
+        /* Value */
+        rc = os_mbuf_copyinto(txom, OS_MBUF_PKTLEN(txom),
+                              OS_MBUF_DATA(notif_values[i], void *),
+                              OS_MBUF_PKTLEN(notif_values[i]));
+        if (rc != 0) {
+            rc = BLE_HS_ENOMEM;
+            goto err;
+        }
+    }
+
+    return ble_att_tx(conn_handle, txom);

Review Comment:
   this function truncate data to ATT MTU size but according to spec "The server shall not truncate a Handle Length Value Tuple".
   
   I'd lean towards splitting such case into multiple multi-notification...   (probably in ble_gatts_multi_notify_custom)



-- 
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] apache-mynewt-bot commented on pull request #1426: NimBLE/Host: Feature Multi Handle Value Notification

Posted by GitBox <gi...@apache.org>.
apache-mynewt-bot commented on PR #1426:
URL: https://github.com/apache/mynewt-nimble/pull/1426#issuecomment-1381400815

   
   <!-- style-bot -->
   
   ## Style check summary
   
   ### Our coding style is [here!](https://github.com/apache/mynewt-core/blob/master/CODING_STANDARDS.md)
   
   
   #### nimble/host/src/ble_att_clt.c
   <details>
   
   ```diff
   @@ -908,8 +906,8 @@
    }
    
    /*****************************************************************************
   - * $multi handle value notification                                          *
   - *****************************************************************************/
   +* $multi handle value notification                                          *
   +*****************************************************************************/
    
    int
    ble_att_clt_tx_multi_notify(uint16_t conn_handle, struct ble_gatt_hv *tuples,
   @@ -919,7 +917,7 @@
        return BLE_HS_ENOTSUP;
    #endif
    
   -    struct os_mbuf* txom;
   +    struct os_mbuf * txom;
        struct ble_gatt_hv *tpl = tuples;
        int rc;
        uint16_t num = num_tuples;
   @@ -977,8 +975,8 @@
    }
    
    /*****************************************************************************
   - * $handle value indication                                                  *
   - *****************************************************************************/
   +* $handle value indication                                                  *
   +*****************************************************************************/
    
    int
    ble_att_clt_tx_indicate(uint16_t conn_handle, uint16_t handle,
   ```
   
   </details>
   
   #### nimble/host/src/ble_att_svr.c
   <details>
   
   ```diff
   @@ -2519,13 +2519,13 @@
    #if !MYNEWT_VAL(BLE_ATT_SVR_MULTI_NOTIFY)
        return BLE_HS_ENOTSUP;
    #endif
   -    
   +
        struct ble_gatt_hv tuple;
        uint16_t value_len;
        int rc;
        int offset = 0;
        int datalen = (*rxom)->om_len;
   -    
   +
        while (offset < datalen) {
            memset(&tuple, 0, sizeof tuple);
    
   ```
   
   </details>
   
   #### nimble/host/src/ble_gattc.c
   <details>
   
   ```diff
   @@ -4233,7 +4233,7 @@
    
        int rc;
        int num = num_tuples;
   -    struct ble_gatt_hv* tpl = tuples;
   +    struct ble_gatt_hv * tpl = tuples;
    
        STATS_INC(ble_gattc_stats, multi_notify);
        ble_gattc_log_multi_notify(tuples, num_tuples);
   @@ -4241,8 +4241,8 @@
        while (num) {
            if (tpl->value == NULL) {
                /* No custom attribute data; read the value from the specified
   -            * attribute
   -            */
   +             * attribute
   +             */
                tpl->value = ble_hs_mbuf_att_pkt();
                if (tpl->value == NULL) {
                    rc = BLE_HS_ENOMEM;
   @@ -4283,7 +4283,7 @@
    
        return rc;
    }
   -    
   +
    
    /**
     * Deprecated. Should not be used. Use ble_gatts_notify_custom instead.
   ```
   
   </details>


-- 
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] SumeetSingh19 commented on a diff in pull request #1426: NimBLE/Host: Feature Multi Handle Value Notification

Posted by "SumeetSingh19 (via GitHub)" <gi...@apache.org>.
SumeetSingh19 commented on code in PR #1426:
URL: https://github.com/apache/mynewt-nimble/pull/1426#discussion_r1149121770


##########
nimble/host/src/ble_gattc.c:
##########
@@ -4212,6 +4223,61 @@ 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, uint16_t * att_handles,
+                              struct os_mbuf ** notif_values, uint16_t num_handles)
+{
+#if !MYNEWT_VAL(BLE_GATT_MULTI_NOTIFY)
+    return BLE_HS_ENOTSUP;
+#endif
+
+    int i;
+    int rc;
+
+    STATS_INC(ble_gattc_stats, multi_notify);
+    ble_gattc_log_multi_notify(att_handles, num_handles);
+
+    for (i = 0; i < num_handles; i++) {
+        if (notif_values[i] == NULL) {
+            /* No custom attribute data; read the value from the specified

Review Comment:
   Non-custom variant is created.



-- 
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] apache-mynewt-bot commented on pull request #1426: NimBLE/Host: Feature Multi Handle Value Notification

Posted by GitBox <gi...@apache.org>.
apache-mynewt-bot commented on PR #1426:
URL: https://github.com/apache/mynewt-nimble/pull/1426#issuecomment-1396655797

   
   <!-- style-bot -->
   
   ## Style check summary
   
   ### Our coding style is [here!](https://github.com/apache/mynewt-core/blob/master/CODING_STANDARDS.md)
   
   
   #### nimble/host/src/ble_att_clt.c
   <details>
   
   ```diff
   @@ -908,8 +906,8 @@
    }
    
    /*****************************************************************************
   - * $multi handle value notification                                          *
   - *****************************************************************************/
   +* $multi handle value notification                                          *
   +*****************************************************************************/
    
    int
    ble_att_clt_tx_multi_notify(uint16_t conn_handle, struct ble_gatt_hv *tuples,
   @@ -977,8 +975,8 @@
    }
    
    /*****************************************************************************
   - * $handle value indication                                                  *
   - *****************************************************************************/
   +* $handle value indication                                                  *
   +*****************************************************************************/
    
    int
    ble_att_clt_tx_indicate(uint16_t conn_handle, uint16_t handle,
   ```
   
   </details>


-- 
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] SumeetSingh19 commented on a diff in pull request #1426: NimBLE/Host: Feature Multi Handle Value Notification

Posted by "SumeetSingh19 (via GitHub)" <gi...@apache.org>.
SumeetSingh19 commented on code in PR #1426:
URL: https://github.com/apache/mynewt-nimble/pull/1426#discussion_r1149006790


##########
nimble/host/src/ble_gattc.c:
##########
@@ -4212,6 +4223,61 @@ 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, uint16_t * att_handles,
+                              struct os_mbuf ** notif_values, uint16_t num_handles)
+{
+#if !MYNEWT_VAL(BLE_GATT_MULTI_NOTIFY)
+    return BLE_HS_ENOTSUP;
+#endif
+
+    int i;
+    int rc;
+
+    STATS_INC(ble_gattc_stats, multi_notify);
+    ble_gattc_log_multi_notify(att_handles, num_handles);
+
+    for (i = 0; i < num_handles; i++) {
+        if (notif_values[i] == NULL) {
+            /* No custom attribute data; read the value from the specified
+             * attribute
+             */
+            notif_values[i] = ble_hs_mbuf_att_pkt();
+            if (notif_values[i] == NULL) {
+                rc = BLE_HS_ENOMEM;
+                goto done;
+            }
+            rc = ble_att_svr_read_handle(BLE_HS_CONN_HANDLE_NONE,
+                                         att_handles[i], 0, notif_values[i], NULL);
+            if (rc != 0) {
+                /* Fatal error; application disallowed attribute read. */
+                rc = BLE_HS_EAPP;
+                goto done;
+            }
+        }
+    }
+
+    rc = ble_att_clt_tx_multi_notify(conn_handle, att_handles,
+                                     notif_values, num_handles);
+    if (rc != 0) {

Review Comment:
   Check is removed



-- 
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] KKopyscinski commented on a diff in pull request #1426: NimBLE/Host: Feature Multi Handle Value Notification

Posted by "KKopyscinski (via GitHub)" <gi...@apache.org>.
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-unsubscribe@mynewt.apache.org

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


[GitHub] [mynewt-nimble] SumeetSingh19 commented on a diff in pull request #1426: NimBLE/Host: Feature Multi Handle Value Notification

Posted by "SumeetSingh19 (via GitHub)" <gi...@apache.org>.
SumeetSingh19 commented on code in PR #1426:
URL: https://github.com/apache/mynewt-nimble/pull/1426#discussion_r1149125076


##########
nimble/host/src/ble_att_clt.c:
##########
@@ -907,6 +907,59 @@ ble_att_clt_tx_notify(uint16_t conn_handle, uint16_t handle,
     return rc;
 }
 
+/*****************************************************************************
+* $multi handle value notification                                           *
+*****************************************************************************/
+
+int
+ble_att_clt_tx_multi_notify(uint16_t conn_handle, uint16_t * att_handles,
+                            struct os_mbuf ** notif_values, uint16_t num_handles)
+{
+#if !NIMBLE_BLE_ATT_CLT_MULTI_NOTIFY
+    return BLE_HS_ENOTSUP;
+#endif
+
+    struct os_mbuf * txom;
+    int rc;
+    int i;
+
+    if (ble_att_cmd_get(BLE_ATT_OP_MULTI_NOTIFY_REQ, 0, &txom) == NULL) {
+        rc = BLE_HS_ENOMEM;
+        goto err;
+    }
+
+    for (i = 0; i < num_handles; i++) {
+        /* Handle */
+        rc = os_mbuf_copyinto(txom, OS_MBUF_PKTLEN(txom),
+                              &att_handles[i], sizeof(att_handles[i]));
+        if (rc != 0) {
+            rc = BLE_HS_ENOMEM;
+            goto err;
+        }
+        /* Length */
+        rc = os_mbuf_copyinto(txom, OS_MBUF_PKTLEN(txom),
+                              &(OS_MBUF_PKTLEN(notif_values[i])),
+                              sizeof(OS_MBUF_PKTLEN(notif_values[i])));
+        if (rc != 0) {
+            rc = BLE_HS_ENOMEM;
+            goto err;
+        }
+        /* Value */
+        rc = os_mbuf_copyinto(txom, OS_MBUF_PKTLEN(txom),
+                              OS_MBUF_DATA(notif_values[i], void *),
+                              OS_MBUF_PKTLEN(notif_values[i]));
+        if (rc != 0) {
+            rc = BLE_HS_ENOMEM;
+            goto err;
+        }
+    }
+
+    return ble_att_tx(conn_handle, txom);

Review Comment:
   Added logic to make sure that the notification isn't truncated.
   
   If the multi notification is too large, it will be split into multiple smaller multi notifications.
   If a single notification is larger than MTU, no notifications will be sent by the server.



-- 
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] apache-mynewt-bot commented on pull request #1426: NimBLE/Host: Feature Multi Handle Value Notification

Posted by GitBox <gi...@apache.org>.
apache-mynewt-bot commented on PR #1426:
URL: https://github.com/apache/mynewt-nimble/pull/1426#issuecomment-1396809082

   
   <!-- style-bot -->
   
   ## Style check summary
   
   #### No suggestions at this time!
   


-- 
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] KKopyscinski commented on a diff in pull request #1426: NimBLE/Host: Feature Multi Handle Value Notification

Posted by "KKopyscinski (via GitHub)" <gi...@apache.org>.
KKopyscinski commented on code in PR #1426:
URL: https://github.com/apache/mynewt-nimble/pull/1426#discussion_r1283117573


##########
nimble/host/include/host/ble_gatt.h:
##########
@@ -473,6 +479,22 @@ int ble_gattc_write_reliable(uint16_t conn_handle,
 int ble_gatts_notify_custom(uint16_t conn_handle, uint16_t att_handle,
                             struct os_mbuf *om);
 
+/**
+ * Sends multiple characteristic notifications on the specified
+ * attribute handles. This function consumes the mbuf of the
+ * notification value after sending notification.
+ *
+ * @param conn_handle       The connection over which to execute the
+ *                              procedure.
+ * @param tuples            The list of attribute handles and notification
+ *                              value tuples.
+ * @param num_tuples        The number of notifications to send.
+ *
+ * @return                  0 on success; nonzero on failure.
+ */
+int ble_gatts_multi_notify_custom(uint16_t conn_handle,
+                                  struct ble_gatt_hv * tuples, uint16_t num_tuples);

Review Comment:
   adjust name after change and codestyle
   ```suggestion
                                     struct ble_gatt_mult_notif_entry *tuples, uint16_t num_tuples);
   ```



##########
nimble/host/include/host/ble_gatt.h:
##########
@@ -79,6 +79,12 @@ struct ble_hs_cfg;
 #define BLE_GATT_SVC_TYPE_PRIMARY                       1
 #define BLE_GATT_SVC_TYPE_SECONDARY                     2
 
+/*** @server. */
+struct ble_gatt_hv {
+    uint16_t handle;
+    struct os_mbuf* value;

Review Comment:
   codestyle
   ```suggestion
       struct os_mbuf *value;
   ```



##########
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;

Review Comment:
   ```suggestion
   ```
   not needed



##########
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),

Review Comment:
   ditto (`os_mbuf_append`)



##########
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,

Review Comment:
   offset is 0, so `os_mbuf_append` can be used afaik



##########
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) {

Review Comment:
   This is neither fatal error nor only caused by missing permissions (permissions are not checked for self-reads) Maybe just log error
   ```suggestion
                   BLE_HS_LOG(ERROR, "Attribute read failed (err=0x%02x), rc");
   ```
   and return rc as is: for example `handle` was invalid, and `BLE_HS_EAPP` doesn't make sense then



##########
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);
+
+done:
+    if (rc != 0) {
+        STATS_INC(ble_gattc_stats, multi_notify_fail);
+    }
+
+    /* Tell the application that multiple notification transmissions were attempted. */
+    for (i = 0; i < num_tuples; i++) {
+        ble_gap_notify_tx_event(rc, conn_handle, tuples[i].handle, 0);
+        os_mbuf_free_chain(tuples[i].value);
+    }

Review Comment:
   ```suggestion
       int j; //this on top
       /* Tell the application that multiple notification transmissions were attempted. */
       for (j = 0; j < i; j++) {
           ble_gap_notify_tx_event(rc, conn_handle, tuples[j].handle, 0);
           os_mbuf_free_chain(tuples[j].value);
       }
   ```
   `i` now holds how many tuples were actually send (it may be leftover).



##########
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);
+        }
+    }

Review Comment:
   ```suggestion
   
   ```
   I think these two loops can be merged (or this one removed and second modified)



##########
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),

Review Comment:
   you are copying data to buffer at same offset every time. This will just overwrite previous data. I think you need to use `os_mbuf_append()`



##########
nimble/host/include/host/ble_gatt.h:
##########
@@ -79,6 +79,12 @@ struct ble_hs_cfg;
 #define BLE_GATT_SVC_TYPE_PRIMARY                       1
 #define BLE_GATT_SVC_TYPE_SECONDARY                     2
 
+/*** @server. */
+struct ble_gatt_hv {

Review Comment:
   `hv` isn't very clear, maybe
   ```suggestion
   struct ble_gatt_mult_notif_entry {
   ```
   or `notif_value` as @sjanc suggested



##########
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);
                   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-unsubscribe@mynewt.apache.org

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


Re: [PR] NimBLE/Host: Feature Multi Handle Value Notification [mynewt-nimble]

Posted by "SumeetSingh19 (via GitHub)" <gi...@apache.org>.
SumeetSingh19 commented on code in PR #1426:
URL: https://github.com/apache/mynewt-nimble/pull/1426#discussion_r1414945034


##########
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);
+
+done:
+    if (rc != 0) {
+        STATS_INC(ble_gattc_stats, multi_notify_fail);
+    }
+
+    /* Tell the application that multiple notification transmissions were attempted. */
+    for (i = 0; i < num_tuples; i++) {
+        ble_gap_notify_tx_event(rc, conn_handle, tuples[i].handle, 0);
+        os_mbuf_free_chain(tuples[i].value);
+    }

Review Comment:
   This is fine because we are assigning 0 to i again



-- 
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] apache-mynewt-bot commented on pull request #1426: NimBLE/Host: Feature Multi Handle Value Notification

Posted by GitBox <gi...@apache.org>.
apache-mynewt-bot commented on PR #1426:
URL: https://github.com/apache/mynewt-nimble/pull/1426#issuecomment-1396446087

   
   <!-- style-bot -->
   
   ## Style check summary
   
   ### Our coding style is [here!](https://github.com/apache/mynewt-core/blob/master/CODING_STANDARDS.md)
   
   
   #### nimble/host/src/ble_att_clt.c
   <details>
   
   ```diff
   @@ -908,8 +906,8 @@
    }
    
    /****************************************************************************
   -* $multi handle value notification                                          *
   -*****************************************************************************/
   + * $multi handle value notification                                          *
   + *****************************************************************************/
    
    int
    ble_att_clt_tx_multi_notify(uint16_t conn_handle, struct ble_gatt_hv *tuples,
   @@ -977,8 +975,8 @@
    }
    
    /****************************************************************************
   -* $handle value indication                                                  *
   -*****************************************************************************/
   + * $handle value indication                                                  *
   + *****************************************************************************/
    
    int
    ble_att_clt_tx_indicate(uint16_t conn_handle, uint16_t handle,
   ```
   
   </details>


-- 
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] SumeetSingh19 commented on a diff in pull request #1426: NimBLE/Host: Feature Multi Handle Value Notification

Posted by "SumeetSingh19 (via GitHub)" <gi...@apache.org>.
SumeetSingh19 commented on code in PR #1426:
URL: https://github.com/apache/mynewt-nimble/pull/1426#discussion_r1149000084


##########
nimble/host/include/host/ble_gatt.h:
##########
@@ -473,6 +473,23 @@ int ble_gattc_write_reliable(uint16_t conn_handle,
 int ble_gatts_notify_custom(uint16_t conn_handle, uint16_t att_handle,
                             struct os_mbuf *om);
 
+/**
+ * Sends multiple characteristic notifications on the specified
+ * attribute handles. This function consumes the mbuf of the
+ * notification value after sending notification.
+ *
+ * @param conn_handle       The connection over which to execute the
+ *                              procedure.
+ * @param att_handles       The list of attribute handles to which
+ *                              notifications have to be sent.
+ * @param notif_values      The list of notification value mbufs.
+ * @param num_handles        The number of handles to notify.
+ *
+ * @return                  0 on success; nonzero on failure.
+ */
+int ble_gatts_multi_notify_custom(uint16_t conn_handle, uint16_t * att_handles,

Review Comment:
   A structure to implement this has been added.



-- 
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] SumeetSingh19 commented on a diff in pull request #1426: NimBLE/Host: Feature Multi Handle Value Notification

Posted by "SumeetSingh19 (via GitHub)" <gi...@apache.org>.
SumeetSingh19 commented on code in PR #1426:
URL: https://github.com/apache/mynewt-nimble/pull/1426#discussion_r1149000536


##########
nimble/include/nimble/nimble_opt_auto.h:
##########
@@ -105,6 +105,10 @@ extern "C" {
 #define NIMBLE_BLE_ATT_CLT_INDICATE             \
     (MYNEWT_VAL(BLE_GATT_INDICATE))
 
+#undef NIMBLE_BLE_ATT_CLT_MULTI_NOTIFY
+#define NIMBLE_BLE_ATT_CLT_MULTI_NOTIFY         \
+    (MYNEWT_VAL(BLE_GATT_MULTI_NOTIFY))

Review Comment:
   syscfg,yml change is added



-- 
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


Re: [PR] NimBLE/Host: Feature Multi Handle Value Notification [mynewt-nimble]

Posted by "SumeetSingh19 (via GitHub)" <gi...@apache.org>.
SumeetSingh19 commented on code in PR #1426:
URL: https://github.com/apache/mynewt-nimble/pull/1426#discussion_r1414944100


##########
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,

Review Comment:
   `os_mbuf_append` needs a flat buffer, the source here is another `mbuf`



-- 
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] SumeetSingh19 commented on pull request #1426: NimBLE/Host: Feature Multi Handle Value Notification

Posted by "SumeetSingh19 (via GitHub)" <gi...@apache.org>.
SumeetSingh19 commented on PR #1426:
URL: https://github.com/apache/mynewt-nimble/pull/1426#issuecomment-1447959397

   #AutoPTS run mynewt GATT/SR/GAN/BV-02-C


-- 
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 a diff in pull request #1426: NimBLE/Host: Feature Multi Handle Value Notification

Posted by "sjanc (via GitHub)" <gi...@apache.org>.
sjanc commented on code in PR #1426:
URL: https://github.com/apache/mynewt-nimble/pull/1426#discussion_r1112782657


##########
nimble/host/include/host/ble_gatt.h:
##########
@@ -473,6 +473,23 @@ int ble_gattc_write_reliable(uint16_t conn_handle,
 int ble_gatts_notify_custom(uint16_t conn_handle, uint16_t att_handle,
                             struct os_mbuf *om);
 
+/**
+ * Sends multiple characteristic notifications on the specified
+ * attribute handles. This function consumes the mbuf of the
+ * notification value after sending notification.
+ *
+ * @param conn_handle       The connection over which to execute the
+ *                              procedure.
+ * @param att_handles       The list of attribute handles to which
+ *                              notifications have to be sent.
+ * @param notif_values      The list of notification value mbufs.
+ * @param num_handles        The number of handles to notify.
+ *
+ * @return                  0 on success; nonzero on failure.
+ */
+int ble_gatts_multi_notify_custom(uint16_t conn_handle, uint16_t * att_handles,

Review Comment:
   hmm maybe have a "constructor" function in att that would allow for multiple calls to create ATT multinotif in loop?
   That way you don't need to include ble_gatt.h (which is user api)



-- 
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] apache-mynewt-bot commented on pull request #1426: NimBLE/Host: Feature Multi Handle Value Notification

Posted by GitBox <gi...@apache.org>.
apache-mynewt-bot commented on PR #1426:
URL: https://github.com/apache/mynewt-nimble/pull/1426#issuecomment-1397965509

   
   <!-- style-bot -->
   
   ## Style check summary
   
   ### Our coding style is [here!](https://github.com/apache/mynewt-core/blob/master/CODING_STANDARDS.md)
   
   
   #### nimble/host/src/ble_att.c
   <details>
   
   ```diff
   @@ -78,61 +78,61 @@
    
    STATS_SECT_DECL(ble_att_stats) ble_att_stats;
    STATS_NAME_START(ble_att_stats)
   -    STATS_NAME(ble_att_stats, error_rsp_rx)
   -    STATS_NAME(ble_att_stats, error_rsp_tx)
   -    STATS_NAME(ble_att_stats, mtu_req_rx)
   -    STATS_NAME(ble_att_stats, mtu_req_tx)
   -    STATS_NAME(ble_att_stats, mtu_rsp_rx)
   -    STATS_NAME(ble_att_stats, mtu_rsp_tx)
   -    STATS_NAME(ble_att_stats, find_info_req_rx)
   -    STATS_NAME(ble_att_stats, find_info_req_tx)
   -    STATS_NAME(ble_att_stats, find_info_rsp_rx)
   -    STATS_NAME(ble_att_stats, find_info_rsp_tx)
   -    STATS_NAME(ble_att_stats, find_type_value_req_rx)
   -    STATS_NAME(ble_att_stats, find_type_value_req_tx)
   -    STATS_NAME(ble_att_stats, find_type_value_rsp_rx)
   -    STATS_NAME(ble_att_stats, find_type_value_rsp_tx)
   -    STATS_NAME(ble_att_stats, read_type_req_rx)
   -    STATS_NAME(ble_att_stats, read_type_req_tx)
   -    STATS_NAME(ble_att_stats, read_type_rsp_rx)
   -    STATS_NAME(ble_att_stats, read_type_rsp_tx)
   -    STATS_NAME(ble_att_stats, read_req_rx)
   -    STATS_NAME(ble_att_stats, read_req_tx)
   -    STATS_NAME(ble_att_stats, read_rsp_rx)
   -    STATS_NAME(ble_att_stats, read_rsp_tx)
   -    STATS_NAME(ble_att_stats, read_blob_req_rx)
   -    STATS_NAME(ble_att_stats, read_blob_req_tx)
   -    STATS_NAME(ble_att_stats, read_blob_rsp_rx)
   -    STATS_NAME(ble_att_stats, read_blob_rsp_tx)
   -    STATS_NAME(ble_att_stats, read_mult_req_rx)
   -    STATS_NAME(ble_att_stats, read_mult_req_tx)
   -    STATS_NAME(ble_att_stats, read_mult_rsp_rx)
   -    STATS_NAME(ble_att_stats, read_mult_rsp_tx)
   -    STATS_NAME(ble_att_stats, read_group_type_req_rx)
   -    STATS_NAME(ble_att_stats, read_group_type_req_tx)
   -    STATS_NAME(ble_att_stats, read_group_type_rsp_rx)
   -    STATS_NAME(ble_att_stats, read_group_type_rsp_tx)
   -    STATS_NAME(ble_att_stats, write_req_rx)
   -    STATS_NAME(ble_att_stats, write_req_tx)
   -    STATS_NAME(ble_att_stats, write_rsp_rx)
   -    STATS_NAME(ble_att_stats, write_rsp_tx)
   -    STATS_NAME(ble_att_stats, prep_write_req_rx)
   -    STATS_NAME(ble_att_stats, prep_write_req_tx)
   -    STATS_NAME(ble_att_stats, prep_write_rsp_rx)
   -    STATS_NAME(ble_att_stats, prep_write_rsp_tx)
   -    STATS_NAME(ble_att_stats, exec_write_req_rx)
   -    STATS_NAME(ble_att_stats, exec_write_req_tx)
   -    STATS_NAME(ble_att_stats, exec_write_rsp_rx)
   -    STATS_NAME(ble_att_stats, exec_write_rsp_tx)
   -    STATS_NAME(ble_att_stats, notify_req_rx)
   -    STATS_NAME(ble_att_stats, notify_req_tx)
   -    STATS_NAME(ble_att_stats, indicate_req_rx)
   -    STATS_NAME(ble_att_stats, indicate_req_tx)
   -    STATS_NAME(ble_att_stats, indicate_rsp_rx)
   -    STATS_NAME(ble_att_stats, indicate_rsp_tx)
   -    STATS_NAME(ble_att_stats, multi_notify_req_rx)
   -    STATS_NAME(ble_att_stats, write_cmd_rx)
   -    STATS_NAME(ble_att_stats, write_cmd_tx)
   +STATS_NAME(ble_att_stats, error_rsp_rx)
   +STATS_NAME(ble_att_stats, error_rsp_tx)
   +STATS_NAME(ble_att_stats, mtu_req_rx)
   +STATS_NAME(ble_att_stats, mtu_req_tx)
   +STATS_NAME(ble_att_stats, mtu_rsp_rx)
   +STATS_NAME(ble_att_stats, mtu_rsp_tx)
   +STATS_NAME(ble_att_stats, find_info_req_rx)
   +STATS_NAME(ble_att_stats, find_info_req_tx)
   +STATS_NAME(ble_att_stats, find_info_rsp_rx)
   +STATS_NAME(ble_att_stats, find_info_rsp_tx)
   +STATS_NAME(ble_att_stats, find_type_value_req_rx)
   +STATS_NAME(ble_att_stats, find_type_value_req_tx)
   +STATS_NAME(ble_att_stats, find_type_value_rsp_rx)
   +STATS_NAME(ble_att_stats, find_type_value_rsp_tx)
   +STATS_NAME(ble_att_stats, read_type_req_rx)
   +STATS_NAME(ble_att_stats, read_type_req_tx)
   +STATS_NAME(ble_att_stats, read_type_rsp_rx)
   +STATS_NAME(ble_att_stats, read_type_rsp_tx)
   +STATS_NAME(ble_att_stats, read_req_rx)
   +STATS_NAME(ble_att_stats, read_req_tx)
   +STATS_NAME(ble_att_stats, read_rsp_rx)
   +STATS_NAME(ble_att_stats, read_rsp_tx)
   +STATS_NAME(ble_att_stats, read_blob_req_rx)
   +STATS_NAME(ble_att_stats, read_blob_req_tx)
   +STATS_NAME(ble_att_stats, read_blob_rsp_rx)
   +STATS_NAME(ble_att_stats, read_blob_rsp_tx)
   +STATS_NAME(ble_att_stats, read_mult_req_rx)
   +STATS_NAME(ble_att_stats, read_mult_req_tx)
   +STATS_NAME(ble_att_stats, read_mult_rsp_rx)
   +STATS_NAME(ble_att_stats, read_mult_rsp_tx)
   +STATS_NAME(ble_att_stats, read_group_type_req_rx)
   +STATS_NAME(ble_att_stats, read_group_type_req_tx)
   +STATS_NAME(ble_att_stats, read_group_type_rsp_rx)
   +STATS_NAME(ble_att_stats, read_group_type_rsp_tx)
   +STATS_NAME(ble_att_stats, write_req_rx)
   +STATS_NAME(ble_att_stats, write_req_tx)
   +STATS_NAME(ble_att_stats, write_rsp_rx)
   +STATS_NAME(ble_att_stats, write_rsp_tx)
   +STATS_NAME(ble_att_stats, prep_write_req_rx)
   +STATS_NAME(ble_att_stats, prep_write_req_tx)
   +STATS_NAME(ble_att_stats, prep_write_rsp_rx)
   +STATS_NAME(ble_att_stats, prep_write_rsp_tx)
   +STATS_NAME(ble_att_stats, exec_write_req_rx)
   +STATS_NAME(ble_att_stats, exec_write_req_tx)
   +STATS_NAME(ble_att_stats, exec_write_rsp_rx)
   +STATS_NAME(ble_att_stats, exec_write_rsp_tx)
   +STATS_NAME(ble_att_stats, notify_req_rx)
   +STATS_NAME(ble_att_stats, notify_req_tx)
   +STATS_NAME(ble_att_stats, indicate_req_rx)
   +STATS_NAME(ble_att_stats, indicate_req_tx)
   +STATS_NAME(ble_att_stats, indicate_rsp_rx)
   +STATS_NAME(ble_att_stats, indicate_rsp_tx)
   +STATS_NAME(ble_att_stats, multi_notify_req_rx)
   +STATS_NAME(ble_att_stats, write_cmd_rx)
   +STATS_NAME(ble_att_stats, write_cmd_tx)
    STATS_NAME_END(ble_att_stats)
    
    static const struct ble_att_rx_dispatch_entry *
   ```
   
   </details>
   
   #### nimble/host/src/ble_att_priv.h
   <details>
   
   ```diff
   @@ -50,61 +50,61 @@
    struct ble_att_indicate_req;
    
    STATS_SECT_START(ble_att_stats)
   -    STATS_SECT_ENTRY(error_rsp_rx)
   -    STATS_SECT_ENTRY(error_rsp_tx)
   -    STATS_SECT_ENTRY(mtu_req_rx)
   -    STATS_SECT_ENTRY(mtu_req_tx)
   -    STATS_SECT_ENTRY(mtu_rsp_rx)
   -    STATS_SECT_ENTRY(mtu_rsp_tx)
   -    STATS_SECT_ENTRY(find_info_req_rx)
   -    STATS_SECT_ENTRY(find_info_req_tx)
   -    STATS_SECT_ENTRY(find_info_rsp_rx)
   -    STATS_SECT_ENTRY(find_info_rsp_tx)
   -    STATS_SECT_ENTRY(find_type_value_req_rx)
   -    STATS_SECT_ENTRY(find_type_value_req_tx)
   -    STATS_SECT_ENTRY(find_type_value_rsp_rx)
   -    STATS_SECT_ENTRY(find_type_value_rsp_tx)
   -    STATS_SECT_ENTRY(read_type_req_rx)
   -    STATS_SECT_ENTRY(read_type_req_tx)
   -    STATS_SECT_ENTRY(read_type_rsp_rx)
   -    STATS_SECT_ENTRY(read_type_rsp_tx)
   -    STATS_SECT_ENTRY(read_req_rx)
   -    STATS_SECT_ENTRY(read_req_tx)
   -    STATS_SECT_ENTRY(read_rsp_rx)
   -    STATS_SECT_ENTRY(read_rsp_tx)
   -    STATS_SECT_ENTRY(read_blob_req_rx)
   -    STATS_SECT_ENTRY(read_blob_req_tx)
   -    STATS_SECT_ENTRY(read_blob_rsp_rx)
   -    STATS_SECT_ENTRY(read_blob_rsp_tx)
   -    STATS_SECT_ENTRY(read_mult_req_rx)
   -    STATS_SECT_ENTRY(read_mult_req_tx)
   -    STATS_SECT_ENTRY(read_mult_rsp_rx)
   -    STATS_SECT_ENTRY(read_mult_rsp_tx)
   -    STATS_SECT_ENTRY(read_group_type_req_rx)
   -    STATS_SECT_ENTRY(read_group_type_req_tx)
   -    STATS_SECT_ENTRY(read_group_type_rsp_rx)
   -    STATS_SECT_ENTRY(read_group_type_rsp_tx)
   -    STATS_SECT_ENTRY(write_req_rx)
   -    STATS_SECT_ENTRY(write_req_tx)
   -    STATS_SECT_ENTRY(write_rsp_rx)
   -    STATS_SECT_ENTRY(write_rsp_tx)
   -    STATS_SECT_ENTRY(prep_write_req_rx)
   -    STATS_SECT_ENTRY(prep_write_req_tx)
   -    STATS_SECT_ENTRY(prep_write_rsp_rx)
   -    STATS_SECT_ENTRY(prep_write_rsp_tx)
   -    STATS_SECT_ENTRY(exec_write_req_rx)
   -    STATS_SECT_ENTRY(exec_write_req_tx)
   -    STATS_SECT_ENTRY(exec_write_rsp_rx)
   -    STATS_SECT_ENTRY(exec_write_rsp_tx)
   -    STATS_SECT_ENTRY(notify_req_rx)
   -    STATS_SECT_ENTRY(notify_req_tx)
   -    STATS_SECT_ENTRY(indicate_req_rx)
   -    STATS_SECT_ENTRY(indicate_req_tx)
   -    STATS_SECT_ENTRY(indicate_rsp_rx)
   -    STATS_SECT_ENTRY(indicate_rsp_tx)
   -    STATS_SECT_ENTRY(multi_notify_req_rx)
   -    STATS_SECT_ENTRY(write_cmd_rx)
   -    STATS_SECT_ENTRY(write_cmd_tx)
   +STATS_SECT_ENTRY(error_rsp_rx)
   +STATS_SECT_ENTRY(error_rsp_tx)
   +STATS_SECT_ENTRY(mtu_req_rx)
   +STATS_SECT_ENTRY(mtu_req_tx)
   +STATS_SECT_ENTRY(mtu_rsp_rx)
   +STATS_SECT_ENTRY(mtu_rsp_tx)
   +STATS_SECT_ENTRY(find_info_req_rx)
   +STATS_SECT_ENTRY(find_info_req_tx)
   +STATS_SECT_ENTRY(find_info_rsp_rx)
   +STATS_SECT_ENTRY(find_info_rsp_tx)
   +STATS_SECT_ENTRY(find_type_value_req_rx)
   +STATS_SECT_ENTRY(find_type_value_req_tx)
   +STATS_SECT_ENTRY(find_type_value_rsp_rx)
   +STATS_SECT_ENTRY(find_type_value_rsp_tx)
   +STATS_SECT_ENTRY(read_type_req_rx)
   +STATS_SECT_ENTRY(read_type_req_tx)
   +STATS_SECT_ENTRY(read_type_rsp_rx)
   +STATS_SECT_ENTRY(read_type_rsp_tx)
   +STATS_SECT_ENTRY(read_req_rx)
   +STATS_SECT_ENTRY(read_req_tx)
   +STATS_SECT_ENTRY(read_rsp_rx)
   +STATS_SECT_ENTRY(read_rsp_tx)
   +STATS_SECT_ENTRY(read_blob_req_rx)
   +STATS_SECT_ENTRY(read_blob_req_tx)
   +STATS_SECT_ENTRY(read_blob_rsp_rx)
   +STATS_SECT_ENTRY(read_blob_rsp_tx)
   +STATS_SECT_ENTRY(read_mult_req_rx)
   +STATS_SECT_ENTRY(read_mult_req_tx)
   +STATS_SECT_ENTRY(read_mult_rsp_rx)
   +STATS_SECT_ENTRY(read_mult_rsp_tx)
   +STATS_SECT_ENTRY(read_group_type_req_rx)
   +STATS_SECT_ENTRY(read_group_type_req_tx)
   +STATS_SECT_ENTRY(read_group_type_rsp_rx)
   +STATS_SECT_ENTRY(read_group_type_rsp_tx)
   +STATS_SECT_ENTRY(write_req_rx)
   +STATS_SECT_ENTRY(write_req_tx)
   +STATS_SECT_ENTRY(write_rsp_rx)
   +STATS_SECT_ENTRY(write_rsp_tx)
   +STATS_SECT_ENTRY(prep_write_req_rx)
   +STATS_SECT_ENTRY(prep_write_req_tx)
   +STATS_SECT_ENTRY(prep_write_rsp_rx)
   +STATS_SECT_ENTRY(prep_write_rsp_tx)
   +STATS_SECT_ENTRY(exec_write_req_rx)
   +STATS_SECT_ENTRY(exec_write_req_tx)
   +STATS_SECT_ENTRY(exec_write_rsp_rx)
   +STATS_SECT_ENTRY(exec_write_rsp_tx)
   +STATS_SECT_ENTRY(notify_req_rx)
   +STATS_SECT_ENTRY(notify_req_tx)
   +STATS_SECT_ENTRY(indicate_req_rx)
   +STATS_SECT_ENTRY(indicate_req_tx)
   +STATS_SECT_ENTRY(indicate_rsp_rx)
   +STATS_SECT_ENTRY(indicate_rsp_tx)
   +STATS_SECT_ENTRY(multi_notify_req_rx)
   +STATS_SECT_ENTRY(write_cmd_rx)
   +STATS_SECT_ENTRY(write_cmd_tx)
    STATS_SECT_END
    extern STATS_SECT_DECL(ble_att_stats) ble_att_stats;
    
   ```
   
   </details>


-- 
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] apache-mynewt-bot commented on pull request #1426: NimBLE/Host: Feature Multi Handle Value Notification

Posted by GitBox <gi...@apache.org>.
apache-mynewt-bot commented on PR #1426:
URL: https://github.com/apache/mynewt-nimble/pull/1426#issuecomment-1397991343

   
   <!-- style-bot -->
   
   ## Style check summary
   
   ### Our coding style is [here!](https://github.com/apache/mynewt-core/blob/master/CODING_STANDARDS.md)
   
   
   #### nimble/host/src/ble_gatt_priv.h
   <details>
   
   ```diff
   @@ -34,57 +34,57 @@
    struct ble_att_prep_write_cmd;
    
    STATS_SECT_START(ble_gattc_stats)
   -    STATS_SECT_ENTRY(mtu)
   -    STATS_SECT_ENTRY(mtu_fail)
   -    STATS_SECT_ENTRY(disc_all_svcs)
   -    STATS_SECT_ENTRY(disc_all_svcs_fail)
   -    STATS_SECT_ENTRY(disc_svc_uuid)
   -    STATS_SECT_ENTRY(disc_svc_uuid_fail)
   -    STATS_SECT_ENTRY(find_inc_svcs)
   -    STATS_SECT_ENTRY(find_inc_svcs_fail)
   -    STATS_SECT_ENTRY(disc_all_chrs)
   -    STATS_SECT_ENTRY(disc_all_chrs_fail)
   -    STATS_SECT_ENTRY(disc_chrs_uuid)
   -    STATS_SECT_ENTRY(disc_chrs_uuid_fail)
   -    STATS_SECT_ENTRY(disc_all_dscs)
   -    STATS_SECT_ENTRY(disc_all_dscs_fail)
   -    STATS_SECT_ENTRY(read)
   -    STATS_SECT_ENTRY(read_fail)
   -    STATS_SECT_ENTRY(read_uuid)
   -    STATS_SECT_ENTRY(read_uuid_fail)
   -    STATS_SECT_ENTRY(read_long)
   -    STATS_SECT_ENTRY(read_long_fail)
   -    STATS_SECT_ENTRY(read_mult)
   -    STATS_SECT_ENTRY(read_mult_fail)
   -    STATS_SECT_ENTRY(write_no_rsp)
   -    STATS_SECT_ENTRY(write_no_rsp_fail)
   -    STATS_SECT_ENTRY(write)
   -    STATS_SECT_ENTRY(write_fail)
   -    STATS_SECT_ENTRY(write_long)
   -    STATS_SECT_ENTRY(write_long_fail)
   -    STATS_SECT_ENTRY(write_reliable)
   -    STATS_SECT_ENTRY(write_reliable_fail)
   -    STATS_SECT_ENTRY(notify)
   -    STATS_SECT_ENTRY(notify_fail)
   -    STATS_SECT_ENTRY(multi_notify)
   -    STATS_SECT_ENTRY(multi_notify_fail)
   -    STATS_SECT_ENTRY(indicate)
   -    STATS_SECT_ENTRY(indicate_fail)
   -    STATS_SECT_ENTRY(proc_timeout)
   +STATS_SECT_ENTRY(mtu)
   +STATS_SECT_ENTRY(mtu_fail)
   +STATS_SECT_ENTRY(disc_all_svcs)
   +STATS_SECT_ENTRY(disc_all_svcs_fail)
   +STATS_SECT_ENTRY(disc_svc_uuid)
   +STATS_SECT_ENTRY(disc_svc_uuid_fail)
   +STATS_SECT_ENTRY(find_inc_svcs)
   +STATS_SECT_ENTRY(find_inc_svcs_fail)
   +STATS_SECT_ENTRY(disc_all_chrs)
   +STATS_SECT_ENTRY(disc_all_chrs_fail)
   +STATS_SECT_ENTRY(disc_chrs_uuid)
   +STATS_SECT_ENTRY(disc_chrs_uuid_fail)
   +STATS_SECT_ENTRY(disc_all_dscs)
   +STATS_SECT_ENTRY(disc_all_dscs_fail)
   +STATS_SECT_ENTRY(read)
   +STATS_SECT_ENTRY(read_fail)
   +STATS_SECT_ENTRY(read_uuid)
   +STATS_SECT_ENTRY(read_uuid_fail)
   +STATS_SECT_ENTRY(read_long)
   +STATS_SECT_ENTRY(read_long_fail)
   +STATS_SECT_ENTRY(read_mult)
   +STATS_SECT_ENTRY(read_mult_fail)
   +STATS_SECT_ENTRY(write_no_rsp)
   +STATS_SECT_ENTRY(write_no_rsp_fail)
   +STATS_SECT_ENTRY(write)
   +STATS_SECT_ENTRY(write_fail)
   +STATS_SECT_ENTRY(write_long)
   +STATS_SECT_ENTRY(write_long_fail)
   +STATS_SECT_ENTRY(write_reliable)
   +STATS_SECT_ENTRY(write_reliable_fail)
   +STATS_SECT_ENTRY(notify)
   +STATS_SECT_ENTRY(notify_fail)
   +STATS_SECT_ENTRY(multi_notify)
   +STATS_SECT_ENTRY(multi_notify_fail)
   +STATS_SECT_ENTRY(indicate)
   +STATS_SECT_ENTRY(indicate_fail)
   +STATS_SECT_ENTRY(proc_timeout)
    STATS_SECT_END
    extern STATS_SECT_DECL(ble_gattc_stats) ble_gattc_stats;
    
    STATS_SECT_START(ble_gatts_stats)
   -    STATS_SECT_ENTRY(svcs)
   -    STATS_SECT_ENTRY(chrs)
   -    STATS_SECT_ENTRY(dscs)
   -    STATS_SECT_ENTRY(svc_def_reads)
   -    STATS_SECT_ENTRY(svc_inc_reads)
   -    STATS_SECT_ENTRY(chr_def_reads)
   -    STATS_SECT_ENTRY(chr_val_reads)
   -    STATS_SECT_ENTRY(chr_val_writes)
   -    STATS_SECT_ENTRY(dsc_reads)
   -    STATS_SECT_ENTRY(dsc_writes)
   +STATS_SECT_ENTRY(svcs)
   +STATS_SECT_ENTRY(chrs)
   +STATS_SECT_ENTRY(dscs)
   +STATS_SECT_ENTRY(svc_def_reads)
   +STATS_SECT_ENTRY(svc_inc_reads)
   +STATS_SECT_ENTRY(chr_def_reads)
   +STATS_SECT_ENTRY(chr_val_reads)
   +STATS_SECT_ENTRY(chr_val_writes)
   +STATS_SECT_ENTRY(dsc_reads)
   +STATS_SECT_ENTRY(dsc_writes)
    STATS_SECT_END
    extern STATS_SECT_DECL(ble_gatts_stats) ble_gatts_stats;
    
   ```
   
   </details>
   
   #### nimble/host/src/ble_gattc.c
   <details>
   
   ```diff
   @@ -434,48 +434,48 @@
    /* Statistics. */
    STATS_SECT_DECL(ble_gattc_stats) ble_gattc_stats;
    STATS_NAME_START(ble_gattc_stats)
   -    STATS_NAME(ble_gattc_stats, mtu)
   -    STATS_NAME(ble_gattc_stats, mtu_fail)
   -    STATS_NAME(ble_gattc_stats, disc_all_svcs)
   -    STATS_NAME(ble_gattc_stats, disc_all_svcs_fail)
   -    STATS_NAME(ble_gattc_stats, disc_svc_uuid)
   -    STATS_NAME(ble_gattc_stats, disc_svc_uuid_fail)
   -    STATS_NAME(ble_gattc_stats, find_inc_svcs)
   -    STATS_NAME(ble_gattc_stats, find_inc_svcs_fail)
   -    STATS_NAME(ble_gattc_stats, disc_all_chrs)
   -    STATS_NAME(ble_gattc_stats, disc_all_chrs_fail)
   -    STATS_NAME(ble_gattc_stats, disc_chrs_uuid)
   -    STATS_NAME(ble_gattc_stats, disc_chrs_uuid_fail)
   -    STATS_NAME(ble_gattc_stats, disc_all_dscs)
   -    STATS_NAME(ble_gattc_stats, disc_all_dscs_fail)
   -    STATS_NAME(ble_gattc_stats, read)
   -    STATS_NAME(ble_gattc_stats, read_fail)
   -    STATS_NAME(ble_gattc_stats, read_uuid)
   -    STATS_NAME(ble_gattc_stats, read_uuid_fail)
   -    STATS_NAME(ble_gattc_stats, read_long)
   -    STATS_NAME(ble_gattc_stats, read_long_fail)
   -    STATS_NAME(ble_gattc_stats, read_mult)
   -    STATS_NAME(ble_gattc_stats, read_mult_fail)
   -    STATS_NAME(ble_gattc_stats, write_no_rsp)
   -    STATS_NAME(ble_gattc_stats, write_no_rsp_fail)
   -    STATS_NAME(ble_gattc_stats, write)
   -    STATS_NAME(ble_gattc_stats, write_fail)
   -    STATS_NAME(ble_gattc_stats, write_long)
   -    STATS_NAME(ble_gattc_stats, write_long_fail)
   -    STATS_NAME(ble_gattc_stats, write_reliable)
   -    STATS_NAME(ble_gattc_stats, write_reliable_fail)
   -    STATS_NAME(ble_gattc_stats, notify)
   -    STATS_NAME(ble_gattc_stats, notify_fail)
   -    STATS_NAME(ble_gattc_stats, multi_notify)
   -    STATS_NAME(ble_gattc_stats, multi_notify_fail)
   -    STATS_NAME(ble_gattc_stats, indicate)
   -    STATS_NAME(ble_gattc_stats, indicate_fail)
   -    STATS_NAME(ble_gattc_stats, proc_timeout)
   +STATS_NAME(ble_gattc_stats, mtu)
   +STATS_NAME(ble_gattc_stats, mtu_fail)
   +STATS_NAME(ble_gattc_stats, disc_all_svcs)
   +STATS_NAME(ble_gattc_stats, disc_all_svcs_fail)
   +STATS_NAME(ble_gattc_stats, disc_svc_uuid)
   +STATS_NAME(ble_gattc_stats, disc_svc_uuid_fail)
   +STATS_NAME(ble_gattc_stats, find_inc_svcs)
   +STATS_NAME(ble_gattc_stats, find_inc_svcs_fail)
   +STATS_NAME(ble_gattc_stats, disc_all_chrs)
   +STATS_NAME(ble_gattc_stats, disc_all_chrs_fail)
   +STATS_NAME(ble_gattc_stats, disc_chrs_uuid)
   +STATS_NAME(ble_gattc_stats, disc_chrs_uuid_fail)
   +STATS_NAME(ble_gattc_stats, disc_all_dscs)
   +STATS_NAME(ble_gattc_stats, disc_all_dscs_fail)
   +STATS_NAME(ble_gattc_stats, read)
   +STATS_NAME(ble_gattc_stats, read_fail)
   +STATS_NAME(ble_gattc_stats, read_uuid)
   +STATS_NAME(ble_gattc_stats, read_uuid_fail)
   +STATS_NAME(ble_gattc_stats, read_long)
   +STATS_NAME(ble_gattc_stats, read_long_fail)
   +STATS_NAME(ble_gattc_stats, read_mult)
   +STATS_NAME(ble_gattc_stats, read_mult_fail)
   +STATS_NAME(ble_gattc_stats, write_no_rsp)
   +STATS_NAME(ble_gattc_stats, write_no_rsp_fail)
   +STATS_NAME(ble_gattc_stats, write)
   +STATS_NAME(ble_gattc_stats, write_fail)
   +STATS_NAME(ble_gattc_stats, write_long)
   +STATS_NAME(ble_gattc_stats, write_long_fail)
   +STATS_NAME(ble_gattc_stats, write_reliable)
   +STATS_NAME(ble_gattc_stats, write_reliable_fail)
   +STATS_NAME(ble_gattc_stats, notify)
   +STATS_NAME(ble_gattc_stats, notify_fail)
   +STATS_NAME(ble_gattc_stats, multi_notify)
   +STATS_NAME(ble_gattc_stats, multi_notify_fail)
   +STATS_NAME(ble_gattc_stats, indicate)
   +STATS_NAME(ble_gattc_stats, indicate_fail)
   +STATS_NAME(ble_gattc_stats, proc_timeout)
    STATS_NAME_END(ble_gattc_stats)
    
    /*****************************************************************************
   - * $debug                                                                    *
   - *****************************************************************************/
   +* $debug                                                                    *
   +*****************************************************************************/
    
    static void
    ble_gattc_dbg_assert_proc_not_inserted(struct ble_gattc_proc *proc)
   ```
   
   </details>


-- 
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] SumeetSingh19 commented on pull request #1426: NimBLE/Host: Feature Multi Handle Value Notification

Posted by "SumeetSingh19 (via GitHub)" <gi...@apache.org>.
SumeetSingh19 commented on PR #1426:
URL: https://github.com/apache/mynewt-nimble/pull/1426#issuecomment-1413222544

   Hi @sjanc,
   Could you take a look at this please.


-- 
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] SumeetSingh19 commented on a diff in pull request #1426: NimBLE/Host: Feature Multi Handle Value Notification

Posted by "SumeetSingh19 (via GitHub)" <gi...@apache.org>.
SumeetSingh19 commented on code in PR #1426:
URL: https://github.com/apache/mynewt-nimble/pull/1426#discussion_r1149123945


##########
nimble/host/src/ble_att_clt.c:
##########
@@ -907,6 +907,59 @@ ble_att_clt_tx_notify(uint16_t conn_handle, uint16_t handle,
     return rc;
 }
 
+/*****************************************************************************
+* $multi handle value notification                                           *
+*****************************************************************************/
+
+int
+ble_att_clt_tx_multi_notify(uint16_t conn_handle, uint16_t * att_handles,
+                            struct os_mbuf ** notif_values, uint16_t num_handles)
+{
+#if !NIMBLE_BLE_ATT_CLT_MULTI_NOTIFY
+    return BLE_HS_ENOTSUP;
+#endif
+
+    struct os_mbuf * txom;
+    int rc;
+    int i;
+
+    if (ble_att_cmd_get(BLE_ATT_OP_MULTI_NOTIFY_REQ, 0, &txom) == NULL) {
+        rc = BLE_HS_ENOMEM;
+        goto err;
+    }
+
+    for (i = 0; i < num_handles; i++) {
+        /* Handle */
+        rc = os_mbuf_copyinto(txom, OS_MBUF_PKTLEN(txom),
+                              &att_handles[i], sizeof(att_handles[i]));
+        if (rc != 0) {
+            rc = BLE_HS_ENOMEM;
+            goto err;
+        }
+        /* Length */
+        rc = os_mbuf_copyinto(txom, OS_MBUF_PKTLEN(txom),
+                              &(OS_MBUF_PKTLEN(notif_values[i])),
+                              sizeof(OS_MBUF_PKTLEN(notif_values[i])));
+        if (rc != 0) {
+            rc = BLE_HS_ENOMEM;
+            goto err;
+        }
+        /* Value */
+        rc = os_mbuf_copyinto(txom, OS_MBUF_PKTLEN(txom),

Review Comment:
   Done



-- 
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 pull request #1426: NimBLE/Host: Feature Multi Handle Value Notification

Posted by "sjanc (via GitHub)" <gi...@apache.org>.
sjanc commented on PR #1426:
URL: https://github.com/apache/mynewt-nimble/pull/1426#issuecomment-1415591677

   oh, and it would be nice if you could also add some unit tests for those (see  nimble/host/test/)


-- 
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] SumeetSingh19 commented on a diff in pull request #1426: NimBLE/Host: Feature Multi Handle Value Notification

Posted by "SumeetSingh19 (via GitHub)" <gi...@apache.org>.
SumeetSingh19 commented on code in PR #1426:
URL: https://github.com/apache/mynewt-nimble/pull/1426#discussion_r1097101645


##########
nimble/host/include/host/ble_gatt.h:
##########
@@ -473,6 +473,23 @@ int ble_gattc_write_reliable(uint16_t conn_handle,
 int ble_gatts_notify_custom(uint16_t conn_handle, uint16_t att_handle,
                             struct os_mbuf *om);
 
+/**
+ * Sends multiple characteristic notifications on the specified
+ * attribute handles. This function consumes the mbuf of the
+ * notification value after sending notification.
+ *
+ * @param conn_handle       The connection over which to execute the
+ *                              procedure.
+ * @param att_handles       The list of attribute handles to which
+ *                              notifications have to be sent.
+ * @param notif_values      The list of notification value mbufs.
+ * @param num_handles        The number of handles to notify.
+ *
+ * @return                  0 on success; nonzero on failure.
+ */
+int ble_gatts_multi_notify_custom(uint16_t conn_handle, uint16_t * att_handles,

Review Comment:
   This was my original implementation but in order to use this structure I had to define it in `ble_gatt.h`.
   
   `ble_gatt.h` is inaccessible in both `ble_att_clt.c` and `ble_att_priv.h` (which contain the definition and header of the ATT API).
   
   `ble_att.h` is also a place where I could declare something like this, but that file did not contain a single struct definition so I avoided it.
   
   Which would be better? Including `ble_gatt.h` in `ble_att_priv.h` or using `ble_att.h` instead?



-- 
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] SumeetSingh19 commented on pull request #1426: NimBLE/Host: Feature Multi Handle Value Notification

Posted by "SumeetSingh19 (via GitHub)" <gi...@apache.org>.
SumeetSingh19 commented on PR #1426:
URL: https://github.com/apache/mynewt-nimble/pull/1426#issuecomment-1449438712

   #AutoPTS run mynewt GATT/SR/GAN


-- 
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] SumeetSingh19 commented on a diff in pull request #1426: NimBLE/Host: Feature Multi Handle Value Notification

Posted by "SumeetSingh19 (via GitHub)" <gi...@apache.org>.
SumeetSingh19 commented on code in PR #1426:
URL: https://github.com/apache/mynewt-nimble/pull/1426#discussion_r1106734247


##########
porting/examples/linux/include/syscfg/syscfg.h:
##########
@@ -531,6 +531,10 @@
 #define MYNEWT_VAL_BLE_ATT_SVR_NOTIFY (1)
 #endif
 
+#ifndef MYNEWT_VAL_BLE_ATT_SVR_MULTI_NOTIFY
+#define MYNEWT_VAL_BLE_ATT_SVR_MULTI_NOTIFY (1)

Review Comment:
   Can you tell me how this script is supposed to be used as I am unable to find any documentation on it?



-- 
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] andrzej-kaczmarek commented on a diff in pull request #1426: NimBLE/Host: Feature Multi Handle Value Notification

Posted by "andrzej-kaczmarek (via GitHub)" <gi...@apache.org>.
andrzej-kaczmarek commented on code in PR #1426:
URL: https://github.com/apache/mynewt-nimble/pull/1426#discussion_r1106796075


##########
porting/examples/linux/include/syscfg/syscfg.h:
##########
@@ -531,6 +531,10 @@
 #define MYNEWT_VAL_BLE_ATT_SVR_NOTIFY (1)
 #endif
 
+#ifndef MYNEWT_VAL_BLE_ATT_SVR_MULTI_NOTIFY
+#define MYNEWT_VAL_BLE_ATT_SVR_MULTI_NOTIFY (1)

Review Comment:
   you just need to run it from root directory of Mynewt project:
   ```
   andk@x1n:~/devel/mynewt$ repos/apache-mynewt-nimble/porting/update_generated_files.sh 
   Updating target linux
   Updating target riot
   Updating target porting_default
   Updating target linux_blemesh
   Updating target nuttx
   ```



-- 
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] apache-mynewt-bot commented on pull request #1426: NimBLE/Host: Feature Multi Handle Value Notification

Posted by GitBox <gi...@apache.org>.
apache-mynewt-bot commented on PR #1426:
URL: https://github.com/apache/mynewt-nimble/pull/1426#issuecomment-1397975025

   
   <!-- style-bot -->
   
   ## Style check summary
   
   #### No suggestions at this time!
   


-- 
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] apache-mynewt-bot commented on pull request #1426: NimBLE/Host: Feature Multi Handle Value Notification

Posted by "apache-mynewt-bot (via GitHub)" <gi...@apache.org>.
apache-mynewt-bot commented on PR #1426:
URL: https://github.com/apache/mynewt-nimble/pull/1426#issuecomment-1399914937

   
   <!-- style-bot -->
   
   ## Style check summary
   
   #### No suggestions at this time!
   


-- 
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


Re: [PR] NimBLE/Host: Feature Multi Handle Value Notification [mynewt-nimble]

Posted by "SumeetSingh19 (via GitHub)" <gi...@apache.org>.
SumeetSingh19 commented on code in PR #1426:
URL: https://github.com/apache/mynewt-nimble/pull/1426#discussion_r1414940602


##########
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;

Review Comment:
   this value of `split_at` is used in the first iteration of the loop.



-- 
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