48 #define PRINTF(...) printf(__VA_ARGS__)
49 #define PRINT6ADDR(addr) PRINTF("[%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x]", ((uint8_t *)addr)[0], ((uint8_t *)addr)[1], ((uint8_t *)addr)[2], ((uint8_t *)addr)[3], ((uint8_t *)addr)[4], ((uint8_t *)addr)[5], ((uint8_t *)addr)[6], ((uint8_t *)addr)[7], ((uint8_t *)addr)[8], ((uint8_t *)addr)[9], ((uint8_t *)addr)[10], ((uint8_t *)addr)[11], ((uint8_t *)addr)[12], ((uint8_t *)addr)[13], ((uint8_t *)addr)[14], ((uint8_t *)addr)[15])
50 #define PRINTLLADDR(lladdr) PRINTF("[%02x:%02x:%02x:%02x:%02x:%02x]", (lladdr)->addr[0], (lladdr)->addr[1], (lladdr)->addr[2], (lladdr)->addr[3], (lladdr)->addr[4], (lladdr)->addr[5])
53 #define PRINT6ADDR(addr)
54 #define PRINTLLADDR(addr)
57 PROCESS(rest_engine_process,
"REST Engine");
59 LIST(restful_services);
60 LIST(restful_periodic_services);
74 static uint8_t initialized = 0;
77 PRINTF(
"REST engine process already running - double initialization?\n");
84 REST.set_service_callback(rest_invoke_restful_service);
105 resource->url = path;
106 list_add(restful_services, resource);
108 PRINTF(
"Activating: %s\n", resource->url);
111 if(resource->flags & IS_PERIODIC && resource->periodic->periodic_handler
112 && resource->periodic->period) {
113 PRINTF(
"Periodic resource: %p (%s)\n", resource->periodic,
114 resource->periodic->resource->url);
115 list_add(restful_periodic_services, resource->periodic);
124 return restful_services;
128 rest_invoke_restful_service(
void *request,
void *response, uint8_t *buffer,
129 uint16_t buffer_size, int32_t *offset)
134 resource_t *resource =
NULL;
135 const char *url =
NULL;
136 int url_len, res_url_len;
138 url_len = REST.get_url(request, &url);
139 for(resource = (resource_t *)
list_head(restful_services);
140 resource; resource = resource->next) {
143 res_url_len = strlen(resource->url);
144 if((url_len == res_url_len
145 || (url_len > res_url_len
146 && (resource->flags & HAS_SUB_RESOURCES)
147 && url[res_url_len] ==
'/'))
148 && strncmp(resource->url, url, res_url_len) == 0) {
152 PRINTF(
"/%s, method %u, resource->flags %u\n", resource->url,
153 (uint16_t)method, resource->flags);
155 if((method & METHOD_GET) && resource->get_handler !=
NULL) {
157 resource->get_handler(request, response, buffer, buffer_size, offset);
158 }
else if((method & METHOD_POST) && resource->post_handler !=
NULL) {
160 resource->post_handler(request, response, buffer, buffer_size,
162 }
else if((method & METHOD_PUT) && resource->put_handler !=
NULL) {
164 resource->put_handler(request, response, buffer, buffer_size, offset);
165 }
else if((method & METHOD_DELETE) && resource->delete_handler !=
NULL) {
167 resource->delete_handler(request, response, buffer, buffer_size,
171 REST.set_response_status(response, REST.status.METHOD_NOT_ALLOWED);
177 REST.set_response_status(response, REST.status.NOT_FOUND);
180 if(resource->flags & IS_OBSERVABLE) {
181 REST.subscription_handler(resource, request, response);
184 return found & allowed;
195 periodic_resource_t *periodic_resource =
NULL;
197 for(periodic_resource =
198 (periodic_resource_t *)
list_head(restful_periodic_services);
199 periodic_resource; periodic_resource = periodic_resource->next) {
200 if(periodic_resource->periodic_handler && periodic_resource->period) {
201 PRINTF(
"Periodic: Set timer for /%s to %lu\n",
202 periodic_resource->resource->url, periodic_resource->period);
203 etimer_set(&periodic_resource->periodic_timer,
204 periodic_resource->period);
210 if(ev == PROCESS_EVENT_TIMER) {
211 for(periodic_resource =
212 (periodic_resource_t *)
list_head(restful_periodic_services);
213 periodic_resource; periodic_resource = periodic_resource->next) {
214 if(periodic_resource->period
217 PRINTF(
"Periodic: etimer expired for /%s (period: %lu)\n",
218 periodic_resource->resource->url, periodic_resource->period);
221 (periodic_resource->periodic_handler)();
#define LIST(name)
Declare a linked list.
rest_resource_flags_t
Resource flags for allowed methods and special functionalities.
list_t rest_get_resources(void)
Returns the list of registered RESTful resources.
void etimer_set(struct etimer *et, clock_time_t interval)
Set an event timer.
#define PROCESS_END()
Define the end of a process.
#define PROCESS(name, strname)
Declare a process.
An abstraction layer for RESTful Web services (Erbium).
#define PROCESS_THREAD(name, ev, data)
Define the body of a process.
void ** list_t
The linked list type.
void list_init(list_t list)
Initialize a list.
void * list_head(list_t list)
Get a pointer to the first element of a list.
void rest_activate_resource(resource_t *resource, char *path)
Makes a resource available under the given URI path.
#define NULL
The null pointer.
int etimer_expired(struct etimer *et)
Check if an event timer has expired.
void rest_init_engine(void)
Initializes and starts the REST Engine process.
void list_add(list_t list, void *item)
Add an item at the end of a list.
void process_start(struct process *p, process_data_t data)
Start a process.
#define PROCESS_PAUSE()
Yield the process for a short while.
#define PROCESS_WAIT_EVENT()
Wait for an event to be posted to the process.
void etimer_reset(struct etimer *et)
Reset an event timer with the same interval as was previously set.
#define PROCESS_BEGIN()
Define the beginning of a process.