NanoStack lib for Cortex-M4
Dependents: mbedEndpointNetwork mbedEndpointNetworkMJK
Fork of Nanostack_lib by
Diff: inc/event_os/system_event.h
- 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_*/