⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 nwk.c

📁 ATmega128L+CC2420的单片机源程序
💻 C
📖 第 1 页 / 共 2 页
字号:
#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 + -