1 /*
2 * Copyright (C) 2015-2018 Alibaba Group Holding Limited
3 */
4
5
6
7
8 #include <stdio.h>
9 #include <stdlib.h>
10 #include <string.h>
11 #include "ctype.h"
12 #include "iotx_coap_internal.h"
13 #include "CoAPPlatform.h"
14 #include "CoAPInternal.h"
15 #include "CoAPNetwork.h"
16 #include "CoAPExport.h"
17 #include "CoAPObserve.h"
18
19 #define COAP_DEFAULT_PORT 5683 /* CoAP default UDP port */
20 #define COAPS_DEFAULT_PORT \
21 5684 /* CoAP default UDP port for secure transmission */
22 #define COAP_DEFAULT_SENDLIST_MAXCOUNT 8
23 #define COAP_DEFAULT_RES_MAXCOUNT 8
24 #define COAP_DEFAULT_OBS_MAXCOUNT 8
25
26 #define COAP_DEFAULT_SCHEME "coap" /* the default scheme for CoAP URIs */
27 #define COAP_DEFAULT_HOST_LEN 128
28 #define COAP_DEFAULT_WAIT_TIME_MS 2000
29
CoAPContext_create(CoAPInitParam * param)30 CoAPContext *CoAPContext_create(CoAPInitParam *param)
31 {
32 CoAPIntContext *p_ctx = NULL;
33 NetworkInit network_param;
34
35 memset(&network_param, 0x00, sizeof(NetworkInit));
36 p_ctx = coap_malloc(sizeof(CoAPIntContext));
37 if (NULL == p_ctx) {
38 COAP_ERR("malloc for coap context failed");
39 goto err;
40 }
41 COAP_DEBUG("Send List Max-Count: %d", param->send_maxcount);
42 COAP_DEBUG("Observe Server Max-Count: %d", param->obs_maxcount);
43 COAP_DEBUG("Observe Client Max-Count: %d", param->obs_maxcount);
44 COAP_DEBUG("Resource Max-Count: %d", param->res_maxcount);
45 COAP_DEBUG("MultiCast Address: %s:%d", param->group, param->port);
46 COAP_DEBUG("Send/Recv Wait time: %dms", param->waittime);
47
48 memset(p_ctx, 0, sizeof(CoAPIntContext));
49 p_ctx->message_id = 1;
50 p_ctx->notifier = param->notifier;
51 p_ctx->appdata = param->appdata;
52
53 #ifdef USE_SENDBUFF
54 p_ctx->sendbuf = coap_malloc(COAP_MSG_MAX_PDU_LEN);
55 if (NULL == p_ctx->sendbuf) {
56 COAP_ERR("not enough memory");
57 goto err;
58 }
59 memset(p_ctx->sendbuf, 0x00, COAP_MSG_MAX_PDU_LEN);
60 #endif
61
62 p_ctx->recvbuf = coap_malloc(COAP_MSG_MAX_PDU_LEN);
63 if (NULL == p_ctx->recvbuf) {
64 COAP_ERR("not enough memory");
65 goto err;
66 }
67 memset(p_ctx->recvbuf, 0x00, COAP_MSG_MAX_PDU_LEN);
68
69 if (0 == param->waittime) {
70 p_ctx->waittime = COAP_DEFAULT_WAIT_TIME_MS;
71 } else {
72 p_ctx->waittime = param->waittime;
73 }
74 p_ctx->mutex = HAL_MutexCreate();
75 if (NULL == p_ctx->mutex) {
76 COAP_ERR("Mutex Create failed");
77 goto err;
78 }
79
80 /*Init message send list mutex*/
81 p_ctx->sendlist.list_mutex = HAL_MutexCreate();
82 HAL_MutexLock(p_ctx->sendlist.list_mutex);
83 /*CoAP message send list*/
84 INIT_LIST_HEAD(&p_ctx->sendlist.list);
85 p_ctx->sendlist.count = 0;
86 HAL_MutexUnlock(p_ctx->sendlist.list_mutex);
87
88 if (0 != param->send_maxcount) {
89 p_ctx->sendlist.maxcount = param->send_maxcount;
90 } else {
91 p_ctx->sendlist.maxcount = COAP_DEFAULT_SENDLIST_MAXCOUNT;
92 }
93
94 if (0 == param->res_maxcount) {
95 param->res_maxcount = COAP_DEFAULT_RES_MAXCOUNT;
96 }
97 CoAPResource_init(p_ctx, param->res_maxcount);
98
99 #ifndef COAP_OBSERVE_SERVER_DISABLE
100 if (0 == param->obs_maxcount) {
101 param->obs_maxcount = COAP_DEFAULT_OBS_MAXCOUNT;
102 }
103 CoAPObsServer_init(p_ctx, param->obs_maxcount);
104 #endif
105
106 #ifndef COAP_OBSERVE_CLIENT_DISABLE
107 if (0 == param->obs_maxcount) {
108 param->obs_maxcount = COAP_DEFAULT_OBS_MAXCOUNT;
109 }
110 CoAPObsClient_init(p_ctx, param->obs_maxcount);
111 #endif
112
113 #ifdef COAP_DTLS_SUPPORT
114 network_param.type = COAP_NETWORK_DTLS;
115 network_param.port = COAPS_DEFAULT_PORT;
116 #else
117 network_param.type = COAP_NETWORK_NOSEC;
118 network_param.port = param->port;
119 network_param.group = param->group;
120 #endif
121
122 /*CoAP network init*/
123 p_ctx->p_network = CoAPNetwork_init(&network_param);
124
125 if (NULL == p_ctx->p_network) {
126 COAP_ERR("CoAP Network init failed, exit");
127 goto err;
128 }
129
130 return p_ctx;
131 err:
132 if (NULL == p_ctx) {
133 return p_ctx;
134 }
135
136 if (NULL != p_ctx->recvbuf) {
137 coap_free(p_ctx->recvbuf);
138 p_ctx->recvbuf = NULL;
139 }
140
141 #ifdef USE_SENDBUFF
142 if (NULL != p_ctx->sendbuf) {
143 coap_free(p_ctx->sendbuf);
144 p_ctx->sendbuf = NULL;
145 }
146 #endif
147
148 #ifndef COAP_OBSERVE_SERVER_DISABLE
149 CoAPObsServer_deinit(p_ctx);
150 #endif
151
152 #ifndef COAP_OBSERVE_CLIENT_DISABLE
153 CoAPObsClient_deinit(p_ctx);
154 #endif
155
156 CoAPResource_deinit(p_ctx);
157
158 if (NULL != p_ctx->sendlist.list_mutex) {
159 HAL_MutexDestroy(p_ctx->sendlist.list_mutex);
160 p_ctx->sendlist.list_mutex = NULL;
161 }
162
163 if (NULL != p_ctx->mutex) {
164 HAL_MutexDestroy(p_ctx->mutex);
165 p_ctx->mutex = NULL;
166 }
167
168 coap_free(p_ctx);
169 p_ctx = NULL;
170
171 /* TODO: release the resource */
172 return (CoAPContext *)p_ctx;
173 }
174
CoAPContextAppdata_get(CoAPContext * context)175 void *CoAPContextAppdata_get(CoAPContext *context)
176 {
177 CoAPIntContext *p_ctx = (CoAPIntContext *)context;
178 if (NULL == p_ctx) {
179 return NULL;
180 }
181
182 return (void *)p_ctx->appdata;
183 }
184
CoAPContext_free(CoAPContext * context)185 void CoAPContext_free(CoAPContext *context)
186 {
187 CoAPIntContext *p_ctx = NULL;
188 CoAPSendNode *cur = NULL, *next = NULL;
189 if (NULL == context) {
190 return;
191 }
192
193 p_ctx = (CoAPIntContext *)context;
194
195 CoAPNetwork_deinit(p_ctx->p_network);
196 COAP_DEBUG("CoAP Network Deinit");
197
198 HAL_MutexLock(p_ctx->sendlist.list_mutex);
199 list_for_each_entry_safe(cur, next, &p_ctx->sendlist.list, sendlist,
200 CoAPSendNode)
201 {
202 if (NULL != cur) {
203 if (NULL != cur->message) {
204 coap_free(cur->message);
205 cur->message = NULL;
206 }
207 coap_free(cur);
208 cur = NULL;
209 }
210 }
211 INIT_LIST_HEAD(&p_ctx->sendlist.list);
212 HAL_MutexUnlock(p_ctx->sendlist.list_mutex);
213 HAL_MutexDestroy(p_ctx->sendlist.list_mutex);
214 p_ctx->sendlist.list_mutex = NULL;
215 HAL_MutexDestroy(p_ctx->mutex);
216 p_ctx->mutex = NULL;
217 COAP_DEBUG("Release Send List and Memory");
218
219 #ifndef COAP_OBSERVE_SERVER_DISABLE
220 CoAPObsServer_deinit(p_ctx);
221 COAP_DEBUG("CoAP Observe Server Deinit");
222 #endif
223
224 #ifndef COAP_OBSERVE_CLIENT_DISABLE
225 CoAPObsClient_deinit(p_ctx);
226 COAP_DEBUG("CoAP Observe Client Deinit");
227 #endif
228
229 CoAPResource_deinit(p_ctx);
230 COAP_DEBUG("CoAP Resource unregister");
231
232 if (NULL != p_ctx->recvbuf) {
233 coap_free(p_ctx->recvbuf);
234 p_ctx->recvbuf = NULL;
235 COAP_DEBUG("Release The Recv Memory");
236 }
237 #ifdef USE_SENDBUFF
238 if (NULL != p_ctx->sendbuf) {
239 coap_free(p_ctx->sendbuf);
240 p_ctx->sendbuf = NULL;
241 COAP_DEBUG("Release The Send Memory");
242 }
243 #endif
244
245 if (NULL != p_ctx) {
246 coap_free(p_ctx);
247 p_ctx = NULL;
248 COAP_DEBUG("Release The CoAP Context");
249 }
250 }
251