📄 nwk.i
字号:
*******************************************************************************************************/
//-------------------------------------------------------------------------------------------------------
extern CC2420_RX_INFO rfRxInfo;
extern CC2420_TX_INFO rfTxInfo;
extern unsigned char pTxBuffer[(127 - ((2 + 1 + 2 + 2 + 2) + (2)))];
extern unsigned char pRxBuffer[(127 - ((2 + 1 + 2 + 2 + 2) + (2)))];
//-------------------------------------------------------------------------------------------------------
/***********************************************************************
* 创建网络 (仅对协调器节点有效 )
************************************************************************/
void nwk_CreatNetwork(void)
{
MAC_Init();
nwk_Addr_Assign_Init();
}
/***********************************************************************
* 初始化地址分配表 (仅对协调器节点有效 )
************************************************************************/
void nwk_Addr_Assign_Init(void)
{
unsigned char i;
//addrTableList[0].ShortAddr = 43776;
//addrTableList[0].Avail = 0x01; // 地址允许分配
for(i=0;i<20 ;i++)
{
addrTableList[i].ShortAddr = i+1;
addrTableList[i].Avail = 0x01; // 地址允许分配
}
}
/***********************************************************************
* 检查地址分配表是否有未分配的地址 (仅对协调器节点有效 )
* 如果有,则返回地址分配表中第一个可用地址的下标,没有则返回0xFF
************************************************************************/
unsigned char nwk_Addr_Assign_Check(void)
{
unsigned char i;
for(i=0;i<20 ;i++)
{
if(addrTableList[i].Avail == 0x01) // 地址允许分配
{
return i;
}
}
return 0xFF;
}
/***********************************************************************
* 检查地址分配表是否有指定地址存在 (仅对协调器节点有效 )
* 如果有,则返回地址分配表中此地址的下标,没有则返回0xFF
************************************************************************/
unsigned char nwk_Addr_Assign_Check_Addr(unsigned int addr)
{
unsigned char i;
for(i=0;i<20 ;i++)
{
if(addrTableList[i].ShortAddr == addr) // 地址允许分配
{
return i;
}
}
return 0xFF;
}
/***********************************************************************
* 检查邻居表是否有空的 (仅对协调器节点有效 )
* 如果有,则返回地址分配表中第一个的下标,没有则返回0xFF
************************************************************************/
unsigned char nwk_NeighborTable_Check(void)
{
unsigned char i;
for(i=0;i<20 ;i++)
{
if(neighbor[i].Avail == 0x00)
{
return i;
}
}
return 0xFF;
}
/***********************************************************************
* 检查IEEE地址是否在邻居表中 (仅对协调器节点有效 )
* ieeeAddr :要查询的地址的指针
* 如果找到则返回下标,没有则返回0xFF
************************************************************************/
unsigned char nwk_IEEEIsInNeighborTable_Check(unsigned char *ieeeAddr)
{
unsigned char i;
unsigned char *ieeeAddr_temp;
for(i=0;i<20 ;i++)
{
ieeeAddr_temp = ieeeAddr;
if(
(neighbor[i].IEEEAddr[0] == *ieeeAddr_temp++)&&
(neighbor[i].IEEEAddr[1] == *ieeeAddr_temp++)&&
(neighbor[i].IEEEAddr[2] == *ieeeAddr_temp++)&&
(neighbor[i].IEEEAddr[3] == *ieeeAddr_temp++)&&
(neighbor[i].IEEEAddr[4] == *ieeeAddr_temp++)&&
(neighbor[i].IEEEAddr[5] == *ieeeAddr_temp++)&&
(neighbor[i].IEEEAddr[6] == *ieeeAddr_temp++)&&
(neighbor[i].IEEEAddr[7] == *ieeeAddr_temp)
)return i;
}
return 0xFF;
}
/***********************************************************************
* 删除邻居表中指定的地址 (仅对协调器节点有效 )
* shortAddr :要删除的地址的指针
************************************************************************/
unsigned char nwk_DeleteNeighborTable(unsigned int shortAddr)
{
unsigned char i,j,k=0;
for(i=0;i<20 ;i++)
{
if( neighbor[i].ShortAddr == shortAddr )
{
nwk_Send_neighbortable_to_PC(i,0x02); //向PC机发送
PORTD ^= (1<<7 ) ;
neighbor[i].Avail = '';
for(j=0;j<8;j++)
{
neighbor[i].IEEEAddr[j] = '';
}
neighbor[i].ShortAddr = '';
neighbor[i].DeviceType = '';
neighbor[i].Relationship = '';
k = nwk_Addr_Assign_Check_Addr(shortAddr); //检查地址分配表中是否有此地址,如果有则把此地址设置为可分配
if( k != 0xFF )
{
addrTableList[k].Avail = 0x01;
}
return i;
}
}
return 0xFF;
}
/***********************************************************************
* 允许其他节点加入网络 (仅对协调器节点有效 )
************************************************************************/
void nwk_PermitJoinIn(void)
{
flag_PermitJoinIn = 0x01;
}
/***********************************************************************
* 加入网络 (仅对终端节点有效 )
************************************************************************/
void nwk_JoinInNetwork(void)
{
unsigned char i;
MAC_Init();
nwk_FCF = 0x02;
nwk_RequestOrAck = 0x01;
nwk_CmdTypes = 0x01 ;
rfTxInfo.destAddr = 0x1234; // 发送的目的地址
rfTxInfo.length = 0x05; // 要发送消息内容的长度
rfTxInfo.ackRequest = 0; // 不要求返回确认
pTxBuffer[0] = nwk_FCF;
pTxBuffer[1] = nwk_RequestOrAck;
pTxBuffer[2] = nwk_CmdTypes;
pTxBuffer[3] = 0x11;
pTxBuffer[4] = 0x03;
CC2420_SendPacket(&rfTxInfo,0x02);
// 等待一段时间看看有没有加入成功,有没有获得 16 bit 短地址
delay_ms(1000);
if(rfSettings.JoinNetworkSuccess) // 加入成功 ,通知协调器加入成功
{
nwk_CmdTypes = 0x03 ;
rfTxInfo.destAddr = 0x1234; // 发送的目的地址
rfTxInfo.length = 0x011; // 要发送消息内容的长度
rfTxInfo.ackRequest = 0; // 不要求返回确认
pTxBuffer[0] = nwk_FCF;
pTxBuffer[1] = nwk_RequestOrAck;
pTxBuffer[2] = nwk_CmdTypes;
for(i=0;i<8;i++) // 自己的IEEE地址
{
pTxBuffer[i+3] = rfSettings.myIEEE[i];
}
CC2420_SendPacket(&rfTxInfo,0x01);
Sleep();//休眠模式:掉电模式
}
}
/***********************************************************************
* 加入网络请求的应答 (仅对协调器节点有效 )
* 地址分配表中可分配的地址的下标,如果没有则其值为0xFF
************************************************************************/
void nwk_JoinInNetwork_ACK(unsigned char flage,unsigned char addrlistID,unsigned char neighbortable_tempID)
{
unsigned char i;
unsigned char NeighborTableID;
nwk_FCF = 0x02;
nwk_RequestOrAck = 0x02;
nwk_CmdTypes = 0x01 ;
for(i=0;i<8;i++)
{
rfTxInfo.destIEEE[i] = rfSettings.pRxInfo->srcIEEE[i]; // 发送的目的地址
}
rfTxInfo.ackRequest = 0; // 不要求返回确认
pTxBuffer[0] = nwk_FCF;
pTxBuffer[1] = nwk_RequestOrAck;
pTxBuffer[2] = nwk_CmdTypes;
if(!flage)
{
if( addrlistID == 0xFF ) // 没有可分配地址
{
pTxBuffer[3] = 0x01; // 没有可分配地址
rfTxInfo.length = 0x04; // 要发送消息内容的长度
}
else // 有可分配地址
{
pTxBuffer[3] = 0x02; // 有可分配地址
pTxBuffer[4] = addrTableList[addrlistID].ShortAddr & 0x00FF;
pTxBuffer[5] = ( addrTableList[addrlistID].ShortAddr >> 8 );
rfTxInfo.length = 0x06; // 要发送消息内容的长度
addrTableList[addrlistID].Avail = 0x00; // 地址分配表中的这个地址设置为已经被分配
NeighborTableID = nwk_NeighborTable_Check();
for(i=0;i<8;i++)
{
neighbor[NeighborTableID].IEEEAddr[i] = rfSettings.pRxInfo->srcIEEE[i];
}
}
}
else
{
pTxBuffer[3] = 0x02; // 有可分配地址
pTxBuffer[4] = neighbor[neighbortable_tempID].ShortAddr & 0x00FF;
pTxBuffer[5] = ( neighbor[neighbortable_tempID].ShortAddr >> 8 );
rfTxInfo.length = 0x06; // 要发送消息内容的长度
}
CC2420_SendPacket(&rfTxInfo,0x03);
}
/***********************************************************************
* 离开网络 (仅对终端节点有效 )
************************************************************************/
void nwk_LeaveNetwork(void)
{
nwk_FCF = 0x02;
nwk_RequestOrAck = 0x01;
nwk_CmdTypes = 0x02 ;
rfTxInfo.destAddr = 0x1234; // 发送的目的地址
rfTxInfo.length = 0x03; // 求取要发送消息内容的长度
rfTxInfo.ackRequest = 0; // 不要求返回确认
pTxBuffer[0] = nwk_FCF;
pTxBuffer[1] = nwk_RequestOrAck;
pTxBuffer[2] = nwk_CmdTypes;
CC2420_SendPacket(&rfTxInfo,0x01);
// 等待一段时间看看有没有离开成功
delay_ms(1000);
if(!rfSettings.JoinNetworkSuccess) // 离开网络成功 ,通知协调器离开成功
{
nwk_CmdTypes = 0x04 ;
rfTxInfo.destAddr = 0x1234; // 发送的目的地址
rfTxInfo.length = 0x03; // 要发送消息内容的长度
rfTxInfo.ackRequest = 0; // 不要求返回确认
pTxBuffer[0] = nwk_FCF;
pTxBuffer[1] = nwk_RequestOrAck;
pTxBuffer[2] = nwk_CmdTypes;
CC2420_SendPacket(&rfTxInfo,0x01);
CC2420_SetShortAddress(0x0000);
}
}
/***********************************************************************
* 离开网络的应答 (仅对协调器节点有效 )
************************************************************************/
void nwk_LeaveNetwork_ACK(void)
{
nwk_FCF = 0x02;
nwk_RequestOrAck = 0x02;
nwk_CmdTypes = 0x02 ;
rfTxInfo.destAddr = rfSettings.pRxInfo->srcAddr; // 发送的目的地址
rfTxInfo.length = 0x04;
rfTxInfo.ackRequest = 0; // 不要求返回确认
pTxBuffer[0] = nwk_FCF;
pTxBuffer[1] = nwk_RequestOrAck;
pTxBuffer[2] = nwk_CmdTypes;
pTxBuffer[3] = 0x01; //同意脱离网络
CC2420_SendPacket(&rfTxInfo,0x01);
}
/***********************************************************************
* 网络层打包函数
************************************************************************/
void nwk_PackData(unsigned char *pPayload, unsigned char length)
{
unsigned char i=0;
nwk_FCF = 0x01;
pTxBuffer[0] = nwk_FCF;
for(i=0;i<length;i++)
{
pTxBuffer[i+1] = *pPayload++;
}
rfTxInfo.length = length+1; // 要发送消息内容的长度
rfTxInfo.ackRequest = 0; // 不要求返回确认
CC2420_SendPacket(&rfTxInfo,0x01);
}
/***********************************************************************
* 网络层解包函数
************************************************************************/
void nwk_UnPackData(unsigned char *pPayload, unsigned char length)
{
unsigned char temp0,temp1,temp2,temp3;
unsigned char addrlist_temp;
unsigned char neighborID_temp;
temp0 = *pPayload++;
switch (temp0)
{
case 0x01:
{
app_UnPackData(pPayload,length-1); // 调用应用层解包
break;
}
case 0x02: // 网络层命令
{
temp1 = *pPayload++;
switch (temp1)
{
case 0x01: // 请求命令
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -