Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Dependents: mbedEndpointNetwork mbedEndpointNetworkMJK
Fork of Nanostack_lib by
inc/event_os/system_event.h
- Committer:
- sscaglia
- Date:
- 2014-07-15
- Revision:
- 14:b486fa9e70a7
- Parent:
- 12:acef6f596835
File content as of revision 14:b486fa9e70a7:
#ifndef _SYSTEM_EVENT_H_
#define _SYSTEM_EVENT_H_
/*
* Copyright ARM Ltd 2014
*/
#ifdef __cplusplus
extern "C" {
#endif
/**
* \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);
#ifdef __cplusplus
}
#endif
#endif /*_SYSTEM_EVENT_H_*/
