📄 nwk.c
字号:
#include "nwk.h"
#include "mac.h"
#include "mcu.h"
#include "config.h"
#include "compiler.h"
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
unsigned char nwk_TxBuffer[NWK_MAX_PAYLOAD_SIZE];
unsigned char nwk_RxBuffer[NWK_MAX_PAYLOAD_SIZE];
NeighborTable neighbor[MAX_NEIGHBORTABLE]; //邻居表
AddrTable addrTableList[MAX_ADDRTABLE]; //地址分配表
unsigned char flag_PermitJoinIn=0x00;
//************************** NWK FrameHeader ***************************
unsigned char nwk_FCF;
unsigned char nwk_RequestOrAck;
unsigned char nwk_CmdTypes;
//**********************************************************************
unsigned char nwk_DeviceTypes;
/*******************************************************************************************************
************************** mac.h 中的变量 **************************
*******************************************************************************************************/
//-------------------------------------------------------------------------------------------------------
extern CC2420_RX_INFO rfRxInfo;
extern CC2420_TX_INFO rfTxInfo;
extern unsigned char pTxBuffer[CC2420_MAX_PAYLOAD_SIZE];
extern unsigned char pRxBuffer[CC2420_MAX_PAYLOAD_SIZE];
//-------------------------------------------------------------------------------------------------------
/***********************************************************************
* 创建网络 (仅对协调器节点有效 )
************************************************************************/
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<MAX_ADDRTABLE;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<MAX_ADDRTABLE;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<MAX_ADDRTABLE;i++)
{
if(addrTableList[i].ShortAddr == addr) // 地址允许分配
{
return i;
}
}
return 0xFF;
}
/***********************************************************************
* 检查邻居表是否有空的 (仅对协调器节点有效 )
* 如果有,则返回地址分配表中第一个的下标,没有则返回0xFF
************************************************************************/
unsigned char nwk_NeighborTable_Check(void)
{
unsigned char i;
for(i=0;i<MAX_ADDRTABLE;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<MAX_NEIGHBORTABLE;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<MAX_NEIGHBORTABLE;i++)
{
if( neighbor[i].ShortAddr == shortAddr )
{
nwk_Send_neighbortable_to_PC(i,0x02); //向PC机发送
WLED_TOGGLE();
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 = NWK_FCF_CMD;
nwk_RequestOrAck = NWK_REQUEST;
nwk_CmdTypes = NWK_CMD_REQUESTJIONIN;
rfTxInfo.destAddr = COORDINATOR_ADDR; // 发送的目的地址
rfTxInfo.length = 0x05; // 要发送消息内容的长度
rfTxInfo.ackRequest = FALSE; // 不要求返回确认
pTxBuffer[0] = nwk_FCF;
pTxBuffer[1] = nwk_RequestOrAck;
pTxBuffer[2] = nwk_CmdTypes;
pTxBuffer[3] = JION_TO_NETWORK_PASSWORD;
pTxBuffer[4] = I_Am_What;
CC2420_SendPacket(&rfTxInfo,0x02);
// 等待一段时间看看有没有加入成功,有没有获得 16 bit 短地址
delay_ms(1000);
if(rfSettings.JoinNetworkSuccess) // 加入成功 ,通知协调器加入成功
{
nwk_CmdTypes = NWK_CMD_JIONINSUCCESSFUL;
rfTxInfo.destAddr = COORDINATOR_ADDR; // 发送的目的地址
rfTxInfo.length = 0x011; // 要发送消息内容的长度
rfTxInfo.ackRequest = FALSE; // 不要求返回确认
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 = NWK_FCF_CMD;
nwk_RequestOrAck = NWK_ACK;
nwk_CmdTypes = NWK_CMD_REQUESTJIONIN;
for(i=0;i<8;i++)
{
rfTxInfo.destIEEE[i] = rfSettings.pRxInfo->srcIEEE[i]; // 发送的目的地址
}
rfTxInfo.ackRequest = FALSE; // 不要求返回确认
pTxBuffer[0] = nwk_FCF;
pTxBuffer[1] = nwk_RequestOrAck;
pTxBuffer[2] = nwk_CmdTypes;
if(!flage)
{
if( addrlistID == 0xFF ) // 没有可分配地址
{
pTxBuffer[3] = NWK_NO_ADDR_ASSIGN; // 没有可分配地址
rfTxInfo.length = 0x04; // 要发送消息内容的长度
}
else // 有可分配地址
{
pTxBuffer[3] = NWK_ADDR_ASSIGN; // 有可分配地址
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] = NWK_ADDR_ASSIGN; // 有可分配地址
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 = NWK_FCF_CMD;
nwk_RequestOrAck = NWK_REQUEST;
nwk_CmdTypes = NWK_CMD_REQUESTLEAVE;
rfTxInfo.destAddr = COORDINATOR_ADDR; // 发送的目的地址
rfTxInfo.length = 0x03; // 求取要发送消息内容的长度
rfTxInfo.ackRequest = FALSE; // 不要求返回确认
pTxBuffer[0] = nwk_FCF;
pTxBuffer[1] = nwk_RequestOrAck;
pTxBuffer[2] = nwk_CmdTypes;
CC2420_SendPacket(&rfTxInfo,0x01);
// 等待一段时间看看有没有离开成功
delay_ms(1000);
if(!rfSettings.JoinNetworkSuccess) // 离开网络成功 ,通知协调器离开成功
{
nwk_CmdTypes = NWK_CMD_LEAVESUCCESSFUL;
rfTxInfo.destAddr = COORDINATOR_ADDR; // 发送的目的地址
rfTxInfo.length = 0x03; // 要发送消息内容的长度
rfTxInfo.ackRequest = FALSE; // 不要求返回确认
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 = NWK_FCF_CMD;
nwk_RequestOrAck = NWK_ACK;
nwk_CmdTypes = NWK_CMD_REQUESTLEAVE;
rfTxInfo.destAddr = rfSettings.pRxInfo->srcAddr; // 发送的目的地址
rfTxInfo.length = 0x04;
rfTxInfo.ackRequest = FALSE; // 不要求返回确认
pTxBuffer[0] = nwk_FCF;
pTxBuffer[1] = nwk_RequestOrAck;
pTxBuffer[2] = nwk_CmdTypes;
pTxBuffer[3] = NWK_AGREE_LEAVE_NETWORK; //同意脱离网络
CC2420_SendPacket(&rfTxInfo,0x01);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -