Просмотр исходного кода

ble_mesh: No timeout for client message to non-unicast address

lly 6 лет назад
Родитель
Сommit
4a3b06dde3
1 измененных файлов с 63 добавлено и 32 удалено
  1. 63 32
      components/bt/esp_ble_mesh/mesh_models/client/client_common.c

+ 63 - 32
components/bt/esp_ble_mesh/mesh_models/client/client_common.c

@@ -245,7 +245,7 @@ int bt_mesh_client_send_msg(struct bt_mesh_model *model,
                             void *cb_data)
 {
     bt_mesh_client_internal_data_t *internal = NULL;
-    bt_mesh_client_user_data_t *cli = NULL;
+    bt_mesh_client_user_data_t *client = NULL;
     bt_mesh_client_node_t *node = NULL;
     int err = 0;
 
@@ -254,49 +254,80 @@ int bt_mesh_client_send_msg(struct bt_mesh_model *model,
         return -EINVAL;
     }
 
-    cli = (bt_mesh_client_user_data_t *)model->user_data;
-    __ASSERT(cli, "Invalid client value when sent client msg.");
-    internal = (bt_mesh_client_internal_data_t *)cli->internal_data;
-    __ASSERT(internal, "Invalid internal value when sent client msg.");
+    client = (bt_mesh_client_user_data_t *)model->user_data;
+    if (!client) {
+        BT_ERR("%s, Invalid client user data", __func__);
+        return -EINVAL;
+    }
+
+    internal = (bt_mesh_client_internal_data_t *)client->internal_data;
+    if (!internal) {
+        BT_ERR("%s, Invalid client internal data", __func__);
+        return -EINVAL;
+    }
+
+    if (ctx->addr == BLE_MESH_ADDR_UNASSIGNED) {
+        BT_ERR("%s, Invalid DST 0x%04x", __func__, ctx->addr);
+        return -EINVAL;
+    }
 
     if (!need_ack) {
         /* If this is an unack message, send it directly. */
         return bt_mesh_model_send(model, ctx, msg, cb, cb_data);
     }
 
+    if (!BLE_MESH_ADDR_IS_UNICAST(ctx->addr)) {
+        /* If an acknowledged message is not sent to a unicast address,
+         * for example to a group/virtual address, then all the
+         * corresponding responses will be treated as publish messages.
+         * And no timeout will be used for the message.
+         */
+        return bt_mesh_model_send(model, ctx, msg, cb, cb_data);
+    }
+
+    if (!timer_handler) {
+        BT_ERR("%s, Invalid timeout handler", __func__);
+        return -EINVAL;
+    }
+
     if (bt_mesh_client_check_node_in_list(&internal->queue, ctx->addr)) {
         BT_ERR("%s, Busy sending message to DST 0x%04x", __func__, ctx->addr);
-        err = -EBUSY;
-    } else {
-        /* Don't forget to free the node in the timeout (timer_handler) function. */
-        node = (bt_mesh_client_node_t *)bt_mesh_calloc(sizeof(bt_mesh_client_node_t));
-        if (!node) {
-            BT_ERR("%s, Failed to allocate memory", __func__);
-            return -ENOMEM;
-        }
-        memcpy(&node->ctx, ctx, sizeof(struct bt_mesh_msg_ctx));
-        node->ctx.model = model;
-        node->opcode = opcode;
-        if ((node->op_pending = bt_mesh_client_get_status_op(cli->op_pair, cli->op_pair_size, opcode)) == 0) {
-            BT_ERR("%s, Not found the status opcode in the op_pair list", __func__);
-            bt_mesh_free(node);
-            return -EINVAL;
-        }
+        return -EBUSY;
+    }
 
-        s32_t time = bt_mesh_client_calc_timeout(ctx, msg, opcode, timeout ? timeout : CONFIG_BLE_MESH_CLIENT_MSG_TIMEOUT);
+    /* Don't forget to free the node in the timeout (timer_handler) function. */
+    node = (bt_mesh_client_node_t *)bt_mesh_calloc(sizeof(bt_mesh_client_node_t));
+    if (!node) {
+        BT_ERR("%s, Failed to allocate memory", __func__);
+        return -ENOMEM;
+    }
 
-        if ((err = bt_mesh_model_send(model, ctx, msg, cb, cb_data)) != 0) {
-            bt_mesh_free(node);
-        } else {
-            bt_mesh_list_lock();
-            sys_slist_append(&internal->queue, &node->client_node);
-            bt_mesh_list_unlock();
-            k_delayed_work_init(&node->timer, timer_handler);
-            k_delayed_work_submit(&node->timer, time);
-        }
+    memcpy(&node->ctx, ctx, sizeof(struct bt_mesh_msg_ctx));
+    node->ctx.model = model;
+    node->opcode = opcode;
+    node->op_pending = bt_mesh_client_get_status_op(client->op_pair, client->op_pair_size, opcode);
+    if (node->op_pending == 0U) {
+        BT_ERR("%s, Not found the status opcode in the op_pair list", __func__);
+        bt_mesh_free(node);
+        return -EINVAL;
+    }
+
+    s32_t time = bt_mesh_client_calc_timeout(ctx, msg, opcode, timeout ? timeout : CONFIG_BLE_MESH_CLIENT_MSG_TIMEOUT);
+
+    err = bt_mesh_model_send(model, ctx, msg, cb, cb_data);
+    if (err) {
+        bt_mesh_free(node);
+        return err;
     }
 
-    return err;
+    bt_mesh_list_lock();
+    sys_slist_append(&internal->queue, &node->client_node);
+    bt_mesh_list_unlock();
+
+    k_delayed_work_init(&node->timer, timer_handler);
+    k_delayed_work_submit(&node->timer, time);
+
+    return 0;
 }
 
 static bt_mesh_mutex_t client_model_lock;