1 /******************************************************************
3 * Copyright 2014 Samsung Electronics All Rights Reserved.
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
11 * http://www.apache.org/licenses/LICENSE-2.0
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.
19 ******************************************************************/
26 #include "cainterface.h"
27 #include "camessagehandler_singlethread.h"
28 #include "caremotehandler.h"
29 #include "cainterfacecontroller_singlethread.h"
30 #include "caprotocolmessage.h"
31 #include "caretransmission_singlethread.h"
33 #include "config.h" /* for coap protocol */
34 #include "oic_malloc.h"
38 #define CA_MAX_RT_ARRAY_SIZE 3
42 SEND_TYPE_MULTICAST = 0, SEND_TYPE_UNICAST
47 CASendDataType_t type;
48 CARemoteEndpoint_t *remoteEndpoint;
49 CARequestInfo_t *requestInfo;
50 CAResponseInfo_t *responseInfo;
51 CAHeaderOption_t *options;
56 static CARetransmission_t g_retransmissionContext;
59 static CARequestCallback g_requestHandler = NULL;
60 static CAResponseCallback g_responseHandler = NULL;
62 static void CATimeoutCallback(const CARemoteEndpoint_t *endpoint, const void *pdu, uint32_t size)
64 OIC_LOG(DEBUG, TAG, "IN");
65 CARemoteEndpoint_t* ep = CACloneRemoteEndpoint(endpoint);
68 OIC_LOG(ERROR, TAG, "clone failed");
72 CAResponseInfo_t* resInfo = (CAResponseInfo_t*) OICCalloc(1, sizeof(CAResponseInfo_t));
76 OIC_LOG(ERROR, TAG, "calloc failed");
77 CADestroyRemoteEndpointInternal(ep);
81 resInfo->result = CA_RETRANSMIT_TIMEOUT;
82 resInfo->info.type = CAGetMessageTypeFromPduBinaryData(pdu, size);
83 resInfo->info.messageId = CAGetMessageIdFromPduBinaryData(pdu, size);
85 if (g_responseHandler)
87 g_responseHandler(ep, resInfo);
90 CADestroyRemoteEndpointInternal(ep);
93 OIC_LOG(DEBUG, TAG, "OUT");
95 static void CAProcessData(const CAData_t *data)
97 OIC_LOG(DEBUG, TAG, "IN");
98 VERIFY_NON_NULL_VOID(data, TAG, "data");
99 VERIFY_NON_NULL_VOID(data->remoteEndpoint, TAG, "remoteEndpoint");
101 CAResult_t res = CA_STATUS_FAILED;
103 CASendDataType_t type = data->type;
105 if (SEND_TYPE_UNICAST == type)
107 coap_pdu_t *pdu = NULL;
109 if (NULL != data->requestInfo)
111 OIC_LOG(DEBUG, TAG, "reqInfo avlbl");
113 pdu = (coap_pdu_t *) CAGeneratePDU(data->remoteEndpoint->resourceUri,
114 data->requestInfo->method,
115 data->requestInfo->info);
117 else if (NULL != data->responseInfo)
119 OIC_LOG(DEBUG, TAG, "resInfo avlbl");
121 pdu = (coap_pdu_t *) CAGeneratePDU(data->remoteEndpoint->resourceUri,
122 data->responseInfo->result,
123 data->responseInfo->info);
127 OIC_LOG(DEBUG, TAG, "request info, response info is empty");
130 // interface controller function call.
135 res = CASendUnicastData(data->remoteEndpoint, pdu->hdr, pdu->length);
136 if (CA_STATUS_OK != res)
138 OIC_LOG_V(ERROR, TAG, "send failed:%d", res);
139 coap_delete_pdu(pdu);
142 // for retransmission
143 res = CARetransmissionSentData(&g_retransmissionContext, data->remoteEndpoint, pdu->hdr,
145 if (CA_STATUS_OK != res)
147 OIC_LOG_V(INFO, TAG, "retransmissions will not be working: %d", res);
148 coap_delete_pdu(pdu);
152 coap_delete_pdu(pdu);
155 else if (SEND_TYPE_MULTICAST == type)
157 OIC_LOG(DEBUG, TAG, "both requestInfo & responseInfo is not available");
159 CAInfo_t info = { 0 };
161 info.options = data->options;
162 info.numOptions = data->numOptions;
163 info.token = data->requestInfo->info.token;
164 info.tokenLength = data->requestInfo->info.tokenLength;
165 info.type = data->requestInfo->info.type;
166 info.messageId = data->requestInfo->info.messageId;
167 info.payload = data->requestInfo->info.payload;
169 coap_pdu_t *pdu = (coap_pdu_t *) CAGeneratePDU(data->remoteEndpoint->resourceUri, CA_GET,
175 res = CASendMulticastData(pdu->hdr, pdu->length);
176 if(CA_STATUS_OK != res)
178 OIC_LOG_V(ERROR, TAG, "send failed:%d", res);
179 coap_delete_pdu(pdu);
183 coap_delete_pdu(pdu);
187 OIC_LOG(DEBUG, TAG, "OUT");
190 static void CAReceivedPacketCallback(CARemoteEndpoint_t *endpoint, void *data, uint32_t dataLen)
192 OIC_LOG(DEBUG, TAG, "IN");
193 VERIFY_NON_NULL_VOID(data, TAG, "data");
195 uint32_t code = CA_NOT_FOUND;
196 coap_pdu_t *pdu = (coap_pdu_t *) CAParsePDU((const char *) data, dataLen, &code);
200 OIC_LOG(ERROR, TAG, "Parse PDU failed");
204 char uri[CA_MAX_URI_LENGTH] = { 0, };
205 uint32_t bufLen = sizeof(uri);
207 if (CA_GET == code || CA_POST == code || CA_PUT == code || CA_DELETE == code)
209 CARequestInfo_t *ReqInfo = (CARequestInfo_t *) OICCalloc(1, sizeof(CARequestInfo_t));
212 OIC_LOG(ERROR, TAG, "CAReceivedPacketCallback, Memory allocation failed!");
213 coap_delete_pdu(pdu);
217 CAResult_t res = CAGetRequestInfoFromPDU(pdu, ReqInfo, uri, bufLen);
218 if (CA_STATUS_OK != res)
220 OIC_LOG_V(ERROR, TAG, "CAGetRequestInfoFromPDU failed : %d", res);
222 coap_delete_pdu(pdu);
226 if (NULL != ReqInfo->info.options)
228 for (uint32_t i = 0; i < ReqInfo->info.numOptions; i++)
230 OIC_LOG_V(DEBUG, TAG, "optionID: %d", ReqInfo->info.options[i].optionID);
232 OIC_LOG_V(DEBUG, TAG, "list: %s", ReqInfo->info.options[i].optionData);
236 if (NULL != ReqInfo->info.payload)
238 OIC_LOG_V(DEBUG, TAG, "Request- payload: %s", ReqInfo->info.payload);
241 OIC_LOG_V(DEBUG, TAG, "code: %d", ReqInfo->method);
242 OIC_LOG(DEBUG, TAG, "token:");
243 OIC_LOG_BUFFER(DEBUG, TAG, (const uint8_t *) ReqInfo->info.token, CA_MAX_TOKEN_LEN);
244 if (NULL != endpoint)
246 endpoint->resourceUri = (char *) OICMalloc(bufLen + 1);
247 if (NULL == endpoint->resourceUri)
249 OIC_LOG(ERROR, TAG, "CAReceivedPacketCallback, Memory allocation failed!");
251 coap_delete_pdu(pdu);
254 memcpy(endpoint->resourceUri, uri, bufLen);
255 endpoint->resourceUri[bufLen] = '\0';
256 OIC_LOG_V(DEBUG, TAG, "URI : %s", endpoint->resourceUri);
261 if (g_requestHandler)
263 g_requestHandler(endpoint, ReqInfo);
266 CADestroyRequestInfoInternal(ReqInfo);
271 CAResponseInfo_t *ResInfo = (CAResponseInfo_t *) OICCalloc(1, sizeof(CAResponseInfo_t));
274 OIC_LOG(ERROR, TAG, "CAReceivedPacketCallback, Memory allocation failed!");
275 coap_delete_pdu(pdu);
279 CAResult_t res = CAGetResponseInfoFromPDU(pdu, ResInfo, uri, bufLen);
280 if (CA_STATUS_OK != res)
282 OIC_LOG_V(ERROR, TAG, "CAGetResponseInfoFromPDU failed : %d", res);
284 coap_delete_pdu(pdu);
288 if (NULL != ResInfo->info.options)
290 for (uint32_t i = 0; i < ResInfo->info.numOptions; i++)
292 OIC_LOG_V(DEBUG, TAG, "optionID: %d", ResInfo->info.options[i].optionID);
294 OIC_LOG_V(DEBUG, TAG, "list: %s", ResInfo->info.options[i].optionData);
298 if (NULL != ResInfo->info.payload)
300 OIC_LOG_V(DEBUG, TAG, "payload: %s", ResInfo->info.payload);
302 OIC_LOG_V(DEBUG, TAG, "code: %d", ResInfo->result);
304 if (NULL != endpoint)
306 endpoint->resourceUri = (char *) OICMalloc(bufLen + 1);
307 if (NULL == endpoint->resourceUri)
309 OIC_LOG(ERROR, TAG, "CAReceivedPacketCallback, Memory allocation failed !");
311 coap_delete_pdu(pdu);
314 memcpy(endpoint->resourceUri, uri, bufLen);
315 endpoint->resourceUri[bufLen] = '\0';
316 OIC_LOG_V(DEBUG, TAG, "URI : %s", endpoint->resourceUri);
319 // for retransmission
320 void *retransmissionPdu = NULL;
321 CARetransmissionReceivedData(&g_retransmissionContext, endpoint, pdu->hdr, pdu->length,
324 // get token from saved data in retransmission list
325 if (retransmissionPdu && CA_EMPTY == code)
327 CAResult_t res = CAGetTokenFromPDU((const coap_hdr_t *)retransmissionPdu,
329 if(res != CA_STATUS_OK)
331 OIC_LOG(ERROR, TAG, "fail to get Token from retransmission list");
332 OICFree(ResInfo->info.token);
335 OICFree(retransmissionPdu);
339 if (g_responseHandler)
341 g_responseHandler(endpoint, ResInfo);
343 CADestroyResponseInfoInternal(ResInfo);
347 if (endpoint && endpoint->resourceUri)
349 OICFree(endpoint->resourceUri);
350 endpoint->resourceUri = NULL;
354 coap_delete_pdu(pdu);
356 OIC_LOG(DEBUG, TAG, "OUT");
359 static void CANetworkChangedCallback(CALocalConnectivity_t *info, CANetworkStatus_t status)
361 OIC_LOG(DEBUG, TAG, "IN");
363 OIC_LOG(DEBUG, TAG, "OUT");
366 void CAHandleRequestResponseCallbacks()
369 CARetransmissionBaseRoutine((void *)&g_retransmissionContext);
372 CAResult_t CADetachRequestMessage(const CARemoteEndpoint_t *object, const CARequestInfo_t *request)
374 OIC_LOG(DEBUG, TAG, "IN");
376 VERIFY_NON_NULL(object, TAG, "object");
377 VERIFY_NON_NULL(request, TAG, "request");
379 // If max retransmission queue is reached, then don't handle new request
380 if (CA_MAX_RT_ARRAY_SIZE == u_arraylist_length(g_retransmissionContext.dataList))
382 OIC_LOG(ERROR, TAG, "max RT queue size reached!");
383 return CA_SEND_FAILED;
386 // allocate & initialize
387 CAData_t *data = (CAData_t *) OICCalloc(1, sizeof(CAData_t));
388 CA_MEMORY_ALLOC_CHECK(data);
391 data->type = SEND_TYPE_UNICAST;
392 data->remoteEndpoint = object;
393 data->requestInfo = request;
394 data->responseInfo = NULL;
398 OIC_LOG(DEBUG, TAG, "OUT");
401 // memory error label.
404 OIC_LOG(DEBUG, TAG, "OUT");
405 return CA_MEMORY_ALLOC_FAILED;
408 CAResult_t CADetachRequestToAllMessage(const CAGroupEndpoint_t *object,
409 const CARequestInfo_t *request)
411 OIC_LOG(DEBUG, TAG, "IN");
413 if (NULL == object || NULL == request || NULL == object->resourceUri)
415 return CA_STATUS_INVALID_PARAM;
418 if ((request->method < CA_GET) || (request->method > CA_DELETE))
420 OIC_LOG(ERROR, TAG, "Invalid method type!");
422 return CA_STATUS_INVALID_PARAM;
425 // allocate & initialize
426 CAData_t *data = (CAData_t *) OICCalloc(1, sizeof(CAData_t));
427 CA_MEMORY_ALLOC_CHECK(data);
429 CAAddress_t addr = {0};
430 CARemoteEndpoint_t *remoteEndpoint = CACreateRemoteEndpointInternal(object->resourceUri, addr,
431 object->connectivityType);
434 data->type = SEND_TYPE_MULTICAST;
435 data->remoteEndpoint = remoteEndpoint;
436 data->requestInfo = request;
437 data->responseInfo = NULL;
440 CADestroyRemoteEndpointInternal(remoteEndpoint);
443 OIC_LOG(DEBUG, TAG, "OUT");
446 // memory error label.
450 OIC_LOG(DEBUG, TAG, "OUT");
451 return CA_MEMORY_ALLOC_FAILED;
454 CAResult_t CADetachResponseMessage(const CARemoteEndpoint_t *object,
455 const CAResponseInfo_t *response)
457 OIC_LOG(DEBUG, TAG, "IN");
458 VERIFY_NON_NULL(object, TAG, "object");
459 VERIFY_NON_NULL(response, TAG, "response");
461 // allocate & initialize
462 CAData_t *data = (CAData_t *) OICCalloc(1, sizeof(CAData_t));
463 CA_MEMORY_ALLOC_CHECK(data);
466 data->type = SEND_TYPE_UNICAST;
467 data->remoteEndpoint = object;
468 data->requestInfo = NULL;
469 data->responseInfo = response;
474 OIC_LOG(DEBUG, TAG, "OUT");
477 // memory error label.
480 OIC_LOG(DEBUG, TAG, "OUT");
482 return CA_MEMORY_ALLOC_FAILED;
485 CAResult_t CADetachMessageResourceUri(const CAURI_t resourceUri, const CAToken_t token,
486 uint8_t tokenLength, const CAHeaderOption_t *options,
489 OIC_LOG(DEBUG, TAG, "IN");
490 VERIFY_NON_NULL(resourceUri, TAG, "resourceUri is NULL");
491 VERIFY_NON_NULL(token, TAG, "Token is NULL");
493 // allocate & initialize
494 CAData_t *data = (CAData_t *) OICCalloc(1, sizeof(CAData_t));
495 CA_MEMORY_ALLOC_CHECK(data);
497 CAAddress_t addr = {0};
498 CARemoteEndpoint_t *remoteEndpoint =
499 CACreateRemoteEndpointInternal(resourceUri, addr,
500 CA_ETHERNET | CA_WIFI | CA_EDR | CA_LE);
502 // create request info
503 CARequestInfo_t *reqInfo = (CARequestInfo_t *) OICCalloc(1, sizeof(CARequestInfo_t));
504 CA_MEMORY_ALLOC_CHECK(reqInfo);
506 // save request info data
507 reqInfo->method = CA_GET;
508 reqInfo->info.type = CA_MSG_NONCONFIRM;
510 reqInfo->info.token = token;
511 reqInfo->info.tokenLength = tokenLength;
514 data->type = SEND_TYPE_MULTICAST;
515 data->remoteEndpoint = remoteEndpoint;
516 data->requestInfo = reqInfo;
518 data->responseInfo = NULL;
519 data->options = NULL;
520 data->numOptions = 0;
521 CAHeaderOption_t *headerOption = NULL;
522 if (NULL != options && numOptions > 0)
525 headerOption = (CAHeaderOption_t *) OICMalloc(sizeof(CAHeaderOption_t) * numOptions);
526 CA_MEMORY_ALLOC_CHECK(headerOption);
527 memcpy(headerOption, options, sizeof(CAHeaderOption_t) * numOptions);
529 data->options = headerOption;
530 data->numOptions = numOptions;
535 CADestroyRemoteEndpoint(remoteEndpoint);
536 OICFree(headerOption);
539 OIC_LOG(DEBUG, TAG, "OUT");
542 // memory error label.
545 CADestroyRemoteEndpointInternal(remoteEndpoint);
549 OIC_LOG(DEBUG, TAG, "OUT");
550 return CA_MEMORY_ALLOC_FAILED;
553 void CASetRequestResponseCallbacks(CARequestCallback ReqHandler, CAResponseCallback RespHandler)
555 OIC_LOG(DEBUG, TAG, "IN");
556 g_requestHandler = ReqHandler;
557 g_responseHandler = RespHandler;
558 OIC_LOG(DEBUG, TAG, "OUT");
561 CAResult_t CAInitializeMessageHandler()
563 OIC_LOG(DEBUG, TAG, "IN");
564 CASetPacketReceivedCallback(CAReceivedPacketCallback);
566 CASetNetworkChangeCallback(CANetworkChangedCallback);
568 // retransmission initialize
569 CARetransmissionInitialize(&g_retransmissionContext, CASendUnicastData,
570 CATimeoutCallback, NULL);
572 CAInitializeAdapters();
573 OIC_LOG(DEBUG, TAG, "OUT");
577 void CATerminateMessageHandler()
579 OIC_LOG(DEBUG, TAG, "IN");
580 // terminate interface adapters by controller
581 CATerminateAdapters();
583 // stop retransmission
584 CARetransmissionStop(&g_retransmissionContext);
585 CARetransmissionDestroy(&g_retransmissionContext);
587 OIC_LOG(DEBUG, TAG, "OUT");
590 void CALogPDUInfo(coap_pdu_t *pdu)
592 VERIFY_NON_NULL_VOID(pdu, TAG, "pdu");
594 OIC_LOG_V(DEBUG, TAG, "PDU Maker - payload : %s", pdu->data);
596 OIC_LOG_V(DEBUG, TAG, "PDU Maker - type : %d", pdu->hdr->type);
598 OIC_LOG_V(DEBUG, TAG, "PDU Maker - code : %d", pdu->hdr->code);
600 OIC_LOG_V(DEBUG, TAG, "PDU Maker - id : %d", ntohs(pdu->hdr->id));
602 OIC_LOG(DEBUG, TAG, "PDU Maker - token :");
604 OIC_LOG_BUFFER(DEBUG, TAG, pdu->hdr->token, pdu->hdr->token_length);