采用三個藍牙節(jié)點,使用自配網(wǎng)例程。
節(jié)點2收到1的消息后轉(zhuǎn)發(fā)給節(jié)點3,但是有個問題是:節(jié)點1發(fā)送兩次消息,節(jié)點1第一次消息發(fā)送后,節(jié)點2收到消息后打印,節(jié)點3卻沒有收到并打印,節(jié)點1發(fā)送第二次消息后,節(jié)點3才收到節(jié)點1第一次發(fā)送的消息。
代碼如下:
? ?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;
? ? ? ? // 當接收到來自0x0001節(jié)點的信息后,會向0x0003節(jié)點發(fā)送信息
? ? ? ? if(ctx->addr==0x0001)
? ? ? ? {
? ? ? ? ? ? // 自定義隨機數(shù)據(jù)發(fā)送版本
? ? ? ? ? ? uint8_t *received_data = val->vendor_model_srv_Event.trans.pdata;
? ? ? ? ? ? int len = val->vendor_model_srv_Event.trans.len;
? ? ? ? ? ? if(len >= 4)? // 假設(shè)數(shù)據(jù)至少有4字節(jié)
? ? ? ? ? ? {
? ? ? ? ? ? ? ? // 解析數(shù)據(jù)
? ? ? ? ? ? ? ? char dataStr[254];
? ? ? ? ? ? ? ? int offset = sprintf(dataStr, "data={");
? ? ? ? ? ? ? ? for(int i = 0; i < len; i++) {
? ? ? ? ? ? ? ? ? ? offset += sprintf(dataStr + offset, "%d", received_data[i]);
? ? ? ? ? ? ? ? ? ? if(i < len - 1)
? ? ? ? ? ? ? ? ? ? ? ? offset += sprintf(dataStr + offset, ",");
? ? ? ? ? ? ? ? }
? ? ? ? ? ? ? ? sprintf(dataStr + offset, "},src:0x%04x", ctx->addr);
? ? ? ? ? ? ? ? APP_DBG("%s\n", dataStr);
? ? ? ? ? ? ? ? // 發(fā)送數(shù)據(jù)
? ? ? ? ? ? ? ? uint8_t status = vendor_model_srv_send(0x0003, received_data, len);
? ? ? ? ? ? ? ? if(status)
? ? ? ? ? ? ? ? ? ? APP_DBG("trans failed %d", status);
? ? ? ? ? ? }
? ? ? ? ? ? else
? ? ? ? ? ? {
? ? ? ? ? ? ? ? APP_DBG("Received data is too short.");
? ? ? ? ? ? }
? ? ? ? ? ? // 休眠處理
? ? ? ? ? ? PRINT("sleep mode sleep \n");
? ? ? ? ? ? tmos_stop_task(halTaskID, HAL_REG_INIT_EVENT);? //默認2分鐘一次的校準先暫停
? ? ? ? ? ? DelayMs(5);
? ? //? ? ? ? RTC_TMRFunCfg(Period_16_S);/* 定時1s的RTC鬧鐘 */
? ? ? ? ? ? RTC_TRIGFunCfg(32768*10);
? ? ? ? ? ? PWR_PeriphWakeUpCfg(ENABLE, RB_SLP_RTC_WAKE, Long_Delay);/* 使能RTC中斷喚醒源 */
? ? ? ? ? ? PFIC_EnableIRQ(RTC_IRQn);/* 使能RTC中斷 */
? ? ? ? ? ? /* 注意當主頻為80M時,Sleep睡眠喚醒中斷不可調(diào)用flash內(nèi)代碼 */
//? ? ? ? ? ? LowPower_Idle();
//? ? ? ? ? ? LowPower_Halt();
? ? ? ? ? ? LowPower_Sleep(RB_PWR_RAM30K | RB_PWR_RAM2K); /* 只保留30+2K SRAM 供電 */
//? ? ? ? ? ? LowPower_Shutdown(0);
? ? ? ? ? ? HSECFG_Current(HSE_RCur_100); /* 降為額定電流(低功耗函數(shù)中提升了HSE偏置電流) */
? ? ? ? ? ? PFIC_DisableIRQ(RTC_IRQn);
? ? ? ? ? ? DelayMs(5);
? ? ? ? ? ? PRINT("wake.. \n");
? ? ? ? ? ? DelayMs(20);
? ? ? ? ? ? tmos_set_event(halTaskID, HAL_REG_INIT_EVENT);? ? ? //先校準RF,再開廣播
? ? ? ? }
? ? ? ? // 當接收到來自0x0003節(jié)點的信息pdata后,會向0x0001節(jié)點發(fā)送該pdata信息
? ? ? ? if(ctx->addr==0x0003)
? ? ? ? {
? ? ? ? ? ? // 確保接收到的數(shù)據(jù)長度至少為5個字節(jié)
? ? ? ? ? ? if(val->vendor_model_srv_Event.trans.len >= 5) {
? ? ? ? ? ? ? ? // 解析數(shù)據(jù)
? ? ? ? ? ? ? ? uint16_t src_addr = val->vendor_model_srv_Event.trans.pdata[0] + (val->vendor_model_srv_Event.trans.pdata[1] << 8);
? ? ? ? ? ? ? ? uint16_t my_addr = val->vendor_model_srv_Event.trans.pdata[2] + (val->vendor_model_srv_Event.trans.pdata[3] << 8);
? ? ? ? ? ? ? ? int8_t rssi = val->vendor_model_srv_Event.trans.pdata[4];
? ? ? ? ? ? ? ? // 打印解析后的數(shù)據(jù)
? ? ? ? ? ? ? ? APP_DBG("src: 0x%04x, my_addr: 0x%04x, rssi: %d", src_addr, my_addr, rssi);
? ? ? ? ? ? ? ? // 將該解析數(shù)據(jù)pdata發(fā)送給0x0001
? ? ? ? ? ? ? ? uint8_t status;
? ? ? ? ? ? ? ? // 準備要發(fā)送的數(shù)據(jù)
? ? ? ? ? ? ? ? uint8_t sendData[5]; // 2 bytes for src_addr, 2 bytes for my_addr, and 1 byte for rssi
? ? ? ? ? ? ? ? // 打包數(shù)據(jù)
? ? ? ? ? ? ? ? // 注意: 這里假設(shè)系統(tǒng)為小端字節(jié)序,如果是大端字節(jié)序需要調(diào)整
? ? ? ? ? ? ? ? memcpy(sendData, &src_addr, 2); // 復制ctx->addr
? ? ? ? ? ? ? ? memcpy(sendData + 2, &my_addr, 2); // 復制my_addr
? ? ? ? ? ? ? ? // 由于rssi是int8_t,直接將其值賦給數(shù)組的相應(yīng)位置
? ? ? ? ? ? ? ? sendData[4] = rssi; // 復制ctx->recv_rssi
? ? ? ? ? ? ? ? status=vendor_model_srv_send(0x0001,sendData,sizeof(sendData));
? ? ? ? ? ? ? ? if(status) // 如果發(fā)送失敗,打印錯誤狀態(tài)
? ? ? ? ? ? ? ? ? ? APP_DBG("trans failed %d", status);
? ? ? ? ? ? } else {
? ? ? ? ? ? ? ? APP_DBG("Received data is too short.");
? ? ? ? ? ? }
? ? ? ? }