📄 znwk.c
字号:
#include "zNWK.h"
SM_NWK smNWK; // NWK state machine state
NWK_HEADER nwkCurrentFrame; // Current NWK frame header
NWK_FLAGS _NWKFlags; // NWK module flags
BYTE* NWKPayload;
BYTE* NWKPayloadHead;
BYTE NWKPayloadLength;
BYTE NWKPayloadLengthSave;
////////////////////////////////////
//路由信息
PATH_INFO path_info[MAX_NODE];
PATH_INFO nwk_get_path_info(BYTE dst)
{
return path_info[dst];
}
////////////////////////////////////
static BOOL NWKGetHeader(void);
/*********************************************************************
* Function: void NWKInit(void)
*
* PreCondition: None
*
* Input: None
*
* Output: None
*
* Side Effects: None
*
* Overview: None
*
* Note: None
********************************************************************/
void NWKInit(void)
{
_NWKFlags.Val = 0x00;
// Clear out all NWK flags.
nwkCurrentFrame.Flags.Val = 0x00;
NWKPayload = NULL;
//初始化路由
init_route();
MACInit();
}
/*********************************************************************
* Function: BOOL NWKTask(void)
*
* PreCondition: None
*
* Input: TRUE if task has finished its task
* FALSE, if otherwise
*
* Output: None
*
* Side Effects: None
*
* Overview: None
*
* Note: This function must be called frequently to
* keep NWK layer going.
********************************************************************/
BOOL NWKTask(void)
{
MACTask();
if ( !MACIsGetReady() )
{
return TRUE;
}
if ( nwkCurrentFrame.Flags.bits.bIsInProcess ){
ConsolePutString("nwk data not handled\n");
return TRUE;
}
if ( MACIsData() )
{
if ( macState.bits.bIsAssociated )
{
if ( NWKGetHeader() )
{
if (NWKIsCommand())
{
BYTE command = NWKGet();
switch (command){
case NWK_CMD_ROUTE_REQUEST:
#ifdef route_debug
if (macCurrentFrame.src.shortAddr.Val == 2 && macInfo.shortAddr.Val == 0){
ConsolePutString("filter route request\n");
break;
}
#endif
nwk_proc_rreq( macCurrentFrame.src.shortAddr.Val, (RREQ*) NWKPayload, NWKPayloadLength);
break;
case NWK_CMD_ROUTE_REPLY:
nwk_proc_rrep( macCurrentFrame.src.shortAddr.Val, (RREP*) NWKPayload, NWKPayloadLength);
break;
case NWK_CMD_ROUTE_ERROR:nwk_proc_rerr( macCurrentFrame.src.shortAddr.Val, (RERR*) NWKPayload, NWKPayloadLength);
break;
case NWK_CMD_ROUTE_ACK:nwk_proc_rrep_ack( macCurrentFrame.src.shortAddr.Val, (RREP_ACK*) NWKPayload, NWKPayloadLength);
break;
default:
break;
}
NWKDiscardRx();
}
else if (NWKIsData()){
if (nwkCurrentFrame.destAddr.Val == macInfo.shortAddr.Val){
#ifdef ROUTE_MONITOR
/*
//ConsolePutString("alex");
//ConsolePut(0);
//ConsolePut((BYTE)nwkCurrentFrame.destAddr.byte.MSB+48);
ConsolePut((BYTE)nwkCurrentFrame.destAddr.byte.LSB);
//ConsolePut((BYTE)nwkCurrentFrame.srcAddr.byte.MSB+48);
ConsolePut((BYTE)nwkCurrentFrame.srcAddr.byte.LSB);
BYTE hop_count = NWKGet();
ConsolePut(hop_count);
while(hop_count){
ConsolePut(NWKGet());
hop_count--;
}
ConsolePutString("end");
ConsolePut(0);
*/
ConsolePut(01);
ConsolePut(2);
ConsolePut(03);
ConsolePut(04);
ConsolePut(05);
BYTE metric = NWKGet();
BYTE index = NWKGet();
path_info[index].metric = metric-1;
path_info[index].src = index;
ConsolePut(path_info[index].src);
path_info[index].dst = nwkCurrentFrame.destAddr.byte.LSB;
ConsolePut(nwkCurrentFrame.destAddr.byte.LSB);
metric--;
ConsolePut(metric);
while (metric){
path_info[index].path[path_info[index].metric - metric] = NWKGet();
ConsolePut(path_info[index].path[path_info[index].metric - metric]);
metric--;
ConsolePut(path_info[index].path[path_info[index].metric - metric]);
}
ConsolePut(06);
ConsolePut(7);
ConsolePut(8);
ConsolePut(9);
ConsolePut(10);
#endif
//du 到达数据,由应用层处理
return TRUE;
}
else
{
//du 转发数据
struct Route_Table_Entry *route = lookup_route( nwkCurrentFrame.destAddr.Val);
NWKDiscardRx();
if (route == NULL || !route->flag.bit.is_route_valid)
{
// 不用产生路由错误
}
else
{
macDestInfo.addrMode = MAC_DST_SHORT_ADDR;
macDestInfo.panID = macInfo.panID;
macDestInfo.shortAddr.Val = route->next_ip;
NWKPutHeader(&macDestInfo, NWK_FRAME_DATA | NWK_PROT_VER, 0x00, nwkCurrentFrame.destAddr);
#ifdef ROUTE_MONITOR
BYTE hop_count = NWKGet();
ConsolePut(1);
ConsolePut(2);
ConsolePut(3);
ConsolePut(hop_count);
NWKPut(hop_count+1);
BYTE temp;
while (hop_count){
temp = NWKGet();
NWKPut(temp);
ConsolePut(temp);
hop_count--;
}
NWKPut(macInfo.shortAddr.byte.LSB);
ConsolePut(macInfo.shortAddr.byte.LSB);
ConsolePut(1);
ConsolePut(2);
ConsolePut(3);
#endif
NWKPutArray(NWKPayload, NWKPayloadLength);
HFRAME forward_frame = NWKFlush();
ConsolePut(48+forward_frame);
ConsolePutString("forward data\n");
while (1){
MACTask();
if(MACFrameIsAcked(forward_frame)){
MACFrameRemove(forward_frame);
ConsolePutString("forward send successfully\n");
break;
}
else if(MACFrameIsTimedOut(forward_frame)){
//du 产生路由错误
ConsolePutString("forward send failed\n");
gen_rerr(route->next_ip);
MACFrameRemove(forward_frame);
break;
}
}
}
}
}
}
}
}
return TRUE;
}
/*********************************************************************
* Function: void NWKStartDiscovery(void)
*
* PreCondition: None
*
* Input: None
*
* Output: None
*
* Side Effects: None
*
* Overview: Starts network discovery process
*
* Note: Available for coorindator only.
********************************************************************/
void NWKStartDiscovery(void)
{
MACSetFirstChannel();
smNWK = SM_NWK_ENERGY_SCAN;
_NWKFlags.bits.bIsNWKDiscovered = FALSE;
ConsolePutString("NWK: NWKStartDiscovery() \n");
}
/*********************************************************************
* Function: BOOL NWKIsDiscoveryComplete(void)
*
* PreCondition: NWKStartDiscovery() is called
*
* Input: None
*
* Output: TRUE, if complete
* FALSE otherwise
* Use GetZError() to check for error.
*
* Side Effects: None
*
* Overview: Performs network discovery process.
*
* Note: None
********************************************************************/
BOOL NWKIsDiscoveryComplete(void)
{
BYTE energy;
switch(smNWK)
{
case SM_NWK_ENERGY_SCAN:
// Check with application to see if this channel should be used.
// If application does not want to use this channel, we will stay in this state
// and next channel will be selected.
if ( !AppOkayToUseChannel(MACGetChannel()) )
{
smNWK = SM_NWK_NEXT_CHANNEL;
break;
}
MACStartED();
smNWK = SM_NWK_ENERGY_SCAN_WAIT;
break;
case SM_NWK_NEXT_CHANNEL:
if ( !MACSetNextChannel() )
{
ConsolePutString("NWK: NWKIsDiscoveryComplete(): No channel is free.\r\n");
SetZError(ZCODE_CHANNEL_BUSY);
PHYSetTRXState(PHY_TRX_OFF);
return TRUE;
}
smNWK = SM_NWK_ENERGY_SCAN;
break;
case SM_NWK_ENERGY_SCAN_WAIT:
if ( MACIsEDComplete() )
{
energy = MACGetEDValue();
MACStartScan(TRUE);
smNWK = SM_NWK_ACTIVE_SCAN_WAIT;
}
break;
case SM_NWK_ACTIVE_SCAN_WAIT:
if ( MACIsScanComplete() )
{
if ( MACIsPANAvailable() )
{
ConsolePutString("NWK: NWKIsDiscoveryComplete(): A network is found.\r\n");
_NWKFlags.bits.bIsNWKDiscovered = TRUE;
}
else
_NWKFlags.bits.bIsNWKDiscovered = FALSE;
// Depending on whether this is coordinator or end device,
// this function may get called to continue scanning next available channel.
// A coordinator would want to scan for empty channel. If no network is discovered,
// coordinator may form network and may not call this function again.
// An end device needs to find an occupied channel. If no network is discovered,
// end device would continue to scan and see if it can find a busy channel. In
// that case, this function will be called again.
// In any case, set the next state to NEXT_CHANNEL so that if this function is called
// agian, it will switch to next channel and continue the discovery.
SetZError(ZCODE_NO_ERROR);
smNWK = SM_NWK_NEXT_CHANNEL;
PHYSetTRXState(PHY_TRX_OFF);
return TRUE;
}
break;
}
return FALSE;
}
/*********************************************************************
* Function: void NWKPutHeader(NODE_INFO *dest,
* BYTE frameCONLSB,
* BYTE frameCONMSB)
*
* PreCondition: NWKIsPutReady() = TRUE
*
* Input: dest - Dest node
* frameCONLSB - NWK frame header control LSB
* frameCONMSB - NWK frame header control MSB
*
* Output: None
*
* Side Effects: None
*
* Overview: Prepares NWK frame header and loads it in XCVR
*
* Note: None
********************************************************************/
void NWKPutHeader(NODE_INFO *dest,
BYTE frameCONLSB,
BYTE frameCONMSB,
SHORT_ADDR dest_nwk_addr)
{
macInfo.addrMode = MAC_SRC_SHORT_ADDR;
//du 如果是广播
if(dest->shortAddr.Val==0xFFFF)
{
MACPutHeader(dest,
MAC_FRAME_DATA |
MAC_SECURITY |
MAC_FRAME_PENDING_NO |
MAC_ACK_NO |
MAC_INTRA_PAN_YES);
}
else
{
MACPutHeader(dest,
MAC_FRAME_DATA |
MAC_SECURITY |
MAC_FRAME_PENDING_NO |
MAC_ACK_YES |
MAC_INTRA_PAN_YES);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -