1 /*
2 * Copyright (C) 2015-2018 Alibaba Group Holding Limited
3 */
4 #include "iotx_dm_internal.h"
5
6 #if !defined(DM_MESSAGE_CACHE_DISABLED)
7
8 dm_msg_cache_ctx_t g_dm_msg_cache_ctx;
9
_dm_msg_cache_get_ctx(void)10 dm_msg_cache_ctx_t *_dm_msg_cache_get_ctx(void)
11 {
12 return &g_dm_msg_cache_ctx;
13 }
14
_dm_msg_cache_mutex_lock(void)15 static void _dm_msg_cache_mutex_lock(void)
16 {
17 dm_msg_cache_ctx_t *ctx = _dm_msg_cache_get_ctx();
18 if (ctx->mutex) {
19 HAL_MutexLock(ctx->mutex);
20 }
21 }
22
_dm_msg_cache_mutex_unlock(void)23 static void _dm_msg_cache_mutex_unlock(void)
24 {
25 dm_msg_cache_ctx_t *ctx = _dm_msg_cache_get_ctx();
26 if (ctx->mutex) {
27 HAL_MutexUnlock(ctx->mutex);
28 }
29 }
30
dm_msg_cache_init(void)31 int dm_msg_cache_init(void)
32 {
33 dm_msg_cache_ctx_t *ctx = _dm_msg_cache_get_ctx();
34
35 memset(ctx, 0, sizeof(dm_msg_cache_ctx_t));
36
37 /* Create Mutex */
38 ctx->mutex = HAL_MutexCreate();
39 if (ctx->mutex == NULL) {
40 return DM_MEMORY_NOT_ENOUGH;
41 }
42
43 /* Init Message Cache List */
44 INIT_LIST_HEAD(&ctx->dmc_list);
45
46 return SUCCESS_RETURN;
47 }
48
dm_msg_cache_deinit(void)49 int dm_msg_cache_deinit(void)
50 {
51 dm_msg_cache_ctx_t *ctx = _dm_msg_cache_get_ctx();
52 dm_msg_cache_node_t *node = NULL;
53 dm_msg_cache_node_t *next = NULL;
54
55 _dm_msg_cache_mutex_lock();
56 list_for_each_entry_safe(node, next, &ctx->dmc_list, linked_list,
57 dm_msg_cache_node_t)
58 {
59 list_del(&node->linked_list);
60 if (node->data) {
61 DM_free(node->data);
62 }
63 DM_free(node);
64 _dm_msg_cache_mutex_unlock();
65 }
66 _dm_msg_cache_mutex_unlock();
67
68 if (ctx->mutex) {
69 HAL_MutexDestroy(ctx->mutex);
70 }
71
72 return SUCCESS_RETURN;
73 }
74
dm_msg_cache_insert(int msgid,int devid,iotx_dm_event_types_t type,char * data)75 int dm_msg_cache_insert(int msgid, int devid, iotx_dm_event_types_t type,
76 char *data)
77 {
78 dm_msg_cache_ctx_t *ctx = _dm_msg_cache_get_ctx();
79 dm_msg_cache_node_t *node = NULL;
80
81 dm_log_debug("dmc list size: %d", ctx->dmc_list_size);
82 if (ctx->dmc_list_size >= CONFIG_MSGCACHE_QUEUE_MAXLEN) {
83 return FAIL_RETURN;
84 }
85
86 node = DM_malloc(sizeof(dm_msg_cache_node_t));
87 if (node == NULL) {
88 return DM_MEMORY_NOT_ENOUGH;
89 }
90 memset(node, 0, sizeof(dm_msg_cache_node_t));
91
92 node->msgid = msgid;
93 node->devid = devid;
94 node->response_type = type;
95 node->data = data;
96 node->ctime = HAL_UptimeMs();
97 INIT_LIST_HEAD(&node->linked_list);
98
99 _dm_msg_cache_mutex_lock();
100 list_add_tail(&node->linked_list, &ctx->dmc_list);
101 ctx->dmc_list_size++;
102 _dm_msg_cache_mutex_unlock();
103
104 return SUCCESS_RETURN;
105 }
106
dm_msg_cache_search(_IN_ int msgid,_OU_ dm_msg_cache_node_t ** node)107 int dm_msg_cache_search(_IN_ int msgid, _OU_ dm_msg_cache_node_t **node)
108 {
109 dm_msg_cache_ctx_t *ctx = _dm_msg_cache_get_ctx();
110 dm_msg_cache_node_t *search_node = NULL;
111
112 if (msgid < 0 || node == NULL || *node != NULL) {
113 return DM_INVALID_PARAMETER;
114 }
115
116 _dm_msg_cache_mutex_lock();
117 list_for_each_entry(search_node, &ctx->dmc_list, linked_list,
118 dm_msg_cache_node_t)
119 {
120 if (search_node->msgid == msgid) {
121 *node = search_node;
122 _dm_msg_cache_mutex_unlock();
123 return SUCCESS_RETURN;
124 }
125 }
126
127 _dm_msg_cache_mutex_unlock();
128 return FAIL_RETURN;
129 }
130
dm_msg_cache_remove(int msgid)131 int dm_msg_cache_remove(int msgid)
132 {
133 dm_msg_cache_ctx_t *ctx = _dm_msg_cache_get_ctx();
134 dm_msg_cache_node_t *node = NULL;
135 dm_msg_cache_node_t *next = NULL;
136
137 _dm_msg_cache_mutex_lock();
138 list_for_each_entry_safe(node, next, &ctx->dmc_list, linked_list,
139 dm_msg_cache_node_t)
140 {
141 if (node->msgid == msgid) {
142 list_del(&node->linked_list);
143 if (node->data) {
144 DM_free(node->data);
145 }
146 ctx->dmc_list_size--;
147 DM_free(node);
148 dm_log_debug("Remove Message ID: %d", msgid);
149 _dm_msg_cache_mutex_unlock();
150 return SUCCESS_RETURN;
151 }
152 }
153
154 _dm_msg_cache_mutex_unlock();
155 return FAIL_RETURN;
156 }
157
dm_msg_cache_tick(void)158 void dm_msg_cache_tick(void)
159 {
160 dm_msg_cache_ctx_t *ctx = _dm_msg_cache_get_ctx();
161 dm_msg_cache_node_t *node = NULL;
162 dm_msg_cache_node_t *next = NULL;
163 uint64_t current_time = HAL_UptimeMs();
164
165 _dm_msg_cache_mutex_lock();
166 list_for_each_entry_safe(node, next, &ctx->dmc_list, linked_list,
167 dm_msg_cache_node_t)
168 {
169 if (current_time < node->ctime) {
170 node->ctime = current_time;
171 }
172 if (current_time - node->ctime >= DM_MSG_CACHE_TIMEOUT_MS_DEFAULT) {
173 dm_log_debug("Message ID Timeout: %d", node->msgid);
174 /* Send Timeout Message To User */
175 dm_msg_send_msg_timeout_to_user(node->msgid, node->devid,
176 node->response_type);
177 list_del(&node->linked_list);
178 if (node->data) {
179 DM_free(node->data);
180 }
181 DM_free(node);
182 }
183 }
184 _dm_msg_cache_mutex_unlock();
185 }
186 #endif
187