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

📄 znwk.c

📁 zigbee精简协议栈代码
💻 C
📖 第 1 页 / 共 3 页
字号:
    }

    // Write Network Frame Control field
    // The frameCONLSB must include NWK_PROT_VER by the caller
    // (APSPutHeader)
    MACPut(frameCONLSB);
    MACPut(frameCONMSB);

    // Write 16 bit destination and 16 bit source network addresses
    // (same as 16 bit short IEEE 802.15.4 addresses)
	MACPut(dest_nwk_addr.byte.LSB);
    MACPut(dest_nwk_addr.byte.MSB);
    MACPut(MACGetShortAddrLSB());
    MACPut(MACGetShortAddrMSB());

    // Write broadcast radius and broadcast sequence number fields.
    // These are mandatory for all addresses now.
    MACPut(nwkCurrentFrame.broadcastRadius);
    MACPut(nwkCurrentFrame.broadcastSequence);
}

/*********************************************************************
 * Function:        BOOL NWKGetHeader(void)
 *
 * PreCondition:    NWKIsGetReady() = TRUE
 *
 * Input:           None
 *
 * Output:          TRUE if a valid NWK frame was received
 *
 * Side Effects:    None
 *
 * Overview:        Fetches and validates already received frame
 *                  against NWK frame rules.
 *
 * Note:            None
 ********************************************************************/
static BOOL NWKGetHeader(void)
{
    // A valid NWK frame must have at least six bytes (2 frame control,
    // 2 destination address, 2 source address) in its payload.
    if ( macCurrentFrame.frameLength < 6 )
        return FALSE;

    nwkCurrentFrame.frameCONLSB.Val = MACGet();
    nwkCurrentFrame.frameCONMSB.Val = MACGet();

    // Make sure that this frame version is supposed.
    if ( (nwkCurrentFrame.frameCONLSB.Val & NWK_PROT_VER_MASK) != NWK_PROT_VER)
        return FALSE;

    // TODO: Implement security capabilities so we don't have to
    // discard all frames with security enabled.
    if ( nwkCurrentFrame.frameCONMSB.bits.security )
        return FALSE;

    // Get 16 bit destination NWK address.  In ZigBee 1.0, this is
    // always the same as the IEEE 802.15.4 short address.
    nwkCurrentFrame.destAddr.byte.LSB = MACGet();
    nwkCurrentFrame.destAddr.byte.MSB = MACGet();

    // Get 16 bit source NWK address.  In ZigBee 1.0, this is
    // always the same as the IEEE 802.15.4 short address.
    nwkCurrentFrame.srcAddr.byte.LSB = MACGet();
    nwkCurrentFrame.srcAddr.byte.MSB = MACGet();

    // Retreive the broadcast radius and broadcast sequence number
    // fields for all destination addresses.
    // Retrieve broadcast radius
    nwkCurrentFrame.broadcastRadius = MACGet();

    // Retrieve broadcast sequence number
    nwkCurrentFrame.broadcastSequence = MACGet();

    // Remember that we have are in process of this frame.
    nwkCurrentFrame.Flags.bits.bIsInProcess = TRUE;

    if(NWKPayload != NULL)
    {
       free(NWKPayloadHead);
        NWKPayloadLength = 0;
    }
    NWKPayload = (BYTE *)malloc(macCurrentFrame.frameLength);
    if(NWKPayload == NULL)
    {
        //TODO(DF20): if null then destroy packet, mark as discarded and exit
    }
    NWKPayloadHead = NWKPayload;
    NWKPayloadLength = macCurrentFrame.frameLength;
    NWKPayloadLengthSave = macCurrentFrame.frameLength;
    while(macCurrentFrame.frameLength)
    {
        *NWKPayload++=MACGet();
    }

    // Account for CRC/(RSSI + CORRELATION for CC2420)
    MACGet();
    MACGet();

    if(nwkCurrentFrame.destAddr.Val == 0xFFFF)
    {
    }
    NWKPayload = NWKPayloadHead;
    return TRUE;
}

/*********************************************************************
 * Macro:           BYTE NWKGet(void)
 *
 * PreCondition:    NWKIsGetReady() = TRUE
 *
 * Input:           None
 *
 * Output:          A data byte
 *
 * Side Effects:    None
 *
 * Overview:        This is a wrapper on MAC function to provide a
 *                  level of abstraction.
 *                  It fetches one data byte from current receive buffer
 *
 * Note:            None
 ********************************************************************/
//du 直接从NWKPayLoad中取数据
BYTE NWKGet(void){
    NWKPayloadLength--;
    return *NWKPayload++;
}

/*********************************************************************
 * Macro:           BYTE NWKGetArray(BYTE *v, BYTE n)
 *
 * PreCondition:    NWKIsGetReady() = TRUE
 *
 * Input:           None
 *
 * Output:          v       - Buffer containing received data bytes
 *                  n       - Number of bytes to get
 *
 * Side Effects:    None
 *
 * Overview:        This is a wrapper on MAC function to provide a
 *                  level of abstraction.
 *                  It fetches given number of data bytes from current receive buffer
 *
 * Note:            None
 ********************************************************************/
//du 直接从NWKPayLoad中取数据
BYTE NWKGetArray(BYTE *v, BYTE n){
    BYTE count = 0;
    while(((n--)>0)&&(NWKPayloadLength>0))
    {
        *v++=*NWKPayload++;
        NWKPayloadLength--;
        count++;
    }
    return count;
}
#if defined(I_AM_COORDINATOR)
	/*********************************************************************
	 * Function:        BOOL NWKIsCoordInitComplete(void)
	 *
	 * PreCondition:    None
	 *
	 * Input:           TRUE if NWK Coordinator is complete
	 *                  FALSE, otherwise
	 *
	 * Output:          None
	 *
	 * Side Effects:    None
	 *
	 * Overview:        Performs coordinaor initialization process.
	 *
	 * Note:            Available for coorindator only.
	 ********************************************************************/
	BOOL NWKIsCoordInitComplete(void)
	{
		// Check to see if discovery is complete.
		if ( NWKIsDiscoveryComplete()){  
			// Terminate this function if there was an error.
			if ( GetLastZError() != ZCODE_NO_ERROR )
				return TRUE;

			// There was no error. Now check to see if
			// any coordinator was discovered.
			else if (  !NWKIsDiscovered() )
			{
				// Terminate this function.
				return TRUE;
			}
		}

		// we are still not done.
		return FALSE;
	}

	/*********************************************************************
	 * Function:        void NWKForm(void)
	 *
	 * PreCondition:    NWKDiscovery is successfully completed.
	 *
	 * Input:           None
	 *
	 * Output:          None
	 *
	 * Side Effects:    None
	 *
	 * Overview:        Selects PANID and establishes network
	 *
	 * Note:            Available to coordinators only.
	 ********************************************************************/
	void NWKForm(void)
	{
		// There was no coordinator in current channel.
		// We can establish network in this channel.

		// Select unique random network
		MACSetPANIdLSB(RANDOM_LSB);
		MACSetPANIdMSB(RANDOM_MSB&0x3F);    //PAN ID only allowed 0x0000-0x3FFF per NWK tables 10,11,17 and 20
		//alex for debug
		MACSetPANIdLSB(0x55);
		MACSetPANIdMSB(0x55);

		// Coordinator gets short address of 0x00.
		MACSetShortAddrLSB(0x00);
		MACSetShortAddrMSB(0x00);

		MACUpdateAddressInfo();

	   

		// Mark that the network is formed.
		MACStart();
		MACFormNetwork();

	}

#endif

//路由
struct Route_Table_Entry *route_table;
struct REQ_ID *req_id_queue;

void init_route()
{
	
		init_route_table();
		init_req_id_queue();
	
}

BOOL is_route_discovered(SHORT_ADDR dest){
	TICK route_tick = TickGet();				
	while(1){
		NWKTask();
		if (TickGetDiff(TickGet(), route_tick) >= NWK_ROUTE_DISCOVER_PERIOD){
			break;
		}
	}
	
	struct Route_Table_Entry *route = lookup_route(dest.Val);
	if (route != NULL && route->flag.bit.is_route_valid){
		return TRUE;	
	}
	else {
		return FALSE;
	}

}

void nwk_proc_rreq( WORD prev_ip, RREQ* request, unsigned int length){	

	//todo: 建立到上一跳节点的无效序列号路由
	
	
	if (!find_req_id( request->source_ip, request->req_id)){
		ConsolePutString("receive route request\n");
		insert_req_id( request->source_ip, request->dest_ip, request->req_id);

		request->hopCount++;

		update_route( request->source_ip, prev_ip, request->sourceSeq, request->hopCount);
		
		if (macInfo.shortAddr.Val == request->dest_ip){
			//目标节点应答
			send_rrep( request);

		}
		/*else if(have_valid_dest_route(route_table, request->dest_ip,
			request->dest_seq) != NULL && !request->flag.bit.d){
			//中间结点应答
			
		}*/
		else{
			//转发RREQ
			struct	Route_Table_Entry * dest_route = lookup_route( request->dest_ip);
			if (dest_route!=NULL && dest_route->flag.bit.is_route_seq_valid){
				if (seq_greater(dest_route->dest_seq, request->dest_seq)){
					request->dest_seq = dest_route->dest_seq;
				}
			}
			forward_rreq( request);
		}
	}
}

void nwk_proc_rrep( WORD prev_ip, RREP *reply, unsigned int length)
{
	//todo:建立到上一跳的无效序列号路由
	ConsolePutString("receive route reply\n");
	
	if (reply->flag.bit.a){
		send_rrep_ack( prev_ip);
	}
	reply->hopCount++;
	update_route( reply->dest_ip, prev_ip, reply->dest_seq, reply->hopCount);

	if (macInfo.shortAddr.Val == reply->source_ip){
		//du 路有查找成功,通知上层应用
		ConsolePutString("we have valid route\n");
	}
	else
	{
		forward_rrep( reply);
	}
}

void nwk_proc_rerr( WORD prev_ip, RERR* error, unsigned int length){
	struct Route_Table_Entry *tmp_route = NULL;
  
	struct Err_Dest *tmp_rerr_dst = NULL;
	struct Err_Dest_List *outgoing_rerr_routes = NULL;
	struct Err_Dest_List *tmp_rerr_route = NULL;
    int num_outgoing_routes = 0;
    
	int i;
    ConsolePutString("receive route error\n");
    tmp_rerr_dst = (struct Err_Dest *) (error + 1);
   
	for ( i = 0; i<error->dest_count; i++)
    {

		tmp_route = lookup_route( tmp_rerr_dst->unreach_dest_ip);
		if (tmp_route && !tmp_route->flag.bit.is_self_route && tmp_route->flag.bit.is_route_valid)
        {
			tmp_route->flag.bit.is_route_valid = FALSE;
			tmp_route->dest_seq = tmp_rerr_dst->unreach_dest_seq; //convert to host format for local storage

							//create a temporary rerr route to use for the outgoing RERR
            if ((tmp_rerr_route = (struct Err_Dest_List *) malloc(sizeof(struct Err_Dest_List))) == NULL)
            {
                //ConsolePutString("malloc new Err_Dest_List error\n");
                return;
            }

            
            tmp_rerr_route->next = outgoing_rerr_routes;
            outgoing_rerr_routes = tmp_rerr_route;
			tmp_rerr_route->err_dest.unreach_dest_ip = tmp_rerr_dst->unreach_dest_ip;
			tmp_rerr_route->err_dest.unreach_dest_seq = tmp_rerr_dst->unreach_dest_seq; //Already in network format...
            num_outgoing_routes++;

        }
        tmp_rerr_dst = tmp_rerr_dst + 1;
     
    }
    if (num_outgoing_routes)
    {
        send_rerr( outgoing_rerr_routes, num_outgoing_routes);
    }
	//ConsolePutString("node%d forward RERR complete\n", node_index+1);
}

void nwk_proc_rrep_ack( WORD prev_ip, RREP_ACK* ack, unsigned int length){
	ConsolePutString("receive route reply ack\n");
}

void send_rreq( WORD dest_ip)
{
	RREQ * request = (RREQ *)malloc(sizeof(RREQ));
	if (request == NULL){
		//ConsolePutString("malloc new RREQ failed\n");
		return;
	}

	struct	Route_Table_Entry *dest_route = lookup_route( dest_ip);
	if (dest_route != NULL && dest_route->flag.bit.is_route_seq_valid){
		//如果存在到目标节点路由,并且序列号有效
		request->dest_seq = dest_route->dest_seq;
		request->flag.bit.u = TRUE;
	}else {
		request->dest_seq = 0;
		request->flag.bit.u = FALSE;
	}
	request->dest_ip  = dest_ip;
	request->type = AODV_RREQ;
	request->reserved = 0;
	request->flag.bit.j = FALSE;
	request->flag.bit.r = FALSE;
	request->flag.bit.d = TRUE;
	request->flag.bit.g = FALSE;
	request->hopCount = 0;

	struct	Route_Table_Entry * src_route = lookup_route( macInfo.shortAddr.Val);
	if (src_route == NULL){
		//ConsolePutString("send rreq failed because of no src_route");
		return;
	}
	request->source_ip = src_route->dest_ip;
	request->req_id = ++src_route->req_id;
	request->sourceSeq = ++src_route->dest_seq;
	//将req_id加入请求表,路由表的第一项是到本地的路由信息
	insert_req_id( macInfo.shortAddr.Val, request->dest_ip, request->req_id);

	//du 发送route_request包
	macDestInfo.addrMode = MAC_DST_SHORT_ADDR;
	macDestInfo.panID = macInfo.panID;
	macDestInfo.shortAddr.Val = 0xffff;
		
    NWKPutHeader(&macDestInfo,
            NWK_FRAME_CMD |
            NWK_PROT_VER,
            0x00,
			macDestInfo.shortAddr);
	NWKPut(NWK_CMD_ROUTE_REQUEST);
	NWKPutArray((BYTE *)request, (BYTE)sizeof(RREQ));
	NWKFlush();
	ConsolePutString("send route request\n");

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -