Contiki-NG
Loading...
Searching...
No Matches
lwm2m-notification-queue.c
Go to the documentation of this file.
1/*
2 * Copyright (c) 2017, RISE SICS AB.
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 * 3. Neither the name of the copyright holder nor the names of its
14 * contributors may be used to endorse or promote products derived
15 * from this software without specific prior written permission.
16 *
17 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER AND CONTRIBUTORS
18 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
19 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
20 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
21 * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
22 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
23 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
24 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
25 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
26 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
27 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
28 * OF THE POSSIBILITY OF SUCH DAMAGE.
29 */
30
31/**
32 * \addtogroup lwm2m
33 * @{
34 */
35
36/**
37 * \file
38 * Implementation of functions to manage the queue to store notifications
39 when waiting for the response to the update message in Queue Mode.
40 * \author
41 * Carlos Gonzalo Peces <carlosgp143@gmail.com>
42 */
43/*---------------------------------------------------------------------------*/
45
46#if LWM2M_QUEUE_MODE_ENABLED
47
48#include "lwm2m-queue-mode.h"
49#include "lwm2m-engine.h"
50#include "coap-engine.h"
51#include "lib/memb.h"
52#include "lib/list.h"
53#include <string.h>
54#include <inttypes.h>
55#include <stdlib.h>
56#include <stdio.h>
57
58/* Log configuration */
59#include "coap-log.h"
60#define LOG_MODULE "lwm2m-notification-queue"
61#define LOG_LEVEL LOG_LEVEL_LWM2M
62
63#ifdef LWM2M_NOTIFICATION_QUEUE_CONF_LENGTH
64#define LWM2M_NOTIFICATION_QUEUE_LENGTH LWM2M_NOTIFICATION_QUEUE_CONF_LENGTH
65#else
66#define LWM2M_NOTIFICATION_QUEUE_LENGTH COAP_MAX_OBSERVERS
67#endif
68
69/*---------------------------------------------------------------------------*/
70/* Queue to store the notifications in the period when the client has woken up, sent the update and it's waiting for the server response*/
71MEMB(notification_memb, notification_path_t, LWM2M_NOTIFICATION_QUEUE_LENGTH); /* Length + 1 to allocate the new path to add */
72LIST(notification_paths_queue);
73/*---------------------------------------------------------------------------*/
74void
75lwm2m_notification_queue_init(void)
76{
77 list_init(notification_paths_queue);
78}
79/*---------------------------------------------------------------------------*/
80static void
81extend_path(notification_path_t *path_object, char *path, int path_size)
82{
83 switch(path_object->level) {
84 case 1:
85 snprintf(path, path_size, "%u", path_object->reduced_path[0]);
86 break;
87 case 2:
88 snprintf(path, path_size, "%u/%u", path_object->reduced_path[0], path_object->reduced_path[1]);
89 break;
90 case 3:
91 snprintf(path, path_size, "%u/%u/%u", path_object->reduced_path[0], path_object->reduced_path[1], path_object->reduced_path[2]);
92 break;
93 }
94}
95/*---------------------------------------------------------------------------*/
96static int
97is_notification_path_present(uint16_t object_id, uint16_t instance_id, uint16_t resource_id)
98{
99 notification_path_t *iteration_path = (notification_path_t *)list_head(notification_paths_queue);
100 while(iteration_path != NULL) {
101 if(iteration_path->reduced_path[0] == object_id && iteration_path->reduced_path[1] == instance_id
102 && iteration_path->reduced_path[2] == resource_id) {
103 return 1;
104 }
105 iteration_path = iteration_path->next;
106 }
107 return 0;
108}
109/*---------------------------------------------------------------------------*/
110static void
111remove_notification_path(notification_path_t *path)
112{
113 list_remove(notification_paths_queue, path);
114 memb_free(&notification_memb, path);
115}
116/*---------------------------------------------------------------------------*/
117void
118lwm2m_notification_queue_add_notification_path(uint16_t object_id, uint16_t instance_id, uint16_t resource_id)
119{
120 if(is_notification_path_present(object_id, instance_id, resource_id)) {
121 LOG_DBG("Notification path already present, not queueing it\n");
122 return;
123 }
124 notification_path_t *path_object = memb_alloc(&notification_memb);
125 if(path_object == NULL) {
126 LOG_DBG("Queue is full, could not allocate new notification\n");
127 return;
128 }
129 path_object->reduced_path[0] = object_id;
130 path_object->reduced_path[1] = instance_id;
131 path_object->reduced_path[2] = resource_id;
132 path_object->level = 3;
133 list_add(notification_paths_queue, path_object);
134 LOG_DBG("Notification path added to the list: %u/%u/%u\n", object_id, instance_id, resource_id);
135}
136/*---------------------------------------------------------------------------*/
137void
138lwm2m_notification_queue_send_notifications()
139{
140 char path[20];
141 notification_path_t *iteration_path = (notification_path_t *)list_head(notification_paths_queue);
142 notification_path_t *aux = iteration_path;
143
144 while(iteration_path != NULL) {
145 extend_path(iteration_path, path, sizeof(path));
146#if LWM2M_QUEUE_MODE_INCLUDE_DYNAMIC_ADAPTATION
147 if(lwm2m_queue_mode_get_dynamic_adaptation_flag()) {
148 lwm2m_queue_mode_set_handler_from_notification();
149 }
150#endif
151 LOG_DBG("Sending stored notification with path: %s\n", path);
152 coap_notify_observers_sub(NULL, path);
153 aux = iteration_path;
154 iteration_path = iteration_path->next;
155 remove_notification_path(aux);
156 }
157}
158#endif /* LWM2M_QUEUE_MODE_ENABLED */
159/** @} */
CoAP engine implementation.
Log support for CoAP.
static void list_init(list_t list)
Initialize a list.
Definition list.h:152
#define LIST(name)
Declare a linked list.
Definition list.h:90
void list_add(list_t list, void *item)
Add an item at the end of a list.
Definition list.c:71
void list_remove(list_t list, const void *item)
Remove a specific element from a list.
Definition list.c:134
static void * list_head(const_list_t list)
Get a pointer to the first element of a list.
Definition list.h:169
int memb_free(struct memb *m, void *ptr)
Deallocate a memory block from a memory block previously declared with MEMB().
Definition memb.c:78
void * memb_alloc(struct memb *m)
Allocate a memory block from a block of memory declared with MEMB().
Definition memb.c:59
#define MEMB(name, structure, num)
Declare a memory block.
Definition memb.h:91
Linked list manipulation routines.
Header file for the Contiki OMA LWM2M engine.
Header file for functions to manage the queue to store notifications when waiting for the response to...
Header file for the Contiki OMA LWM2M Queue Mode implementation to manage the parameters.
Memory block allocation routines.