CH582官方例程Mesh中的self_provisioner_vendor和adv_vendor。
配網(wǎng)者節(jié)點(diǎn):self_provisioner_vendor
普通入網(wǎng)節(jié)點(diǎn):adv_vendor
代碼修改調(diào)整部分:配網(wǎng)者節(jié)點(diǎn):
1、App_Init函數(shù)中注釋掉測(cè)試任務(wù),利用按鍵回調(diào)函數(shù)進(jìn)行測(cè)試(按下按鍵進(jìn)行數(shù)據(jù)發(fā)送,從而開(kāi)始節(jié)點(diǎn)間數(shù)據(jù)傳輸)
?void App_Init(void)
?{
? ? ?// 注冊(cè)事件處理函數(shù)到TMOS任務(wù)系統(tǒng)
? ? ?App_TaskID = TMOS_ProcessEventRegister(App_ProcessEvent);
?
? ? ?// 初始化自定義廠商模型客戶端
? ? ?vendor_model_cli_init(vnd_models);
? ? ?// 同步BLE Mesh功能和參數(shù)
? ? ?blemesh_on_sync();
?
? ? ?// 初始化按鍵硬件
? ? ?HAL_KeyInit();
? ? ?// 配置按鍵回調(diào)函數(shù)
? ? ?HalKeyConfig(keyPress);
?
? ? ?// 添加一個(gè)測(cè)試任務(wù),定時(shí)向第一個(gè)配網(wǎng)設(shè)備發(fā)送透?jìng)鲾?shù)據(jù),定時(shí)時(shí)長(zhǎng)為4800ms
?// ? ?tmos_start_task(App_TaskID, APP_NODE_TEST_EVT, 4800);
?}
對(duì)keyPress函數(shù)進(jìn)行修改,通過(guò)按鍵控制數(shù)據(jù)發(fā)送,從而開(kāi)啟節(jié)點(diǎn)間數(shù)據(jù)傳輸
?void keyPress(uint8_t keys)
?{
? ? ?APP_DBG("%d", keys); // 打印按鍵的值,用于調(diào)試。
?
? ? ?switch(keys) // 根據(jù)按鍵的值執(zhí)行不同的操作。
? ? ?{
? ? ? ? ?default: // 默認(rèn)情況下(未指定特殊鍵的處理邏輯時(shí)),執(zhí)行以下代碼:
? ? ? ? ?{
? ? ? ? ? ? ?if(3) // 如果按鍵為3,即評(píng)估版的S4-KEY
? ? ? ? ? ? ?{
? ? ? ? ? ? ? ? ?// 向所有入網(wǎng)節(jié)點(diǎn)廣播數(shù)據(jù),從而開(kāi)始節(jié)點(diǎn)間數(shù)據(jù)傳輸
? ? ? ? ? ? ? ? ?uint8_t status;
? ? ? ? ? ? ? ? ?uint8_t data[4] = {0, 1, 2, 3}; // 準(zhǔn)備要發(fā)送的測(cè)試數(shù)據(jù)
? ? ? ? ? ? ? ? ?status = vendor_model_cli_send(0xFFFF, data, sizeof(data));
? ? ? ? ? ? ? ? ?if(status) // 如果發(fā)送失敗,打印錯(cuò)誤狀態(tài)
? ? ? ? ? ? ? ? ? ? ?APP_DBG("trans failed %d", status);
? ? ? ? ? ? ?}
?
?
? ? ? ? ? ? ?if(1) // 如果條件為true(這里只是示例,實(shí)際情況中會(huì)替換為具體的條件判斷。)
? ? ? ? ? ? ?{
? ? ? ? ? ? ? ? ?// 刪除節(jié)點(diǎn)操作
? ? ? ? ? ? ? ? ?if(app_nodes[1].node_addr) // 如果第二個(gè)節(jié)點(diǎn)的地址存在。
? ? ? ? ? ? ? ? ?{
? ? ? ? ? ? ? ? ? ? ?uint8_t status; // 定義刪除狀態(tài)變量。
? ? ? ? ? ? ? ? ? ? ?APP_DBG("node1_addr %x", app_nodes[1].node_addr); // 打印節(jié)點(diǎn)地址,用于調(diào)試。
? ? ? ? ? ? ? ? ? ? ?if(0) // 如果條件為false(這里只是示例,實(shí)際情況中會(huì)替換為具體的條件判斷。)
? ? ? ? ? ? ? ? ? ? ?{
? ? ? ? ? ? ? ? ? ? ? ? ?// 通過(guò)藍(lán)牙Mesh協(xié)議棧提供的命令來(lái)刪除節(jié)點(diǎn)
? ? ? ? ? ? ? ? ? ? ? ? ?status = bt_mesh_cfg_node_reset(self_prov_net_idx, app_nodes[1].node_addr);
? ? ? ? ? ? ? ? ? ? ? ? ?if(status) // 如果刪除失敗
? ? ? ? ? ? ? ? ? ? ? ? ?{
? ? ? ? ? ? ? ? ? ? ? ? ? ? ?APP_DBG("reset failed %d", status); // 打印刪除失敗的狀態(tài)碼。
? ? ? ? ? ? ? ? ? ? ? ? ?}
? ? ? ? ? ? ? ? ? ? ? ? ?else
? ? ? ? ? ? ? ? ? ? ? ? ?{
? ? ? ? ? ? ? ? ? ? ? ? ? ? ?reset_node_addr = app_nodes[1].node_addr; // 保存被刪除節(jié)點(diǎn)的地址。
? ? ? ? ? ? ? ? ? ? ? ? ?}
? ? ? ? ? ? ? ? ? ? ?}
? ? ? ? ? ? ? ? ? ? ?if(1) // 如果條件為true(這里只是示例,實(shí)際情況中會(huì)替換為具體的條件判斷。)
? ? ? ? ? ? ? ? ? ? ?{
? ? ? ? ? ? ? ? ? ? ? ? ?// 通過(guò)應(yīng)用層自定義協(xié)議來(lái)刪除節(jié)點(diǎn)。
? ? ? ? ? ? ? ? ? ? ? ? ?app_mesh_manage.delete_node.cmd = CMD_DELETE_NODE; // 設(shè)置刪除命令。
? ? ? ? ? ? ? ? ? ? ? ? ?// 設(shè)置節(jié)點(diǎn)地址,低字節(jié)和高字節(jié)。
? ? ? ? ? ? ? ? ? ? ? ? ?app_mesh_manage.delete_node.addr[0] = app_nodes[1].node_addr & 0xFF;
? ? ? ? ? ? ? ? ? ? ? ? ?app_mesh_manage.delete_node.addr[1] = (app_nodes[1].node_addr >> 8) & 0xFF;
? ? ? ? ? ? ? ? ? ? ? ? ?// 使用廠商自定義模型發(fā)送刪除節(jié)點(diǎn)的命令,并保存返回的狀態(tài)值。
? ? ? ? ? ? ? ? ? ? ? ? ?status = vendor_model_cli_send(app_nodes[1].node_addr, app_mesh_manage.data.buf, DELETE_NODE_DATA_LEN);
? ? ? ? ? ? ? ? ? ? ? ? ?if(status) // 如果刪除失敗。
? ? ? ? ? ? ? ? ? ? ? ? ?{
? ? ? ? ? ? ? ? ? ? ? ? ? ? ?APP_DBG("delete failed %d", status); // 打印刪除失敗的狀態(tài)碼。
? ? ? ? ? ? ? ? ? ? ? ? ?}
? ? ? ? ? ? ? ? ? ? ? ? ?else
? ? ? ? ? ? ? ? ? ? ? ? ?{
? ? ? ? ? ? ? ? ? ? ? ? ? ? ?// 啟動(dòng)一個(gè)定時(shí)任務(wù),3秒后沒(méi)有收到應(yīng)答則認(rèn)為超時(shí)。
? ? ? ? ? ? ? ? ? ? ? ? ? ? ?tmos_start_task(App_TaskID, APP_DELETE_NODE_TIMEOUT_EVT, 4800);
? ? ? ? ? ? ? ? ? ? ? ? ?}
? ? ? ? ? ? ? ? ? ? ?}
? ? ? ? ? ? ? ? ?}
? ? ? ? ? ? ?}
? ? ? ? ? ? ?break; // 結(jié)束switch語(yǔ)句
? ? ? ? ?}
? ? ?}
?}
2、修改vendor_model_cli_status_t結(jié)構(gòu)體的內(nèi)容,增加一項(xiàng)mydata數(shù)據(jù),用于記錄addr、rssi、ttl等信息
?typedef struct
?{
? ? ?struct vendor_model_cli_EventHdr vendor_model_cli_Hdr;
? ? ?union vendor_model_cli_Event_t ? vendor_model_cli_Event;
? ? ?void* mydata;
?} vendor_model_cli_status_t;
利用上述修改后的結(jié)構(gòu)體中增加的mydata變量,在vendor_message_cli_trans函數(shù)中修改廠商模型客戶端狀態(tài)參數(shù)
?static void vendor_message_cli_trans(struct bt_mesh_model ? *model,
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? struct bt_mesh_msg_ctx *ctx, struct net_buf_simple *buf)
?{
? ? ?vendor_model_cli_status_t vendor_model_cli_status; // 定義廠商模型客戶端狀態(tài)結(jié)構(gòu)體
? ? ?uint8_t ? ? ? ? ? ? ? ? ?*pData = buf->data; // 數(shù)據(jù)指針指向緩存的數(shù)據(jù)部分
? ? ?uint16_t ? ? ? ? ? ? ? ? ?len = buf->len; // 數(shù)據(jù)長(zhǎng)度
?
? ? ?// 檢查收到的TID和地址是否與期望的一致
? ? ?if((pData[0] != vendor_model_cli->cli_tid.trans_tid) ||
? ? ? ? (ctx->addr != vendor_model_cli->cli_tid.trans_addr))
? ? ?{
? ? ? ? ?// 更新期望的TID和地址
? ? ? ? ?vendor_model_cli->cli_tid.trans_tid = pData[0];
? ? ? ? ?vendor_model_cli->cli_tid.trans_addr = ctx->addr;
? ? ? ? ?// pData指針指向真正的數(shù)據(jù),跳過(guò)TID
? ? ? ? ?pData++;
? ? ? ? ?len--;
?
? ? ? ? ?// 設(shè)置廠商模型客戶端狀態(tài)參數(shù)
? ? ? ? ?vendor_model_cli_status.vendor_model_cli_Hdr.opcode =
? ? ? ? ? ? ?OP_VENDOR_MESSAGE_TRANSPARENT_MSG;
? ? ? ? ?vendor_model_cli_status.vendor_model_cli_Hdr.status = 0;
? ? ? ? ?vendor_model_cli_status.vendor_model_cli_Event.trans.pdata = pData;
? ? ? ? ?vendor_model_cli_status.vendor_model_cli_Event.trans.len = len;
? ? ? ? ?vendor_model_cli_status.vendor_model_cli_Event.trans.addr = ctx->addr;
? ? ? ? ?vendor_model_cli_status.mydata = (void*)ctx; // 新增的mydata變量記錄ctx
?
? ? ? ? ?// 如果設(shè)置了處理函數(shù),調(diào)用之
? ? ? ? ?if(vendor_model_cli->handler)
? ? ? ? ?{
? ? ? ? ? ? ?vendor_model_cli->handler(&vendor_model_cli_status);
? ? ? ? ?}
? ? ?}
?}
修改vendor_model_cli_rsp_handler函數(shù),在接收到消息后,打印上述獲得的ctx的具體內(nèi)容,即addr、rssi、ttl等,然后定義一個(gè)數(shù)據(jù)data廣播給0xFFFF,即所有節(jié)點(diǎn),這樣在配網(wǎng)器節(jié)點(diǎn)接收到數(shù)據(jù)后就會(huì)向所有入網(wǎng)節(jié)點(diǎn)廣播信息,從而獲得配網(wǎng)器節(jié)點(diǎn)和各個(gè)入網(wǎng)節(jié)點(diǎn)間的rssi等信息
?static void vendor_model_cli_rsp_handler(const vendor_model_cli_status_t *val)
?{
? ? ?// 如果狀態(tài)碼非0,說(shuō)明存在錯(cuò)誤或者超時(shí)未收到應(yīng)答
? ? ?if(val->vendor_model_cli_Hdr.status)
? ? ?{
? ? ? ? ?APP_DBG("Timeout opcode 0x%02x", val->vendor_model_cli_Hdr.opcode); // 打印超時(shí)信息及操作碼
? ? ? ? ?return; // 函數(shù)返回,不處理后續(xù)內(nèi)容
? ? ?}
?
? ? ?// 根據(jù)收到的操作碼執(zhí)行對(duì)應(yīng)的處理
? ? ?if(val->vendor_model_cli_Hdr.opcode == OP_VENDOR_MESSAGE_TRANSPARENT_MSG)
? ? ?{
? ? ? ? ?// 接收數(shù)據(jù)
? ? ? ? ?struct bt_mesh_msg_ctx *ctx = (struct bt_mesh_msg_ctx *)val->mydata;
? ? ? ? ?if(ctx->addr==0x0001)
? ? ? ? ? ? ?return;
? ? ? ? ?APP_DBG("MYDATA_CLI---src:0x%04x dst:0x%04x rssi:%d app_idx:0x%x recv_ttl:%d send_ttl:%d", ctx->addr, ctx->recv_dst, ctx->recv_rssi, ctx->app_idx, ctx->recv_ttl, ctx->send_ttl);
? ? ? ? ?// 發(fā)送數(shù)據(jù)
? ? ? ? ?uint8_t status;
? ? ? ? ?uint8_t data[4] = {0, 1, 2, 3}; // 準(zhǔn)備要發(fā)送的測(cè)試數(shù)據(jù)
? ? ? ? ?status=vendor_model_cli_send(0xFFFF,data,sizeof(data));
? ? ? ? ?if(status) // 如果發(fā)送失敗,打印錯(cuò)誤狀態(tài)
? ? ? ? ? ? ?APP_DBG("trans failed %d", status);
?
? ? ? ? ?// 將透?jìng)鲾?shù)據(jù)復(fù)制到app_mesh_manage結(jié)構(gòu)中
? ? ? ? ?tmos_memcpy(&app_mesh_manage, val->vendor_model_cli_Event.trans.pdata, val->vendor_model_cli_Event.trans.len);
?
? ? ? ? ?// 根據(jù)透?jìng)鲾?shù)據(jù)的首個(gè)字節(jié)判斷處理邏輯
? ? ? ? ?switch(app_mesh_manage.data.buf[0])
? ? ? ? ?{
? ? ? ? ? ? ?case CMD_DELETE_NODE_ACK: // 應(yīng)用層自定義刪除命令應(yīng)答
? ? ? ? ? ? ?{
? ? ? ? ? ? ? ? ?// 如果接收到的數(shù)據(jù)長(zhǎng)度不正確,打印錯(cuò)誤信息后返回
? ? ? ? ? ? ? ? ?if(val->vendor_model_cli_Event.trans.len != DELETE_NODE_ACK_DATA_LEN)
? ? ? ? ? ? ? ? ?{
? ? ? ? ? ? ? ? ? ? ?APP_DBG("Delete node ack data err!");
? ? ? ? ? ? ? ? ? ? ?return;
? ? ? ? ? ? ? ? ?}
?
? ? ? ? ? ? ? ? ?// 定義節(jié)點(diǎn)指針,處理刪除節(jié)點(diǎn)的應(yīng)答邏輯
? ? ? ? ? ? ? ? ?node_t *node;
? ? ? ? ? ? ? ? ?// 停止刪除節(jié)點(diǎn)的超時(shí)任務(wù)
? ? ? ? ? ? ? ? ?tmos_stop_task(App_TaskID, APP_DELETE_NODE_TIMEOUT_EVT);
? ? ? ? ? ? ? ? ?// 按地址刪除節(jié)點(diǎn)
? ? ? ? ? ? ? ? ?bt_mesh_node_del_by_addr(val->vendor_model_cli_Event.trans.addr);
? ? ? ? ? ? ? ? ?// 獲取相應(yīng)地址的節(jié)點(diǎn)
? ? ? ? ? ? ? ? ?node = node_get(val->vendor_model_cli_Event.trans.addr);
? ? ? ? ? ? ? ? ?// 設(shè)置節(jié)點(diǎn)為初始化狀態(tài)
? ? ? ? ? ? ? ? ?node->stage.node = NODE_INIT;
? ? ? ? ? ? ? ? ?// 設(shè)置節(jié)點(diǎn)地址為未分配
? ? ? ? ? ? ? ? ?node->node_addr = BLE_MESH_ADDR_UNASSIGNED;
? ? ? ? ? ? ? ? ?// 設(shè)置false,表示節(jié)點(diǎn)不固定(未配網(wǎng)狀態(tài))
? ? ? ? ? ? ? ? ?APP_DBG("Delete node complete"); // 打印節(jié)點(diǎn)刪除成功的信息
? ? ? ? ? ? ? ? ?break;
? ? ? ? ? ? ?}
? ? ? ? ? ? ?// 可以添加更多的case處理其他消息類(lèi)型
? ? ? ? ?}
? ? ?}
? ? ?else if(val->vendor_model_cli_Hdr.opcode == OP_VENDOR_MESSAGE_TRANSPARENT_IND)
? ? ?{
?
? ? ?}
? ? ?else if(val->vendor_model_cli_Hdr.opcode == OP_VENDOR_MESSAGE_TRANSPARENT_WRT)
? ? ?{
? ? ? ? ?// 如果是write類(lèi)型的響應(yīng),這里沒(méi)有做特殊處理
? ? ?}
? ? ?else
? ? ?{
? ? ? ? ?// 未知的操作碼類(lèi)型,打印操作碼信息
? ? ? ? ?APP_DBG("Unknow opcode 0x%02x", val->vendor_model_cli_Hdr.opcode);
? ? ?}
?}
普通入網(wǎng)節(jié)點(diǎn):
1、和配網(wǎng)者節(jié)點(diǎn)類(lèi)似,修改vendor_model_srv_status_t結(jié)構(gòu)體的內(nèi)容,增加一項(xiàng)mydata數(shù)據(jù),用于記錄addr、rssi、ttl等信息
?typedef struct
?{
? ? ?struct vendor_model_srv_EventHdr vendor_model_srv_Hdr;
? ? ?union vendor_model_srv_Event_t ? vendor_model_srv_Event;
? ? ?void* mydata;
?} vendor_model_srv_status_t;
2、利用上述修改后的結(jié)構(gòu)體中增加的mydata變量,在vendor_message_srv_trans函數(shù)中修改廠商模型服務(wù)端狀態(tài)參數(shù)
?static void vendor_message_srv_trans(struct bt_mesh_model ? *model,
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? struct bt_mesh_msg_ctx *ctx, struct net_buf_simple *buf)
?{
? ? ?// 定義Vendor Model服務(wù)狀態(tài)結(jié)構(gòu)體
? ? ?vendor_model_srv_status_t vendor_model_srv_status;
? ? ?uint8_t ? ? ? ? ? ? ? ? ?*pData = buf->data; ?// 指向接收數(shù)據(jù)內(nèi)容的指針
? ? ?uint16_t ? ? ? ? ? ? ? ? ?len = buf->len; ? ? // 接收數(shù)據(jù)的長(zhǎng)度
?
? ? ?// 如果接收到的消息的事務(wù)ID或地址與期望的不同,則記錄并處理該消息
? ? ?if((pData[0] != vendor_model_srv->srv_tid.trans_tid) ||
? ? ? ? (ctx->addr != vendor_model_srv->srv_tid.trans_addr))
? ? ?{
? ? ? ? ?// 更新期望的事務(wù)ID和來(lái)源地址
? ? ? ? ?vendor_model_srv->srv_tid.trans_tid = pData[0];
? ? ? ? ?vendor_model_srv->srv_tid.trans_addr = ctx->addr;
? ? ? ? ?// 跳過(guò)事務(wù)ID
? ? ? ? ?pData++;
? ? ? ? ?len--;
? ? ? ? ?// 設(shè)置狀態(tài)結(jié)構(gòu)體的操作碼和狀態(tài)
? ? ? ? ?vendor_model_srv_status.vendor_model_srv_Hdr.opcode =
? ? ? ? ? ? ?OP_VENDOR_MESSAGE_TRANSPARENT_MSG;
? ? ? ? ?vendor_model_srv_status.vendor_model_srv_Hdr.status = 0;
? ? ? ? ?// 設(shè)置狀態(tài)結(jié)構(gòu)體的事件參數(shù),包括數(shù)據(jù)內(nèi)容、長(zhǎng)度和來(lái)源地址
? ? ? ? ?vendor_model_srv_status.vendor_model_srv_Event.trans.pdata = pData;
? ? ? ? ?vendor_model_srv_status.vendor_model_srv_Event.trans.len = len;
? ? ? ? ?vendor_model_srv_status.vendor_model_srv_Event.trans.addr = ctx->addr;
? ? ? ? ?vendor_model_srv_status.mydata=ctx; // 新增的mydata變量記錄ctx
? ? ? ? ?// 如果存在處理函數(shù),調(diào)用該函數(shù)
? ? ? ? ?if(vendor_model_srv->handler)
? ? ? ? ?{
? ? ? ? ? ? ?vendor_model_srv->handler(&vendor_model_srv_status);
? ? ? ? ?}
? ? ?}
?}
3、修改vendor_model_srv_rsp_handler函數(shù),在接收到消息后,打印上述獲得的ctx的具體內(nèi)容,即addr、rssi、ttl等,然后定義一個(gè)數(shù)據(jù)data廣播給0xFFFF,即所有節(jié)點(diǎn),這樣在入網(wǎng)節(jié)點(diǎn)接收到數(shù)據(jù)后就會(huì)向所有節(jié)點(diǎn)(包括配網(wǎng)器節(jié)點(diǎn)和其他入網(wǎng)節(jié)點(diǎn))廣播信息,從而獲得當(dāng)前入網(wǎng)節(jié)點(diǎn)和其他節(jié)點(diǎn)間的rssi等信息
?static void vendor_model_srv_rsp_handler(const vendor_model_srv_status_t *val)
?{
? ? ?// 如果收到的消息表明有錯(cuò)誤或狀態(tài)不正確
? ? ?if(val->vendor_model_srv_Hdr.status)
? ? ?{
? ? ? ? ?// 如果是因?yàn)閼?yīng)答回復(fù)超時(shí)未收到
? ? ? ? ?APP_DBG("Timeout opcode 0x%02x", val->vendor_model_srv_Hdr.opcode);
? ? ? ? ?return;
? ? ?}
? ? ?// 如果操作碼表示是透?jìng)飨?/span>
? ? ?if(val->vendor_model_srv_Hdr.opcode == OP_VENDOR_MESSAGE_TRANSPARENT_MSG)
? ? ?{
? ? ? ? ?// 接收
? ? ? ? ?struct bt_mesh_msg_ctx *ctx = (struct bt_mesh_msg_ctx *)val->mydata;
? ? ? ? ?if(ctx->addr==my_addr)
? ? ? ? ? ? ?return;
? ? ? ? ?APP_DBG("MYDATA_SRV---src:0x%04x dst:0x%04x rssi:%d app_idx:0x%x recv_ttl:%d send_ttl:%d", ctx->addr, ctx->recv_dst, ctx->recv_rssi, ctx->app_idx, ctx->recv_ttl, ctx->send_ttl);
?
? ? ? ? ?// 發(fā)送
? ? ? ? ?uint8_t status;
? ? ? ? ?uint8_t data[4] = {0, 1, 2, 3}; // 準(zhǔn)備要發(fā)送的測(cè)試數(shù)據(jù)
? ? ? ? ?status=vendor_model_srv_send(0xFFFF,data,sizeof(data));
? ? ? ? ?if(status) // 如果發(fā)送失敗,打印錯(cuò)誤狀態(tài)
? ? ? ? ? ? ?APP_DBG("trans failed %d", status);
?
? ? ? ? ?// 將收到的數(shù)據(jù)復(fù)制到app_mesh_manage中
? ? ? ? ?tmos_memcpy(&app_mesh_manage, val->vendor_model_srv_Event.trans.pdata, val->vendor_model_srv_Event.trans.len);
? ? ? ? ?// 根據(jù)消息內(nèi)容的第一個(gè)字節(jié)判斷消息類(lèi)型
? ? ? ? ?switch(app_mesh_manage.data.buf[0])
? ? ? ? ?{
? ? ? ? ? ? ?// 如果是刪除節(jié)點(diǎn)的命令
? ? ? ? ? ? ?case CMD_DELETE_NODE:
? ? ? ? ? ? ?{
? ? ? ? ? ? ? ? ?// 檢查接收到的數(shù)據(jù)長(zhǎng)度是否合理
? ? ? ? ? ? ? ? ?if(val->vendor_model_srv_Event.trans.len != DELETE_NODE_DATA_LEN)
? ? ? ? ? ? ? ? ?{
? ? ? ? ? ? ? ? ? ? ?APP_DBG("Delete node data err!");
? ? ? ? ? ? ? ? ? ? ?return;
? ? ? ? ? ? ? ? ?}
? ? ? ? ? ? ? ? ?uint8_t status;
? ? ? ? ? ? ? ? ?// 收到刪除命令,打印信息并發(fā)送ack回信,然后啟動(dòng)延時(shí)以刪除本節(jié)點(diǎn)
? ? ? ? ? ? ? ? ?APP_DBG("receive delete cmd, send ack and start delete node delay");
? ? ? ? ? ? ? ? ?app_mesh_manage.delete_node_ack.cmd = CMD_DELETE_NODE_ACK;
? ? ? ? ? ? ? ? ?status = vendor_model_srv_send(val->vendor_model_srv_Event.trans.addr,
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?app_mesh_manage.data.buf, DELETE_NODE_ACK_DATA_LEN);
? ? ? ? ? ? ? ? ?// 如果發(fā)送ack失敗,打印錯(cuò)誤信息
? ? ? ? ? ? ? ? ?if(status)
? ? ? ? ? ? ? ? ?{
? ? ? ? ? ? ? ? ? ? ?APP_DBG("send ack failed %d", status);
? ? ? ? ? ? ? ? ?}
? ? ? ? ? ? ? ? ?// 向所有節(jié)點(diǎn)發(fā)送命令,告知它們刪除存儲(chǔ)的相關(guān)信息
? ? ? ? ? ? ? ? ?APP_DBG("send to all node to let them delete stored info ");
? ? ? ? ? ? ? ? ?app_mesh_manage.delete_node_info.cmd = CMD_DELETE_NODE_INFO;
? ? ? ? ? ? ? ? ?status = vendor_model_srv_send(BLE_MESH_ADDR_ALL_NODES,
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?app_mesh_manage.data.buf, DELETE_NODE_INFO_DATA_LEN);
? ? ? ? ? ? ? ? ?// 如果發(fā)送失敗,則打印錯(cuò)誤信息
? ? ? ? ? ? ? ? ?if(status)
? ? ? ? ? ? ? ? ?{
? ? ? ? ? ? ? ? ? ? ?APP_DBG("send ack failed %d", status);
? ? ? ? ? ? ? ? ?}
? ? ? ? ? ? ? ? ?// 啟動(dòng)一個(gè)任務(wù),延時(shí)刪除本節(jié)點(diǎn)
? ? ? ? ? ? ? ? ?tmos_start_task(App_TaskID, APP_DELETE_LOCAL_NODE_EVT, APP_DELETE_LOCAL_NODE_DELAY);
? ? ? ? ? ? ? ? ?break;
? ? ? ? ? ? ?}
? ? ? ? ? ? ?// 如果是有節(jié)點(diǎn)被刪除的命令,需要?jiǎng)h除存儲(chǔ)的該節(jié)點(diǎn)信息
? ? ? ? ? ? ?case CMD_DELETE_NODE_INFO:
? ? ? ? ? ? ?{
? ? ? ? ? ? ? ? ?// 檢查接收到的數(shù)據(jù)長(zhǎng)度是否合理
? ? ? ? ? ? ? ? ?if(val->vendor_model_srv_Event.trans.len != DELETE_NODE_INFO_DATA_LEN)
? ? ? ? ? ? ? ? ?{
? ? ? ? ? ? ? ? ? ? ?APP_DBG("Delete node info data err!");
? ? ? ? ? ? ? ? ? ? ?return;
? ? ? ? ? ? ? ? ?}
? ? ? ? ? ? ? ? ?// 記錄要?jiǎng)h除信息的地址,并啟動(dòng)一個(gè)任務(wù),延時(shí)執(zhí)行刪除操作
? ? ? ? ? ? ? ? ?delete_node_info_address = val->vendor_model_srv_Event.trans.addr;
? ? ? ? ? ? ? ? ?tmos_start_task(App_TaskID, APP_DELETE_NODE_INFO_EVT, APP_DELETE_NODE_INFO_DELAY);
? ? ? ? ? ? ? ? ?break;
? ? ? ? ? ? ?}
? ? ? ? ? ? ?// 其他情況,不是已知的命令類(lèi)型
? ? ? ? ? ? ?default:
? ? ? ? ? ? ? ? ?APP_DBG("Unknow opcode 0x%02x", val->vendor_model_srv_Hdr.opcode);
? ? ? ? ? ? ? ? ?break;
? ? ? ? ?}
? ? ?}
? ? ?// 如果操作碼表示是寫(xiě)入消息
? ? ?else if(val->vendor_model_srv_Hdr.opcode == OP_VENDOR_MESSAGE_TRANSPARENT_WRT)
? ? ?{
?
? ? ? ? ?// 收到write數(shù)據(jù),打印長(zhǎng)度和來(lái)源地址
? ? ? ? ?APP_DBG("len %d, from 0x%04x", val->vendor_model_srv_Event.write.len, val->vendor_model_srv_Event.write.addr);
?
? ? ? ? ?// 新增:循環(huán)打印完整的數(shù)據(jù)內(nèi)容
? ? ? ? ?for(int i = 0; i < val->vendor_model_srv_Event.write.len; i++) {
? ? ? ? ? ? ?APP_DBG("data[%d] = 0x%02x", i, val->vendor_model_srv_Event.write.pdata[i]);
? ? ? ? ?}
?
? ? ?}
? ? ?// 如果操作碼表示是確認(rèn)消息
? ? ?else if(val->vendor_model_srv_Hdr.opcode == OP_VENDOR_MESSAGE_TRANSPARENT_IND)
? ? ?{
? ? ? ? ?// 發(fā)送的indicate已收到應(yīng)答
? ? ?}
? ? ?// 如果操作碼未知
? ? ?else
? ? ?{
? ? ? ? ?// 打印未知的操作碼信息
? ? ? ? ?APP_DBG("Unknow opcode 0x%02x", val->vendor_model_srv_Hdr.opcode);
? ? ?}
?}
實(shí)驗(yàn)流程及現(xiàn)象:
①燒錄程序到配網(wǎng)器節(jié)點(diǎn)和多個(gè)入網(wǎng)節(jié)點(diǎn)(實(shí)驗(yàn)采用4個(gè)普通節(jié)點(diǎn))中,并將所有節(jié)點(diǎn)連接串口,在串口調(diào)試助手中可以看到入網(wǎng)節(jié)點(diǎn)依次分配地址為2、3、4、5。
。。。
②評(píng)估版按下按鍵S4(對(duì)應(yīng)keyPress為3),實(shí)現(xiàn)配網(wǎng)者節(jié)點(diǎn)向0xFFFF地址的所有入網(wǎng)節(jié)點(diǎn)廣播消息,從而開(kāi)啟各節(jié)點(diǎn)信息傳輸功能。此時(shí)可以在配網(wǎng)者節(jié)點(diǎn)對(duì)應(yīng)的串口調(diào)試助手中看到來(lái)自各個(gè)普通節(jié)點(diǎn)的信息以及彼此之間的RSSI值。同時(shí),在各個(gè)普通節(jié)點(diǎn)對(duì)應(yīng)的串口調(diào)試助手中也可以看到和其他節(jié)點(diǎn)間的數(shù)據(jù)傳輸過(guò)程以及彼此之間的RSSI值。
配網(wǎng)器的串口調(diào)試助手:
入網(wǎng)節(jié)點(diǎn)2的串口調(diào)試助手:
。。。
入網(wǎng)節(jié)點(diǎn)5的串口調(diào)試助手:
疑問(wèn):
問(wèn)題①:存在一個(gè)問(wèn)題,當(dāng)按下按鍵開(kāi)始節(jié)點(diǎn)間通信時(shí),剛開(kāi)始的一段時(shí)間內(nèi)可以看到所有節(jié)點(diǎn)彼此之間都可以通信,但是一段時(shí)間后,入網(wǎng)節(jié)點(diǎn)2會(huì)刪除自身節(jié)點(diǎn),其他節(jié)點(diǎn)間正常通信,請(qǐng)問(wèn)該問(wèn)題是什么原因?qū)е碌?,怎么解決?現(xiàn)象如下所示:
問(wèn)題②: