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

📄 network.c

📁 关于zigbee厂家jennic的zigbee通信模块JN5139的一些示例程序。
💻 C
📖 第 1 页 / 共 5 页
字号:
/****************************************************************************/
/*!
 *\MODULE              Wireless UART with Flow Control
 *
 *\COMPONENT           $RCSfile: Network.c,v $
 *
 *\VERSION             $Name:  $
 *
 *\REVISION            $Revision: 1.5 $
 *
 *\DATED               $Date: 2008/03/26 14:40:44 $
 *
 *\STATUS              $State: Exp $
 *
 *\AUTHOR              Martin Looker
 *
 *\DESCRIPTION         Network - implementation.
 *
 * This file provides code that is common to most Jenie applications for all
 * node types. The first set of functions are equivalent to the standard Jenie
 * callback functions and should be called by those functions from the node type
 * specific files, (Coordinator.c, Router.c, EndDevice.c).
 *
 * Functions and code are included to manage the binding of services and to transmit
 * and receive data using services.
 *
 * Destination services that receive data can be advertised by registering them
 * with the Jenie API. Whilst a destination service is registered it can be found and
 * bound to by source services on other nodes. Once bound, (even if later unregistered),
 * data can be sent to a destination service. Up to 32 destination services can be
 * specified.
 *
 * Source services that transmit data can look for compatible destination services by
 * requesting them from the Jenie API. When destination services are found they can be
 * bound to from the source service. Data can then be transmitted from the source service
 * to any bound destination service(s). Jenie allows up to 32 source services to be specified
 * however only 4 of these are made available for use in Network.c in order to save memory space,
 * this can be altered by changing the define NETWORK_MAX_SOURCE in Network.h.
 *
 * Binding to and from services can be enabled, (using the Enabled functions).The maximum
 * number of bindings for each service can also be specified, (using the Limit functions).
 * These features used in combination allow the application to control
 * when and how many bindings can be made to and from the application's services.
 * When binding is enabled and the limit not yet reached for a service code is included
 * to automatically register, request and bind the services, handling the Jenie API operations
 * that make this possible.
 *
 * When initialising during a cold start, the destination service for receiving data is
 * limited to one binding and binding enabled. Once bound to by the other node the destination
 * service will no longer be advertised in the network.
 *
 * The source service for transmitting data is also limited to one binding and binding enabled
 * when initialising during a cold start. Once the network is up and running code in Network.c
 * will continue to request a matching destination service and bind to it. Once the binding
 * is made Network.c will stop requesting the destination service.
 *
 * The Coordinator and Router devices will therefore automatically bind to each other
 * after joining the network.
 *
 * Functions are also included and used to transmit data from a source service and to
 * receive data to a destination service.
 */
/*\CHANGE HISTORY
 *
 * $Log: Network.c,v $
 * Revision 1.5  2008/03/26 14:40:44  mlook
 * Now scans channels
 *
 * Revision 1.4  2008/03/20 09:53:19  mlook
 * Button start for Respiratronics
 *
 * Revision 1.3  2008/03/05 09:47:29  mlook
 * Added option for binding with buttons
 *
 * Revision 1.2  2008/03/05 09:33:17  mlook
 * Added option for binding with buttons
 *
 * Revision 1.1  2008/01/21 10:15:04  mlook
 * Initial checkin
 *
 *
 *
 *\LAST MODIFIED BY    $Author: mlook $
 *                     $Modtime: $
 *
 ****************************************************************************
 *
 * This software is owned by Jennic and/or its supplier and is protected
 * under applicable copyright laws. All rights are reserved. We grant You,
 * and any third parties, a license to use this software solely and
 * exclusively on Jennic products. You, and any third parties must reproduce
 * the copyright and warranty notice and any other legend of ownership on each
 * copy or partial copy of the software.
 *
 * THIS SOFTWARE IS PROVIDED "AS IS". JENNIC MAKES NO WARRANTIES, WHETHER
 * EXPRESS, IMPLIED OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED
 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE,
 * ACCURACY OR LACK OF NEGLIGENCE. JENNIC SHALL NOT, IN ANY CIRCUMSTANCES,
 * BE LIABLE FOR ANY DAMAGES, INCLUDING, BUT NOT LIMITED TO, SPECIAL,
 * INCIDENTAL OR CONSEQUENTIAL DAMAGES FOR ANY REASON WHATSOEVER.
 *
 * Copyright Jennic Ltd 2007. All rights reserved
 *
 ****************************************************************************/

/****************************************************************************/
/***        Include files                                                 ***/
/****************************************************************************/
/* Jennic include files */
#include <jendefs.h>
#include <jenie.h>
#include <JPI.h>
#include <Button.h>
#include <LedControl.h>
#include <Printf.h>
/* Standard library include files */
#include <string.h>
/* Debugging include files */
#include <gdb.h>
/* Local include files */
#include "Network.h"
#include "Protocol.h"
#include "SerialQ.h"
#include "Uart.h"
#include "WUartDisp.h"

/****************************************************************************/
/***        Macro Definitions                                             ***/
/****************************************************************************/
#define LED_PULSE 2

/****************************************************************************/
/***        Type Definitions                                              ***/
/****************************************************************************/
typedef enum
{
	E_SERVICE_STATE_IDLE	= 0,	/**< Not setting up services  			*/
	E_SERVICE_STATE_REGISTER,		/**< Attempting to register services	*/
	E_SERVICE_STATE_REQUEST,		/**< Attempting to request services		*/
} teServiceState;

typedef struct
{
	uint32 u32Ready;			/**< Service mask ready, (registered services or bound requested services). */
	uint32 u32Pend;				/**< Service mask pending */
	uint32 u32Allow;			/**< Service mask allowed to bind */
	uint32 u32Enabled;			/**< Service mask binding enabled */
	uint32 u32Free;				/**< Service mask bind slots free, bind count is below bind limit */
	uint8  au8Limit[32];		/**< Service binding limits */
	uint8  au8Count[32];		/**< Service binding counts */
} tsServices;

typedef struct
{
	uint64 u64Address;						/**< Destination address */
	uint8	u8TxFlags;						/**< Transmit flags */
	uint16 u16Length;						/**< Data packet length */
	uint8  au8Data[NETWORK_TX_DATA_SIZE]; 	/**< Data packet data */
} tsNetworkTx;

typedef struct
{
	uint8	    u8Head;						/**< Next packet to be transmitted */
	uint8	    u8Tail;						/**< Next packet available for use */
	uint8		u8Count;					/**< Count of packets pending transmission */
	uint16     u16Timer;					/**< Timer for packet tranmission */
	uint8       u8Attempts;					/**< Number of attempts made */
	bool_t       bPend;						/**< Transmit is pending */
	tsNetworkTx asTx[NETWORK_TX_QUEUE_SIZE];/**< Queue of packets */
} tsNetworkTxQ;

/****************************************************************************/
/***        Local Function Prototypes                                     ***/
/****************************************************************************/
PRIVATE teJenieStatusCode 	eNetwork_Services_Enabled 	(uint8, uint32, bool_t);
PRIVATE bool_t 				bNetwork_Service_Enabled 	(uint8, uint8);
PRIVATE teJenieStatusCode 	eNetwork_Services_Limit 	(uint8, uint32, uint8);
PRIVATE teJenieStatusCode 	eNetwork_Service_Limit 		(uint8, uint8, uint8);
PRIVATE uint8 			   u8Network_Service_Limit 		(uint8, uint8);
PRIVATE uint8 			   u8Network_Service_Count 		(uint8, uint8);
PRIVATE void 			  	vNetwork_Service_Main 		(void);
PRIVATE void 				vNetwork_Service_State 	 	(teServiceState);
PRIVATE void                vNetwork_Service_Current    (void);
PRIVATE teJenieStatusCode 	eNetwork_Service_Free 		(uint8, uint8);
PRIVATE teJenieStatusCode 	eNetwork_Service_Allow 		(uint8);
PRIVATE uint32 			  u32Network_Services_Bind 		(uint8, uint32, uint64);
PRIVATE uint32 			  u32Network_Services_Unbind 	(uint8, uint32, uint64);
PRIVATE uint32 			  u32Network_Services_Bound 	(uint8, uint32, uint64);
PRIVATE bool_t				bNetwork_Services_Bind_Tx	(char, uint8, uint32, uint64);
PRIVATE void 				vNetwork_Services_Bind_Rx	(uint64, uint16, uint8 *);
PRIVATE bool_t 				bNetwork_Tx_Add 			(uint64, uint8, uint16, uint8 *);
PRIVATE bool_t 				bNetwork_Tx_Del 			(void);
PRIVATE void 				vNetwork_Tx_Main			(void);

/****************************************************************************/
/***        Exported Variables                                            ***/
/****************************************************************************/

/****************************************************************************/
/***        Local Variables                                               ***/
/****************************************************************************/
PRIVATE teJenieDeviceType	  eDeviceType;		  /**< Device type 			*/
PRIVATE bool_t				  bNetworkUp;		  /**< Network is up 		*/
PRIVATE bool_t				  bUartUp;		  	  /**< Uart is open   		*/
PRIVATE bool_t				  bBind;			  /**< Currently allowing binding */
PRIVATE uint8				 u8Button;			  /**< Button states */
PRIVATE uint16				u16PollTimer;		  /**< Poll timer 			*/
PRIVATE uint16				u16PollPeriod;		  /**< Time between polls (10ms intervals) */
PRIVATE uint8				 u8ServiceCurrent;	  /**< Service currently being processed */
PRIVATE	teServiceState		  eServiceState;	  /**< Service state        */
PRIVATE	uint16				u16ServiceStateTimer; /**< Service timer        */
PRIVATE tsServices			 asServices[NETWORK_MAX_SOURCE+1]; /**< Services status */
PRIVATE char				 szAsciiHex[17] = "0123456789ABCDEF";
PRIVATE tsNetworkTxQ		  sNetworkTxQ;		  /**< Network transmit queue */
PRIVATE uint64				u64LastRxAddress;	  /**< Last address we received something from */
#if NETWORK_LED
PRIVATE uint8				 u8Led0Timer;		  /**< LED 0 timer */
PRIVATE uint8				 u8Led1Timer;		  /**< LED 1 timer */
#endif

/****************************************************************************/
/***        Local Constants                                               ***/
/****************************************************************************/
/* Timeouts in 10ms units */
PRIVATE const uint16 			    au16ServiceStateTimeout[] = {0, 100, 200};

/* Debugging strings */
#if NETWORK_DEBUG
PRIVATE const char 					aszDeviceType[][20] = {
										"COORDINATOR",
										"ROUTER",
										"END_DEVICE"};
PRIVATE const char 					aszServiceState[][20] = {
										"IDLE",
										"REGISTER",
										"REQUEST"};
PRIVATE const char 					aszEventType[][20]  = {
										"REG_SVC_RSP",
										"SVC_REQ_RSP",
										"POLL_CMPLT",
										"PACKET_SENT",
										"PACKET_FAILED",
										"NETWORK_UP",
										"CHILD_JOINED",
										"DATA",
										"DATA_TO_SERVICE",
										"DATA_ACK",
										"DATA_TO_SERVICE_ACK",
										"STACK_RESET"};
PRIVATE const char 				    aszStatusCode[][20] = {
										"SUCCESS",
										"DEFERRED",
										"ERR_UNKNOWN",
										"ERR_INVLD_PARAM",
										"ERR_STACK_RSRC",
										"ERR_STACK_BUSY"};
#endif

/****************************************************************************/
/***        Public network functions                                      ***/
/****************************************************************************/

/****************************************************************************
 *
 * NAME 		vNetwork_ConfigureNetwork
 */
/*!
 *\DESCRIPTION 	Configures the network before the stack is initialised.
 *
 * This function performs network configuration before the stack is initialised.
 *
 * This function should be called from vJenie_CbConfigureNetwork() as it performs
 * the network configuration tasks common to all Jenie device types.
 *
 * This function is only called during a cold start.
 */
/* RETURNS
 * None
 *
 ****************************************************************************/
PUBLIC void vNetwork_ConfigureNetwork (
	teJenieDeviceType  eConfigDeviceType,	/**< Type of device to run as */
   	uint8 			  u8ConfigMaxChildren)	/**< Maximum child devices allowed */
{
	/* Debug hooks: include these regardless of whether debugging or not */
	HAL_GDB_INIT();
    HAL_BREAKPOINT();

	/* Set network identification parameters */
	gJenie_NetworkApplicationID  = NETWORK_APPLICATION_ID;
	gJenie_PanID 			 	 = NETWORK_PAN_ID;
	gJenie_Channel 			 	 = NETWORK_CHANNEL;
	#if NETWORK_CHANNEL
		gJenie_ScanChannels		 = (1 << NETWORK_CHANNEL);
	#else
		gJenie_ScanChannels		 = NETWORK_SCAN_CHANNELS;
	#endif

	/* Note initialisation settings */
	eDeviceType          = eConfigDeviceType;

	/* Limit maximum children to the absolute maximum allowed (10) */
	if (u8ConfigMaxChildren > 10) u8ConfigMaxChildren = 10;
	/* End device ? */
	if (eDeviceType == E_JENIE_END_DEVICE)
	{
		/* Set ping interval - if required */
		//gJenie_EndDevicePingInterval = 0;
		/* Turn off automatic polling - we're going to control it in software */
		gJenie_EndDevicePollPeriod   = 0;
		/* Set our internal polling period */
		u16PollPeriod = NETWORK_POLL_PERIOD;
		u16PollTimer  = 0;
		/* Don't allow any children for an end device */
		u8ConfigMaxChildren = 0;
	}

	/* Set up maximum children */
	gJenie_MaxChildren = u8ConfigMaxChildren;

	/* Network is not up yet */
	bNetworkUp  = FALSE;

	/* UART is not up yet */
	bUartUp 	= FALSE;

	/* Set binding enabled state */
	#if NETWORK_BUTTON_BIND
		bBind = FALSE;
	#else
		bBind = TRUE;
	#endif

	/* Set current service */
	u8ServiceCurrent = 0;

	/* No services set up yet */
	memset(asServices, 0, sizeof(asServices));

	/* Service state is idle */
	vNetwork_Service_State(E_SERVICE_STATE_IDLE);

	/* No data queued for transmission yet */
	memset(&sNetworkTxQ, 0, sizeof(sNetworkTxQ));

	/* Zero last address we received data from */
	u64LastRxAddress = 0ULL;

	/* Limit source and destination services to one binding each */
	(void) eNetwork_Destination_Limit(1, 1);
	(void) eNetwork_Source_Limit(1, 1, 1);

	/* Set appropriate binding state */
	(void) eNetwork_Destination_Enabled(1, bBind);
	(void) eNetwork_Source_Enabled(1, 1, bBind);
}

/****************************************************************************
 *
 * NAME 		vNetwork_Init
 */
/*!
 *\DESCRIPTION 	Initialise the network and start the stack.
 *
 * Allows initialisation to take place and then starts the stack.
 *
 * This function should be called from vJenie_CbInit() as it performs
 * the network initialisation tasks common to all Jenie device types.
 *
 * This function called during both a cold and warm start.
 */
/* RETURNS
 * None
 *
 ****************************************************************************/
PUBLIC void vNetwork_Init (
	bool_t 			  bWarmStart,	/**< Specifies if a warm start is taking place */
   	bool_t			  bInitUart)	/**< Specifies if the UART should be opened for printf support */
{

	bool_t bUart;
	teJenieStatusCode eStatus;

	#if NETWORK_LED
	/* Cold start ? */
	if (! bWarmStart)
	{
		/* Initialise LEDs */
		vLedInitRfd();
		vLedControl(0, FALSE);
		vLedControl(1, TRUE);
		u8Led0Timer = 0;
		u8Led1Timer = 0;
	}
	#endif

	/* Initialise reduced function device */
	vButtonInitRfd();
	u8Button = 0;

	/* Note passed in uart setting */
	bUart              = bInitUart;

	/* Using GDB or using UART0 for wireless UART ? */
	#ifdef GDB
		/* Override passed in UART setting to turn it off - reserved for GDB */
		bUart = FALSE;
	#else
        #if UART == E_JPI_UART_0
            /* Override passed in UART setting to turn it off - reserved for wireless uart */
            bUart = FALSE;
        #else
            /* Want to run network debugging ? */
            #if NETWORK_DEBUG
                /* Override passed in UART setting to turn it on - needed for debugging */
                bUart = TRUE;
            #endif
        #endif
	#endif

	/* Uart not yet up */
	bUartUp 	= FALSE;

	/* Want to open UART ? */
	if (bUart)
	{
		/* Open UART */
		vUART_printInit();
		/* Note it is open */
		bUartUp = TRUE;
	}

	/* Enable wake timer 1 with interrupt */
	vJPI_WakeTimerEnable(E_JPI_WAKE_TIMER_1, TRUE);
	/* Run the timer for 10ms */

⌨️ 快捷键说明

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