Implementation of connectivity abstraction feature Release v0.3
[platform/upstream/iotivity.git] / resource / csdk / connectivity / src / camessagehandler_singlethread.c
1 /******************************************************************
2  *
3  * Copyright 2014 Samsung Electronics All Rights Reserved.
4  *
5  *
6  *
7  * Licensed under the Apache License, Version 2.0 (the "License");
8  * you may not use this file except in compliance with the License.
9  * You may obtain a copy of the License at
10  *
11  *      http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing, software
14  * distributed under the License is distributed on an "AS IS" BASIS,
15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16  * See the License for the specific language governing permissions and
17  * limitations under the License.
18  *
19  ******************************************************************/
20
21 #include "camessagehandler_singlethread.h"
22
23 #include <stdio.h>
24 #include <stdlib.h>
25 #include <string.h>
26 #include <stdint.h>
27
28 #include "cainterface.h"
29 #include "caremotehandler.h"
30 #include "cainterfacecontroller_singlethread.h"
31 #include "caprotocolmessage.h"
32 #include "logger.h"
33 #include "config.h" /* for coap protocol */
34 #include "coap.h"
35 #include "oic_malloc.h"
36 #include "caadapterutils.h"
37
38 #define TAG1 "CAMH_ST"
39
40 #define MEMORY_ALLOCK_CHECK(arg) { if (arg == NULL) {OIC_LOG_V(DEBUG, TAG1, "Out of memory"); goto memory_error_exit;} }
41
42 #define MAX_THREAD_POOL_SIZE    10
43
44 typedef enum
45 {
46     SEND_TYPE_MULTICAST = 0, SEND_TYPE_UNICAST
47 } CASendDataType_t;
48
49 typedef struct
50 {
51     CASendDataType_t type;
52     CARemoteEndpoint_t *remoteEndpoint;
53     CARequestInfo_t *requestInfo;
54     CAResponseInfo_t *responseInfo;
55     CAHeaderOption_t *options;
56     uint8_t numOptions;
57 } CAData_t;
58
59 // message handler callback
60 static CAMessageHandlerCallback gHandlerCallback = NULL;
61
62 // handler field
63 static CARequestCallback gRequestHandler = NULL;
64 static CAResponseCallback gResponseHandler = NULL;
65
66 static void CAProcessData(CAData_t *data)
67 {
68     OIC_LOG(DEBUG, TAG1, "IN");
69     VERIFY_NON_NULL_VOID(data, TAG1, "data");
70     VERIFY_NON_NULL_VOID(data->remoteEndpoint, TAG1, "remoteendpoint");
71
72     CAResult_t res = CA_STATUS_FAILED;
73
74     CASendDataType_t type = data->type;
75
76     if (type == SEND_TYPE_UNICAST)
77     {
78         coap_pdu_t *pdu = NULL;
79
80         if (data->requestInfo != NULL)
81         {
82             OIC_LOG_V(DEBUG, TAG1, "reqInfo avlbl");
83
84             pdu = (coap_pdu_t *) CAGeneratePdu(data->remoteEndpoint->resourceUri,
85                                                data->requestInfo->method, data->requestInfo->info);
86         }
87         else if (data->responseInfo != NULL)
88         {
89             OIC_LOG_V(DEBUG, TAG1, "resInfo avlbl");
90
91             pdu = (coap_pdu_t *) CAGeneratePdu(data->remoteEndpoint->resourceUri,
92                                                data->responseInfo->result, data->responseInfo->info);
93         }
94         else
95         {
96             OIC_LOG(DEBUG, TAG1, "request info, response info is empty");
97         }
98
99         // interface controller function call.
100         if (NULL != pdu)
101         {
102             OIC_LOG_V(DEBUG, TAG1, "payload: %s", pdu->data);
103
104             OIC_LOG_V(DEBUG, TAG1, "code: %d", pdu->hdr->code);
105
106             OIC_LOG_V(DEBUG, TAG1, "buffer: %s", pdu->hdr);
107
108             res = CASendUnicastData(data->remoteEndpoint, pdu->hdr, pdu->length);
109         }
110
111     }
112     else if (type == SEND_TYPE_MULTICAST)
113     {
114         OIC_LOG(DEBUG, TAG1, "both requestInfo & responseInfo is not available");
115
116         coap_pdu_t *pdu = NULL;
117         CAInfo_t info;
118         memset(&info, 0, sizeof(CAInfo_t));
119
120         info.options = data->options;
121         info.numOptions = data->numOptions;
122         info.token = data->requestInfo->info.token;
123
124         pdu = (coap_pdu_t *) CAGeneratePdu(data->remoteEndpoint->resourceUri, CA_GET, info);
125
126         if (NULL != pdu)
127         {
128             OIC_LOG_V(DEBUG, TAG1, "PDU Maker - payload : %s", pdu->data);
129
130             OIC_LOG_V(DEBUG, TAG1, "PDU Maker - type : %d", pdu->hdr->type);
131
132             OIC_LOG_V(DEBUG, TAG1, "PDU Maker - code : %d", pdu->hdr->code);
133
134             OIC_LOG_V(DEBUG, TAG1, "PDU Maker - id : %d", pdu->hdr->id);
135
136             OIC_LOG_V(DEBUG, TAG1, "PDU Maker - token : %s", pdu->hdr->token);
137             OIC_LOG_V(DEBUG, TAG1, "PDU Maker - buffer data : %s", pdu->hdr);
138
139             res = CASendMulticastData(pdu->hdr, pdu->length);
140         }
141     }
142     else
143     {
144         OIC_LOG(DEBUG, TAG1, "unknown type!");
145     }
146
147     if (gHandlerCallback != NULL)
148     {
149         gHandlerCallback("", res);
150     }
151     OIC_LOG(DEBUG, TAG1, "OUT");
152 }
153
154 static void CAReceivedPacketCallback(CARemoteEndpoint_t *endpoint, void *data, uint32_t dataLen)
155 {
156     OIC_LOG(DEBUG, TAG1, "IN");
157     VERIFY_NON_NULL_VOID(data, TAG1, "data");
158
159     coap_pdu_t *pdu;
160     uint32_t code = CA_NOT_FOUND;
161     pdu = (coap_pdu_t *) CAParsePDU((const char *) data, &code);
162     //OICFree(data);
163
164     char uri[CA_MAX_URI_LENGTH] = { 0, };
165
166     if (CA_GET == code || CA_POST == code  || CA_PUT == code  || CA_DELETE == code )
167     {
168         CARequestInfo_t *ReqInfo;
169         ReqInfo = (CARequestInfo_t *) OICMalloc(sizeof(CARequestInfo_t));
170         VERIFY_NON_NULL_VOID(ReqInfo, TAG1, "reqInfo");
171         memset(ReqInfo, 0, sizeof(CARequestInfo_t));
172         CAGetRequestInfoFromPdu(pdu, ReqInfo, uri);
173
174         if (NULL != ReqInfo->info.options)
175         {
176             uint32_t i;
177             for (i = 0; i < ReqInfo->info.numOptions; i++)
178             {
179                 OIC_LOG_V(DEBUG, TAG1, "Request- optionID: %d", ReqInfo->info.options[i].optionID);
180
181                 OIC_LOG_V(DEBUG, TAG1, "Request- list: %s", ReqInfo->info.options[i].optionData);
182             }
183         }
184
185         if(NULL != ReqInfo->info.payload)
186         {
187             OIC_LOG_V(DEBUG, TAG1, "Request- payload: %s", ReqInfo->info.payload);
188         }
189
190         OIC_LOG_V(DEBUG, TAG1, "Request- code: %d", ReqInfo->method);
191         OIC_LOG_V(DEBUG, TAG1, "Request- token : %s", ReqInfo->info.token);
192
193         if (NULL != endpoint)
194         {
195             endpoint->resourceUri = (char *) OICMalloc(strlen(uri) + 1);
196             memset(endpoint->resourceUri, 0, strlen(uri) + 1);
197             memcpy(endpoint->resourceUri, uri, strlen(uri));
198             OIC_LOG_V(DEBUG, TAG1, "URI : %s", endpoint->resourceUri);
199         }
200
201         if (ReqInfo)
202         {
203             if (gRequestHandler)
204             {
205                 gRequestHandler(endpoint, ReqInfo);
206             }
207
208             CADestroyRequestInfoInternal(ReqInfo);
209         }
210     }
211     else
212     {
213         CAResponseInfo_t *ResInfo = (CAResponseInfo_t *) OICMalloc(sizeof(CAResponseInfo_t));
214         VERIFY_NON_NULL_VOID(ResInfo, TAG1, "ResInfo");
215         memset(ResInfo, 0, sizeof(CAResponseInfo_t));
216         CAGetResponseInfoFromPdu(pdu, ResInfo, uri);
217
218         if (NULL != ResInfo->info.options)
219         {
220             uint32_t i;
221             for (i = 0; i < ResInfo->info.numOptions; i++)
222             {
223                 OIC_LOG_V(DEBUG, TAG1, "optionID: %d", ResInfo->info.options[i].optionID);
224
225                 OIC_LOG_V(DEBUG, TAG1, "list: %s", ResInfo->info.options[i].optionData);
226             }
227
228             if(NULL != ResInfo->info.payload)
229             {
230                 OIC_LOG_V(DEBUG, TAG1, "payload: %s", ResInfo->info.payload);
231             }
232
233             OIC_LOG_V(DEBUG, TAG1, "code: %d", ResInfo->result);
234         }
235
236         if (NULL != endpoint)
237         {
238             endpoint->resourceUri = (char *) OICMalloc(strlen(uri) + 1);
239             memset(endpoint->resourceUri, 0, strlen(uri) + 1);
240             memcpy(endpoint->resourceUri, uri, strlen(uri));
241             OIC_LOG_V(DEBUG, TAG1, "URI : %s", endpoint->resourceUri);
242         }
243
244         if (ResInfo != NULL)
245         {
246             if (gResponseHandler)
247             {
248                 gResponseHandler(endpoint, ResInfo);
249             }
250             CADestroyResponseInfoInternal(ResInfo);
251         }
252     }
253
254     if (endpoint && endpoint->resourceUri)
255     {
256         OICFree(endpoint->resourceUri);
257     }
258     OIC_LOG(DEBUG, TAG1, "OUT");
259 }
260
261 static void CANetworkChangedCallback(CALocalConnectivity_t *info, CANetworkStatus_t status)
262 {
263     OIC_LOG(DEBUG, TAG1, "IN");
264     OIC_LOG(DEBUG, TAG1, "OUT");
265 }
266
267 void CAHandleRequestResponseCallbacks()
268 {
269     //OIC_LOG(DEBUG, TAG1, "IN");
270
271     CAReadData();
272
273     //OIC_LOG(DEBUG, TAG1, "OUT");
274 }
275
276 CAResult_t CADetachRequestMessage(const CARemoteEndpoint_t *object, const CARequestInfo_t *request)
277 {
278     OIC_LOG(DEBUG, TAG1, "IN");
279
280     VERIFY_NON_NULL(object, TAG1, "object");
281     VERIFY_NON_NULL(request, TAG1, "request");
282
283     CAData_t *data = (CAData_t *) OICMalloc(sizeof(CAData_t));
284     MEMORY_ALLOCK_CHECK(data);
285
286     // initialize
287     memset(data, 0, sizeof(CAData_t));
288
289     // clone remote endpoint
290     CARemoteEndpoint_t *remoteEndpoint = CACloneRemoteEndpoint(object);
291     MEMORY_ALLOCK_CHECK(remoteEndpoint);
292
293     // clone request info
294     CARequestInfo_t *requestInfo = CACloneRequestInfo(request);
295     MEMORY_ALLOCK_CHECK(requestInfo);
296
297     // save data
298     data->type = SEND_TYPE_UNICAST;
299     data->remoteEndpoint = remoteEndpoint;
300     data->requestInfo = requestInfo;
301     data->responseInfo = NULL;
302
303     CAProcessData(data);
304     CADestroyRemoteEndpoint(remoteEndpoint);
305     CADestroyRequestInfoInternal(requestInfo);
306     OICFree(data);
307     OIC_LOG(DEBUG, TAG1, "OUT");
308     return CA_STATUS_OK;
309
310     // memory error label.
311 memory_error_exit:
312
313     CADestroyRemoteEndpointInternal(remoteEndpoint);
314
315     CADestroyRequestInfoInternal(requestInfo);
316
317     if (data != NULL)
318     {
319         OICFree(data);
320     }
321     OIC_LOG(DEBUG, TAG1, "OUT");
322     return CA_MEMORY_ALLOC_FAILED;
323 }
324
325 CAResult_t CADetachResponseMessage(const CARemoteEndpoint_t *object,
326                                    const CAResponseInfo_t *response)
327 {
328     OIC_LOG(DEBUG, TAG1, "IN");
329     VERIFY_NON_NULL(object, TAG1, "object");
330     VERIFY_NON_NULL(response, TAG1, "response");
331
332     CAData_t *data = (CAData_t *) OICMalloc(sizeof(CAData_t));
333     MEMORY_ALLOCK_CHECK(data);
334
335     // initialize
336     memset(data, 0, sizeof(CAData_t));
337
338     // clone remote endpoint
339     CARemoteEndpoint_t *remoteEndpoint = CACloneRemoteEndpoint(object);
340     MEMORY_ALLOCK_CHECK(remoteEndpoint);
341
342     // clone response info
343     CAResponseInfo_t *responseInfo = CACloneResponseInfo(response);
344     MEMORY_ALLOCK_CHECK(responseInfo);
345
346     // save data
347     data->type = SEND_TYPE_UNICAST;
348     data->remoteEndpoint = remoteEndpoint;
349     data->requestInfo = NULL;
350     data->responseInfo = responseInfo;
351
352     CAProcessData(data);
353     CADestroyRemoteEndpoint(remoteEndpoint);
354     CADestroyResponseInfoInternal(responseInfo);
355     OICFree(data);
356     OIC_LOG(DEBUG, TAG1, "OUT");
357     return CA_STATUS_OK;
358
359     // memory error label.
360 memory_error_exit:
361
362     CADestroyRemoteEndpointInternal(remoteEndpoint);
363
364     CADestroyResponseInfoInternal(responseInfo);
365
366     if (data != NULL)
367     {
368         OICFree(data);
369     }
370     OIC_LOG(DEBUG, TAG1, "OUT");
371     return CA_MEMORY_ALLOC_FAILED;
372 }
373
374 CAResult_t CADetachMessageResourceUri(const CAURI_t resourceUri, const CAToken_t token, const CAHeaderOption_t* options,
375                                       uint8_t numOptions)
376 {
377     OIC_LOG(DEBUG, TAG1, "IN");
378     if (resourceUri == NULL)
379     {
380         return CA_STATUS_FAILED;
381     }
382
383     CAData_t *data = (CAData_t *) OICMalloc(sizeof(CAData_t));
384     MEMORY_ALLOCK_CHECK(data);
385
386     // initialize
387     memset(data, 0, sizeof(CAData_t));
388
389     CAAddress_t addr;
390     memset(&addr, 0, sizeof(CAAddress_t));
391     CARemoteEndpoint_t *remoteEndpoint = CACreateRemoteEndpointInternal(resourceUri, addr,
392                                          CA_ETHERNET | CA_WIFI | CA_EDR | CA_LE);
393
394     // save data
395     data->type = SEND_TYPE_MULTICAST;
396     data->remoteEndpoint = remoteEndpoint;
397     CARequestInfo_t* ReqInfo = (CARequestInfo_t*) OICMalloc(sizeof(CARequestInfo_t));
398     memset(ReqInfo, 0, sizeof(CARequestInfo_t));
399     ReqInfo->method = CA_GET;
400     ReqInfo->info.token = token;
401     data->requestInfo = ReqInfo;
402
403     data->responseInfo = NULL;
404     data->options = NULL;
405     data->numOptions = 0;
406
407     if (options != NULL && numOptions > 0)
408     {
409         // copy data
410         CAHeaderOption_t *temp = (CAHeaderOption_t *) OICMalloc(
411                                      sizeof(CAHeaderOption_t) * numOptions);
412
413         MEMORY_ALLOCK_CHECK(temp);
414
415         memset(temp, 0, sizeof(CAHeaderOption_t) * numOptions);
416         memcpy(temp, options, sizeof(CAHeaderOption_t) * numOptions);
417
418         data->options = temp;
419         data->numOptions = numOptions;
420     }
421
422     CAProcessData(data);
423     CADestroyRemoteEndpoint(remoteEndpoint);
424     OICFree(data);
425     OICFree(ReqInfo);
426     OIC_LOG(DEBUG, TAG1, "OUT");
427     return CA_STATUS_OK;
428
429     // memory error label.
430 memory_error_exit:
431
432     CADestroyRemoteEndpointInternal(remoteEndpoint);
433
434     if (data != NULL)
435     {
436         OICFree(data);
437     }
438     OIC_LOG(DEBUG, TAG1, "OUT");
439     return CA_MEMORY_ALLOC_FAILED;
440 }
441
442 void CASetMessageHandlerCallback(CAMessageHandlerCallback callback)
443 {
444     OIC_LOG(DEBUG, TAG1, "IN");
445     gHandlerCallback = callback;
446     OIC_LOG(DEBUG, TAG1, "OUT");
447 }
448
449 void CASetRequestResponseCallbacks(CARequestCallback ReqHandler, CAResponseCallback RespHandler)
450 {
451     OIC_LOG(DEBUG, TAG1, "IN");
452     gRequestHandler = ReqHandler;
453     gResponseHandler = RespHandler;
454     OIC_LOG(DEBUG, TAG1, "OUT");
455 }
456
457 CAResult_t CAInitializeMessageHandler()
458 {
459     OIC_LOG(DEBUG, TAG1, "IN");
460     CASetPacketReceivedCallback(CAReceivedPacketCallback);
461
462     CASetNetworkChangeCallback(CANetworkChangedCallback);
463
464     CAInitializeAdapters();
465     OIC_LOG(DEBUG, TAG1, "OUT");
466     return CA_STATUS_OK;
467 }
468
469 void CATerminateMessageHandler()
470 {
471     OIC_LOG(DEBUG, TAG1, "IN");
472     // terminate interface adapters by controller
473     CATerminateAdapters();
474
475     OIC_LOG(DEBUG, TAG1, "OUT");
476 }
477