FreakZ路由應(yīng)答機(jī)制
路由應(yīng)答機(jī)制是建立在路由發(fā)現(xiàn)和路由請求完成之后進(jìn)行的恰矩,換句話說就是在通信鏈路建立完成之后记盒,幀信息被傳輸?shù)侥康墓?jié)點(diǎn)時(shí)憎蛤,由目的節(jié)點(diǎn)進(jìn)行的應(yīng)答機(jī)制;路由應(yīng)答機(jī)制在NWK.c下的mac_data_ind函數(shù)被調(diào)用,該函數(shù)的功能在另一篇文章《FreakZ學(xué)習(xí)筆記:接收過程詳解》中有解釋俩檬,這里不再贅述萎胰;相應(yīng)代碼如下:
switch (cmd.cmd_frm_id)
?????? ?{
??????? case NWK_CMD_RTE_REQ:
?????????? ?if(nib.dev_type != NWK_END_DEVICE)//Added by LiuTianmin
??????????? {???
??????????????? nwk_rte_mesh_rreq_handler(&hdr, &cmd);
??????????? }
??????????? break;
?????? ?case NWK_CMD_RTE_REP:
??????????? if(nib.dev_type != NWK_END_DEVICE)//Added by LiuTianmin
??????????? {?
??????????????? nwk_rte_mesh_rrep_handler(&hdr, &cmd);
??????????? }
??????????? break;
??????? case NWK_CMD_LEAVE:
??????????? nwk_leave_handler(&hdr, &cmd);
??????????? break;
??????? default:
??????????? break;
??????? }
這里的switch語句會(huì)分別對路由請求和路由應(yīng)答的ID進(jìn)行判斷,如果節(jié)點(diǎn)類型為終端節(jié)點(diǎn)的話棚辽,即執(zhí)行相應(yīng)的路由請求函數(shù)nwk_rte_mesh_rreq_handler或路由應(yīng)答函數(shù)nwk_rte_mesh_rrep_handler技竟。
路由應(yīng)答函數(shù)nwk_rte_mesh_rrep_handler的主要功能是處理傳入的路由線路并確定是否需要路由應(yīng)答;首先屈藐,需要確保本次路由應(yīng)答有一個(gè)對應(yīng)的發(fā)現(xiàn)表和路由表榔组,如果沒有,那么丟棄回復(fù)路線灭翔,同樣驶沼,如果路徑的成本比目前發(fā)現(xiàn)路由表里保存的鏈路成本高的話介劫,同樣放棄回復(fù)路線直到有一個(gè)更高效率的鏈路建立。如果這條路由應(yīng)答是給當(dāng)前鏈路的锨推,那么結(jié)束路由發(fā)現(xiàn)過程并發(fā)送路由應(yīng)答,否則公壤,在前進(jìn)的路由回復(fù)中更新記錄路由請求的發(fā)現(xiàn)表换可。代碼原型如下:
void nwk_rte_mesh_rrep_handler(const nwk_hdr_t *hdr_in, const nwk_cmd_t *cmd_in)
{
??? nwk_pcb_t *pcb = nwk_pcb_get();
??? nwk_nib_t *nib = nwk_nib_get();
??? mem_ptr_t *disc_mem_ptr;
??? mem_ptr_t *rte_mem_ptr;
??? U8 path_cost;
??? disc_mem_ptr? = nwk_rte_disc_find(cmd_in->rrep.rreq_id, cmd_in->rrep.originator);
??? rte_mem_ptr?? = nwk_rte_tbl_find(cmd_in->rrep.responder);
??? path_cost?? = cmd_in->rrep.path_cost + NWK_STATIC_PATH_COST;
??? // if the rte entry or discovery entry doesn't exist or the path cost is not less than the current resid cost, then drop
??? // the rrep.
?? ?if ((!rte_mem_ptr) || (!disc_mem_ptr) || (path_cost >= DISC_ENTRY(disc_mem_ptr)->resid_cost))
??? {
??????? if (!rte_mem_ptr || !disc_mem_ptr)
??????? {///????????這里似乎有問題
??????????? nwk_rte_tbl_free(rte_mem_ptr);
??????????? nwk_rte_disc_free(disc_mem_ptr);
??????? }
??????? pcb->drop_rrep_frm++;
??????? return;
??? }
??? // we've met all the criteria to keep the rrep. that means we should update the rrep and disc entry.
??? // any time we update the next hop in the rte entry, we need to reset the discovery entry's expiry
??? DISC_ENTRY(disc_mem_ptr)->resid_cost? = path_cost;
??? DISC_ENTRY(disc_mem_ptr)->expiry????? = NWK_RTE_DISC_TIME;
??? RTE_ENTRY(rte_mem_ptr)->next_hop????? = hdr_in->mac_hdr->src_addr.short_addr;
??? // update the entry to validation underway. once we send an actual frame through it, then we can change
??? // it to NWK_VALIDATION_UNDERWAY.
??? RTE_ENTRY(rte_mem_ptr)->status = (RTE_ENTRY(rte_mem_ptr)->status == NWK_DISCOVERY_UNDERWAY) ?
????????????????????????????????????? NWK_VALIDATION_UNDERWAY :
????????????????????????????????????? RTE_ENTRY(rte_mem_ptr)->status;
??? // check if the rrep is meant for us.
?? ?if (cmd_in->rrep.originator == nib->short_addr)
??? {
??????? /*We should remove the roter request from req_list added by LiuTianmin*/
??????? mem_ptr_t *mem_ptr;
??????? mem_ptr = nwk_rte_mesh_rreq_find(nib->short_addr,cmd_in->rrep.responder);
??????? nwk_rte_mesh_rreq_free(mem_ptr);
??????? /*We should remove the roter request from req_list added by LiuTianmin*/
??????? // send out pending xfers
??????? nwk_pend_send_pending();
??????? DBG_PRINT("\nNWK_RTE_MESH: Route established.\n");
??????? return;
??? }
??? // forward the route reply
?? ?nwk_rte_mesh_send_rrep(cmd_in->rrep.rreq_id, cmd_in->rrep.originator, cmd_in->rrep.responder,
?????????????????????????? path_cost, DISC_ENTRY(disc_mem_ptr)->sender_addr);
}
nwk_rte_mesh_send_rrep為發(fā)送路由應(yīng)答函數(shù),原型如下:
static void nwk_rte_mesh_send_rrep(U8 rreq_id, U16 originator, U16 responder, U8 path_cost, U16 sender_addr)
{
??? nwk_nib_t *nib = nwk_nib_get();
??? nwk_hdr_t hdr;
??? nwk_cmd_t cmd;
??? buffer_t *buf;
??? cmd.cmd_frm_id????????????? = NWK_CMD_RTE_REP;
??? cmd.rrep.cmd_opts?????????? = 0x00;
??? cmd.rrep.rreq_id??????????? = rreq_id;
??? cmd.rrep.originator???? ????= originator;
??? cmd.rrep.responder????????? = responder;
??? cmd.rrep.path_cost????????? = path_cost;
??? hdr.nwk_frm_ctrl.frame_type = NWK_CMD_FRM;
??? hdr.nwk_frm_ctrl.disc_route = false;
??? hdr.src_addr??????????????? = nib->short_addr;
??? hdr.dest_addr?????????????? = sender_addr;
??? hdr.radius????????????????? = (U8)(nib->max_depth << 1);
??? hdr.seq_num???????????????? = nib->seq_num;
??? BUF_ALLOC(buf, TX);
??? nwk_gen_cmd(buf, &cmd);
??? debug_dump_nwk_cmd(&cmd);
??? //nwk_fwd(buf, &hdr);?? //Delete by LiuTianmin
??? /*I think here should respone direct to the sender*/
??? mac_hdr_t mac_hdr_out;
??? buf->len = aMaxPHYPacketSize - (buf->dptr - buf->buf);
??? hdr.mac_hdr???????? = &mac_hdr_out;
??? hdr.mac_hdr->src_addr.mode????????? = SHORT_ADDR;
??? hdr.mac_hdr->dest_addr.mode???????? = SHORT_ADDR;
??? hdr.mac_hdr->src_addr.short_addr??? = nib->short_addr;
??? hdr.mac_hdr->dest_addr.short_addr?? = hdr.dest_addr;
? ??nwk_tx(buf, &hdr, false);
}
當(dāng)路由應(yīng)答產(chǎn)生之后厦幅,會(huì)通過nwk_tx函數(shù)將該路由應(yīng)答由NWK層傳遞到MAC層沾鳄,通過MAC層到達(dá)Radio層,然后將應(yīng)答信息發(fā)送确憨。