#include <avr/io.h>
#include <avr/pgmspace.h>
#include <avr/eeprom.h>
#include <inttypes.h>
#include <stddef.h>
#include "net/application.h"
#include "net/network.h"
#include "net/link.h"
#include "net/buffers.h"
#include "net.h"
#include "utils.h"
Go to the source code of this file.
Data Structures | |
struct | assoc_t |
struct | event_desc_t |
struct | event_t |
struct | main_buf_t |
Defines | |
#define | READ_WORD(x) (x) |
#define | SYS_ADDR_LOGIC_SET 0 |
#define | SYS_ADDR_LOGIC_GET 1 |
#define | SYS_ADDR_GROUP_SET 2 |
#define | SYS_ADDR_GROUP_GET 3 |
#define | SYS_SIZE_SEGMENT_SET 4 |
#define | SYS_SIZE_SEGMENT_GET 5 |
#define | SYS_SIZE_GROUP_SET 6 |
#define | SYS_SIZE_GROUP_GET 7 |
#define | SYS_ASSOC_SET 8 |
#define | SYS_ASSOC_GET 9 |
#define | SYS_GET_ERROR_STATS 10 |
Functions | |
net_buf_t * | tsp_ind (uint8_t *buf, uint8_t len, uint8_t session) |
Called from transport layer if a packet arrived. | |
void | tsp_con (uint8_t *buf, uint8_t len) |
Called from transport layer if a reply to a request arrived. | |
void | tsp_con_fin (uint8_t status) |
Called from transport layer if a request was finished. | |
void | app_init (void) |
Initialize layer. | |
void | app_process (void) |
Process waiting events. | |
void | app_trigger_event (uint8_t obj, uint8_t event) |
Fire an event. | |
uint8_t | app_register_obj (struct AppObject *obj, uint8_t events) |
Dynamically register an object. | |
Variables | |
char | __eeprom_end |
void * | next_eeprom_addr = &__eeprom_end |
assoc_t ee_assoc[APP_MAX_ASSOC] | EEPROM |
This file implements the OpenHome presentation layer and manages all application objects. It also contains the system object which is responsible for network management and node configuration.
All application defined objects must have a predefined structure to be accessable by this layer. Assuming that your application should contain a object called "switch1" you have to define and implement the following:
#include <avr/pgmspace.h> #include <inttypes.h> #include "net/application.h" #define METHOD_0 0x00 #define METHOD_1 0x01 #define EVENT_0 0x80 void switch1_callback(void *self, // pointer to application object uint8_t method, // method which is called uint8_t *buf, // pointer to parameters buffer uint8_t *result, // pointer to result buffer uint8_t repeated) // indicated duplicate requests { switch (method) { case METHOD_0: DoSomethingUseful(); break; case METHOD_1: break; case EVENT_0: ProvideDataToResultPointer(); break; } } static param_desc_t switch1_methods[] = {{2,0}, {1,0}, {0,1}, {1,0}, {0,1}}; static param_desc_t switch1_events[] = {{0,0}, {0,2}};
The purpose of the callback method should be evident. The function is also called if a event was triggered in order to collect the outgoing parameters. Note that 0x80 is added to "method" to indicate a event!
The tricky part now is the definition of the two tables. They define the size of the parameters for all methods and events. The above definition of switch1_methods indicate that method 0 expects two bytes as input parameters and does not return any data while method 2 expects no parameters and returns one byte. It is up to the applications how these bytes are interpreted. Exactly as the switch1_methods-table the switch1_events-table defines the size of the in- and outgoing parameters for all events.
It is possible to compile this file in two versions: static and dynamic. This influences the way the actual application objects are defined and registered.
Static version
The static version defines all object tables to be stored in flash memory. It is intended for non-interactive nodes with limited memory. To compile this version you have to define the following in your net.h:
#define APP_STATIC #define APP_OBJECTS OBJECT(switch1, 2) OBJECT(switch2, 2)
The above definitions tells the application layer to be compiled as static version and that the application contains two objects called "switch1" and "switch2" which both have two events. The number of events must be specified to enable the application layer to reserve the right amount of eeprom space.
The actual application objects must be defined the following:
struct AppObject PROGMEM switch1 = { switch1_methods, switch1_events, switch1_callback }; struct AppObject PROGMEM switch2 = { switch2_methods, switch2_events, switch2_callback };
Dynamic version
The dynamic version stores all object tables in ram and is suited for interactive nodes with sufficient memory. It enables the node to dynamically generate and register objects during initialization.
To compile for this version make sure that the APP_STATIC token is not defined. Application objects are registered through a call of app_register_obj() and should be defined and initialized the following:
struct AppObject *switch1; void init(void) { switch1 = malloc(sizeof(struct AppObject)); switch1->method_sizes = switch1_methods; switch1->event_sizes = switch1_events; switch1->Callback = switch1_callback; app_register_obj(switch1, 2); }
Definition in file application.c.
|
Initialize layer. Should be called after lnk_init(). Definition at line 431 of file application.c. |
|
Process waiting events. This function should be called from your main loop.
Definition at line 446 of file application.c. References tsp_clear_to_send(), tsp_requ(), and tsp_service_e. |
|
Dynamically register an object. In the current implementation it is not possible to unregister an object. Furthermore all objects must be registered in the same order if a reset occurs. Otherwise the event configurations will be corrupted.
Definition at line 519 of file application.c. |
|
Fire an event.
Definition at line 500 of file application.c. |
|
Called from transport layer if a reply to a request arrived.
Definition at line 396 of file application.c. Referenced by net_ind(). |
|
Called from transport layer if a request was finished.
Definition at line 417 of file application.c. Referenced by net_con(), net_ind(), and tsp_check_timeout(). |
|
Called from transport layer if a packet arrived.
Definition at line 359 of file application.c. Referenced by net_ind(). |