NanoStack lib for Cortex-M4

Dependents:   mbedEndpointNetwork mbedEndpointNetworkMJK

Fork of Nanostack_lib by Sensinode

Revision:
4:c449bead5cf3
Child:
11:1b7aaf37a131
diff -r 1e7446b1fcae -r c449bead5cf3 inc/event_os/system_event.h
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/inc/event_os/system_event.h	Tue Jun 24 16:48:01 2014 +0300
@@ -0,0 +1,383 @@
+#ifndef _SYSTEM_EVENT_H_
+#define _SYSTEM_EVENT_H_
+/*
+ * Copyright ARM Ltd 2014
+ */
+
+/**
+ * \file system_event.h
+ * \brief Library Event and Timer API.
+ *
+ * \section Libary-Event-API Library Event API
+ *  - event_dispatch(), NanoStack 2.x event dispatcher loop call
+ *  - arm_ns_event_send(), Event send function
+ *
+ * \section Global-Interrupts-API Global Interrupts API
+ * - lib_enter_critical(), Disable Interrupt
+ * - lib_exit_critical(), Enable Interrupt
+ * Application can handle global interrupts by using next two macros.
+ * These are mandatory if interrupt uses event_send() function.
+ *
+ * \section Library-Timer-API Library Timer API
+ * - timer_sys_event(), Used to allocate timer events
+ * - timer_sys_event_cancel(), Used to cancel allocated timer events
+ *
+ * If the application needs any timers it can allocate one with timer_sys_event() function.
+ * After the needed timers are allocated system timer event occurs.
+ *
+ * Note: Library supports 6 concurrent timers for the application layer use. Quite often the application can multiplex a single timer for multiple purposes.
+ * Library timer API is not mandatory to be used if own timer drivers are desired.
+ *
+ * \section Events-intro Events introduction
+ *
+ * NanoStack2.0 Library works in event-based scheduling model. This chapter describes the event functionality on the application level.
+ * All events are handled in tasklet_main() function and therefore the main.c file must contain this function. The main event senders are SYSTEM, SYSTEM_TIMER, TL_DNSSD, APP_SPESIFIC_EVENT and EV_NETWORK. See below for example of a tasklet_main().
+ *
+ *@code
+ 	void tasklet_main(event_t *event)
+	{
+		switch(event->sender)
+		{
+
+			case SYSTEM:
+				if (event->event == EV_INIT)
+				{
+					//Initializes application layer tasklet
+					main_initilize();
+					//...
+				}
+				else if (event->event == EV_DEBUG)
+				{
+				//Events from debug interface are handled here.
+				int16_t u_data = debug_get();
+				if(u_data != -1)
+				{
+				...
+				}
+				}
+				break;
+
+				case EV_NETWORK:
+				//Network Event state event handler
+				app_parse_network_event(event->event);
+				break;
+
+				case SYSTEM_TIMER:
+				//SYSTEM_TIMER events are handled here
+				timer_sys_event_cancel(event->event);
+				switch(event->event)
+				{
+				}
+				break;
+
+				case APP_SPESIFIC_EVENT:
+				//Applications own event type
+				break;
+
+				default:
+				break;
+			}
+		}
+
+ *@endcode
+ *
+ * \subsection ev_init EV_INIT event type
+ *
+ * This is received only once after startup per tasklet. Typically when event has been received application will set MAC scan channel list,
+ * open sockets, set certificate Chain, configure Multicast Parameter, load last session form NVM etc.
+ * Also the protocol module stack bootstrap is started here. This can also be done elsewhere if necessary.
+ *
+ * NOTE: main_initialize() function call is mandatory here. See below for an example code of EV_INIT handling:
+ * @code
+ 	 #include “zip_certificates.h” // ZIP test certificates
+	static PL_LARGE int8_t app_udp_socket = 0; //UDP socket variable
+	static PL_LARGE int8_t app_tcp_socket = 0; //TCP server socket variable
+	static PL_LARGE int8_t app_tcp_socket_client = 0; //TCP client socket variable
+	static PL_LARGE int8_t app_raw_socket = 0; //RAW socket variable for ICMP communications
+	static PL_LARGE  certificate_info_entry_t certificate_chain_entry;  // Certificate Chain entry
+
+	void main_initilize(void)
+	{
+		//Initializes tasklet allocation. This has to be executed here.
+		main_initialize();
+		//Generate CertiChain for length 3
+		certificate_chain_entry.certificate_owner = SEC_CERTIFICATE_ZIP;
+		certificate_chain_entry.chain_length = 4;
+		//Set Root
+		certificate_chain_entry.certi_chain[0] = root_certificate;
+		certificate_chain_entry.certi_len[0] = sizeof(root_certificate);
+		certificate_chain_entry.key_chain[0] = rootpk;
+		//Set MICA
+		certificate_chain_entry.certi_chain[1] = mca_certi;
+		certificate_chain_entry.certi_len[1] = sizeof(mca_certi);
+		certificate_chain_entry.key_chain[1] = mca_pv;
+		// Set MCA
+		certificate_chain_entry.certi_chain[2] = mica_certi;
+		certificate_chain_entry.certi_len[2] = sizeof(mica_certi);
+		certificate_chain_entry.key_chain[2] = mica_pv;
+		//Set Dev
+		certificate_chain_entry.certi_chain[3] = dev_certi;
+		certificate_chain_entry.certi_len[3] = sizeof(dev_certi);
+		certificate_chain_entry.key_chain[3] = dev_pv;
+
+		//Set chain list
+		sec_certificate_list_update(&certificate_cahin_entry);
+
+		//Open UDP Socket to Port 64771
+		app_udp_socket = socket_open(SOCKET_UDP, 64771, mainreceive_udp);
+
+		//Open TCP Socket to Port 80 & 81
+		app_tcp_socket = socket_open(SOCKET_TCP,80, mainreceive_tcp_server);
+		app_tcp_socket_client = socket_open(SOCKET_TCP,81, mainreceive_tcp_client);
+
+		//Open ICMP RAW socket
+		app_raw_socket = socket_open(SOCKET_ICMP,0xffff, mainreceive_raw);
+
+		// Set one TCP socket to listen state, Cipher mode parameter is unused when
+		//Socket Type is PROTOCOL_UDP or PROTOCOL_TCP
+		socket_listen(app_tcp_socket);
+		multicast_set_parameters(10,0,20,3,75 );
+		if(nwk_nvm_load_nvm_data_to_stack() == 0)
+		{
+			debug("NVM session Load and NWKID filter enabled\r\n");
+			nwk_id_filter_enabled = 1;
+			if(nwk_nvm_get_network_role(&net_start_operating_mode, &pana_suite) == 0)
+			{
+			   int8_t retval;
+				debug("Start After Reset\r\n");
+				if(nwk_nvm_get_network_id(network_id_filter) == 0)
+				{
+					retval = net_zip_start(channel_list, 0xffff,network_id_filter,net_start_operating_mode, pana_suite );
+				}
+				else
+				{
+					network_id_filter[0] = 't';
+					retval = net_zip_start(channel_list, 0xffff,0,net_start_operating_mode, pana_suite );
+				}
+				if(retval != 0)
+				{
+				 debug_int(retval);
+				 debug("Start Fail code\r\n");
+				}
+				else
+				{
+					debug("ZigBeeIP Bootstrap started\r\n");
+				}
+			}
+
+		}
+		else
+		{
+			//Set NanoStack 2.0 in Router mode, Chan channels 11-16, PAN-IDfilter 0xffff and PANA TLS chiphersuite PSK
+			net_zip_start(0x07fff800, 0xffff,0, NW_INFRA_ROUTER, SEC_SOCKET_CHIPHERSUITE_PSK);
+		}
+}
+
+ * @endcode
+ *
+ * \subsection net-event Network event
+ *
+ * Network events are enabled after stack has been started with net_start() function call or after indicated network failure status.
+ * The stack uses these events to inform the application of the network connection status.
+ *
+ * | Event Type                | Value | Description                                       |
+ * | :-----------------------: | :---: | :-----------------------------------------------: |
+ * | NET_READY                 | 0     | Connection to access point is ready               |
+ * | NET_NO_BEACON             | 1     | No Coordinator available                          |
+ * | NET_NO_ND_ROUTER          | 2     | No ND Router available                            |
+ * | NET_NO_PANA_SERVER        | 3     | No Response for Pana PCI                          |
+ * | NET_PANA_SERVER_AUTH_FAIL | 4     | Pana authentication process fail                  |
+ * | NET_BORDER_ROUTER_LOST    | 5     | Connection to Border Router lost 				   |
+ * | NET_PARENT_POLL_FAIL      | 6     | Host poll to parent have been failed direct 3 time|
+ *
+ * Application should start stack again scanning all 16 channels again when receiving NET_PARENT_POLL_FAIL.
+ * When NET_NO_BEACON, NET_NO_ND_ROUTER, NET_NO_PANA-SERVER or NET_PANA_SERVER_AUTH_FAIL  event occur the stack will enter IDLE state automatically.
+ * In case of NET_BORDER_ROUTER_LOST event stack starts scanning automatically for new network and application must wait for the result before attempting to transmit data.
+ *
+ * \subsection app-specific_event Application Specific Event Send
+ *
+ * This chapter describes how application can send events to itself. This is useful if application wants for example to receive a signal from an interrupt or in other case.
+ * Event structure sender has to be APP_SPESIFIC_EVENT.
+ *
+ * See below for a simple example that only initializes Debug interface and Port A.7 GPIO to interrupt. Interrupt handler then sends event to application.
+ * @code
+
+
+	#include "socket_api.h"
+	#include "net.h"
+	#include "system_event.h"
+	#include "string.h"
+	#include "ns_debug.h"
+	#define S1_BUTTON 0xFF
+
+	void s1_init(void);
+	//Initializes interrupt gpio settings in Port A.7.
+	void s1_init(void)
+	{
+		GPIO_PACFGH &= ~PA7_CFG;	//init portA.7 as input
+		GPIO_PACFGH |= 0x8000;
+		GPIO_PAOUT |= PA7;	//pull-up portA.7
+		GPIO_IRQDSEL = 0x07;
+		GPIO_INTCFGD |= 0x140;
+		INT_GPIOFLAG |= INT_IRQDFLAG;
+		INT_CFGSET |= INT_IRQD;
+	}
+
+	//GPIO IRQD Handler.
+	//Sends event to the tasklet_main when button S1 in Port A.7 is pushed.
+
+	void halIrqDIsr(void)
+	{
+		INT_GPIOFLAG |= INT_IRQDFLAG;
+	//	Example of sending event to the application.
+	//	event.event is user defined event.
+	//	In this application S1_BUTTON event is sent when IRQD interrupt occurs
+		event_t event;
+		event.sender = APP_SPESIFIC_EVENT;
+		event.receiver = TL_MAIN;
+		event.event = S1_BUTTON;
+		arm_ns_event_send(&event);
+	}
+
+
+
+	void tasklet_main(event_t *event)
+	{
+		switch(event->sender)
+		{
+			case SYSTEM:
+				if (event->event == EV_INIT)
+				{
+				//Inits debugs and Port A.7 GPIO pin interrupt
+				debug_init(230400);
+				s1_init();
+				}
+				break;
+			case APP_SPESIFIC_EVENT:
+				//Application own event type
+				if(event->event == S1_BUTTON)
+				{
+				debug("S1 button pressed\r\n");
+				}
+				break;
+			default:
+				break;
+		}
+	}
+
+ * @endcode
+ *
+ */
+#include "pl_types.h"
+
+ /**
+  * \enum error_t
+  * \brief System generic error.
+  */
+typedef enum error_t
+{
+	eOK = 0,	/*!< no error */
+	eFALSE = 1, /*!< no result */
+	eBUSY = 2,	/*!< resource busy */
+	eSYSTEM		/*!< error code readable in sys_error */
+}error_t;
+#include "tasklet_api.h"
+
+typedef enum arm_nwk_interface_status_type_e
+{
+	ARM_NWK_BOOTSTRAP_READY = 0, /**< Interface configured Bootstrap is ready*/
+	ARM_NWK_RPL_INSTANCE_FLOODING_READY, /**< RPL instance have been flooded */
+	ARM_NWK_SET_DOWN_COMPLETE, /**< Interface DOWN command successfully */
+	ARM_NWK_NWK_SCAN_FAIL, 	/**< Interface have not detect any valid network*/
+	ARM_NWK_IP_ADDRESS_ALLOCATION_FAIL, /*!*< IP address allocation fail(ND, DHCPv4 or DHCPv6 */
+	ARM_NWK_DUPLICATE_ADDRESS_DETECTED, /*!*< User specific GP16 was not valid */
+	ARM_NWK_AUHTENTICATION_START_FAIL, /**< No valid Authentication server detected behind access point */
+	ARM_NWK_AUHTENTICATION_FAIL,	/**< Network authentication fail by Handshake */
+	ARM_NWK_NWK_CONNECTION_DOWN, /*!*< No connection between Access point or Default Router */
+	ARM_NWK_NWK_PARENT_POLL_FAIL, /*!*< Sleepy host poll fail 3 time */
+	ARM_NWK_PHY_CONNECTION_DOWN, /*!*< Interface PHY cable off or serial port interface not respond anymore */
+} arm_nwk_interface_status_type_e;
+
+typedef enum arm_library_event_type_e
+{
+	ARM_LIB_TASKLET_INIT_EVENT = 0, /**< Tasklet Init come always when generate tasklet*/
+	ARM_LIB_NWK_INTERFACE_EVENT = 1,	/**< Interface Bootstrap  or state update event */
+	ARM_LIB_SYSTEM_TIMER_EVENT = 2, /*!*< System Timer event */
+} arm_library_event_type_e;
+
+
+typedef struct arm_event_s
+{
+	int8_t receiver; /**< Event handler Tasklet ID */
+	int8_t sender; /**< Event sender Tasklet ID */
+	uint8_t event_type; /**< This will be typecast arm_library_event_type_e */
+	uint8_t event_id; /**< Timer ID, NWK interface ID or application specific ID */
+	void *data_ptr; /**< Application could share data pointer tasklet to tasklet */
+	void (*cb_fptr)(uint8_t); /**< Application could share data pointer tasklet to tasklet */
+	uint32_t event_data;
+} arm_event_s;
+
+/**
+ * \brief NanoStack 2.x event dispatcher loop call.
+ */
+extern NEAR_FUNC void event_dispatch(void);
+
+/**
+ * \brief A function to allocate a sapplication tasklet.
+ *
+ * \param tasklet_func_ptr pointer to event handler
+ *
+ * \return eOK event allocated
+ * \return eFAIL event reserved
+ */
+extern int8_t arm_ns_tasklet_create(void (*tasklet_func_ptr)(arm_event_s*));
+
+/**
+ * \brief A function to send an event.
+ *
+ * \param event a pointer to an event to send.
+ * \return eOK
+ * \return eFALSE invalid tasklet ID
+ * \return eBUSY event queue full
+ *
+ *
+ */
+extern int8_t arm_ns_event_send(arm_event_s *event);
+
+/**
+ * \brief A function to request a software timer from NanoStack.
+ *
+ * \param snmessage is a timer ID to send.
+ * \param time is time in milliseconds when the requested event is to trigger.
+ *
+ * \return 0 on success.
+ * \return -1 on failure.
+ *
+ * After allocated time period NanoStack2.0 will send event of which sender SYSTEM_TIMER (event->sender)
+ * and event->event  is indicating allocated timer identification.
+ *
+ * */
+extern int8_t timer_sys_event(uint8_t snmessage, uint32_t time);
+
+/**
+ * \brief A function to cancel a timer that has been requested.
+ * \param snmessage is a timer ID to cancel.
+ * \return 0 on success.
+ * \return -1 on failure or in case if timer is not found.
+ *
+ * */
+extern int8_t timer_sys_event_cancel(uint8_t snmessage);
+
+/**
+  * \brief A function to enter into a mode where global interrupts are disabled.
+  *
+  */
+extern void lib_enter_critical(void);
+
+/**
+  * \brief A function to enter into a mode where global interrupts are enabled.
+  *
+  */
+extern void lib_exit_critical(void);
+
+#endif /*_SYSTEM_EVENT_H_*/