1 /* ****************************************************************
3 * Copyright 2015 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 ******************************************************************/
21 // Defining _BSD_SOURCE or _DEFAULT_SOURCE causes header files to expose
22 // definitions that may otherwise be skipped. Skipping can cause implicit
23 // declaration warnings and/or bugs and subtle problems in code execution.
24 // For glibc information on feature test macros,
25 // Refer http://www.gnu.org/software/libc/manual/html_node/Feature-Test-Macros.html
27 // This file requires #define use due to random()
28 // For details on compatibility and glibc support,
29 // Refer http://www.gnu.org/software/libc/manual/html_node/BSD-Random.html
30 #define _DEFAULT_SOURCE
37 #include "caadapterutils.h"
38 #include "cainterface.h"
39 #include "camessagehandler.h"
40 #include "caremotehandler.h"
41 #include "cablockwisetransfer.h"
42 #include "oic_malloc.h"
48 #define BLOCKWISE_OPTION_BUFFER 3
49 #define BLOCK_NUMBER_IDX 4
50 #define BLOCK_M_BIT_IDX 3
52 #define BLOCK_SIZE(arg) (1 << ((arg) + 4))
54 // context for block-wise transfer
55 static CABlockWiseContext_t g_context = { 0 };
57 CAResult_t CAInitializeBlockWiseTransfer(CASendThreadFunc sendThreadFunc,
58 CAReceiveThreadFunc receivedThreadFunc)
60 OIC_LOG(DEBUG, TAG, "initialize");
62 // set block-wise transfer context
63 if (!g_context.sendThreadFunc)
65 g_context.sendThreadFunc = sendThreadFunc;
68 if (!g_context.receivedThreadFunc)
70 g_context.receivedThreadFunc = receivedThreadFunc;
73 if (!g_context.dataList)
75 g_context.dataList = u_arraylist_create();
78 CAResult_t res = CAInitBlockWiseMutexVariables();
79 if (CA_STATUS_OK != res)
81 OIC_LOG(ERROR, TAG, "init has failed");
87 CAResult_t CATerminateBlockWiseTransfer()
89 OIC_LOG(DEBUG, TAG, "terminate");
91 if (g_context.dataList)
93 u_arraylist_free(&g_context.dataList);
96 CATerminateBlockWiseMutexVariables();
101 CAResult_t CAInitBlockWiseMutexVariables()
103 OIC_LOG(DEBUG, TAG, "IN");
105 if (NULL == g_context.blockDataListMutex)
107 g_context.blockDataListMutex = ca_mutex_new();
108 if (NULL == g_context.blockDataListMutex)
110 OIC_LOG(ERROR, TAG, "ca_mutex_new has failed");
111 return CA_STATUS_FAILED;
115 if (NULL == g_context.blockDataSenderMutex)
117 g_context.blockDataSenderMutex = ca_mutex_new();
118 if (NULL == g_context.blockDataSenderMutex)
120 OIC_LOG(ERROR, TAG, "ca_mutex_new has failed");
121 CATerminateBlockWiseMutexVariables();
122 return CA_STATUS_FAILED;
129 void CATerminateBlockWiseMutexVariables()
131 OIC_LOG(DEBUG, TAG, "IN");
133 if (g_context.blockDataListMutex)
135 ca_mutex_free(g_context.blockDataListMutex);
136 g_context.blockDataListMutex = NULL;
139 if (g_context.blockDataSenderMutex)
141 ca_mutex_free(g_context.blockDataSenderMutex);
142 g_context.blockDataSenderMutex = NULL;
146 CAResult_t CASendBlockWiseData(const CAData_t *sendData)
148 VERIFY_NON_NULL(sendData, TAG, "sendData");
150 // check if message type is CA_MSG_RESET
151 if (NULL != sendData->responseInfo)
153 if (CA_MSG_RESET == sendData->responseInfo->info.type)
155 OIC_LOG(DEBUG, TAG, "reset message can't be sent to the block");
156 return CA_NOT_SUPPORTED;
160 // #1. check if it is already included in block data list
161 CABlockData_t *currData = NULL;
162 CAResult_t res = CACheckBlockDataValidation(sendData, &currData);
163 if (CA_STATUS_OK != res)
165 // #2. if it is not included, add the data into list
166 if (NULL == currData)
168 OIC_LOG(DEBUG, TAG, "There is no block data");
169 currData = CACreateNewBlockData(sendData);
170 if (NULL == currData)
172 OIC_LOG(ERROR, TAG, "failed to create block data");
173 return CA_MEMORY_ALLOC_FAILED;
178 // #3. check request/response block option type and payload length
179 res = CACheckBlockOptionType(currData);
180 if (CA_STATUS_OK == res)
182 // #4. send block message
183 OIC_LOG(DEBUG, TAG, "send first block msg");
184 CALogBlockInfo(&currData->block);
186 res = CAAddSendThreadQueue(currData->sentData,
187 (const unsigned char*) currData->token);
188 if (CA_STATUS_OK != res)
190 OIC_LOG(ERROR, TAG, "add has failed");
198 CAResult_t CAAddSendThreadQueue(const CAData_t *sendData, const unsigned char* token)
200 VERIFY_NON_NULL(sendData, TAG, "sendData");
201 VERIFY_NON_NULL(token, TAG, "token");
203 CAData_t *cloneData = CACloneCAData(sendData);
204 if (NULL == cloneData)
206 OIC_LOG(ERROR, TAG, "clone has failed");
207 CARemoveBlockDataFromList(token);
208 return CA_STATUS_FAILED;
211 if (g_context.sendThreadFunc)
213 ca_mutex_lock(g_context.blockDataSenderMutex);
214 g_context.sendThreadFunc(cloneData);
215 ca_mutex_unlock(g_context.blockDataSenderMutex);
220 CAResult_t CACheckBlockOptionType(CABlockData_t *currData)
222 VERIFY_NON_NULL(currData, TAG, "currData");
223 VERIFY_NON_NULL(currData->sentData, TAG, "currData->sentData");
225 size_t payloadLen = 0;
226 CAGetPayloadInfo(currData->sentData, &payloadLen);
228 // check if message has to be transfered to a block
229 size_t maxBlockSize = BLOCK_SIZE(CA_DEFAULT_BLOCK_SIZE);
230 if (payloadLen <= maxBlockSize)
232 OIC_LOG_V(DEBUG, TAG, "payloadLen=%d, maxBlockSize=%d", payloadLen, maxBlockSize);
233 return CA_NOT_SUPPORTED;
236 // check if next block are required to transfer
237 CAGetMoreBitFromBlock(payloadLen, &currData->block);
239 // set block option (COAP_OPTION_BLOCK2 or COAP_OPTION_BLOCK1)
240 if (NULL != currData->sentData->requestInfo) // request message
242 if (currData->block.m)
244 OIC_LOG(DEBUG, TAG, "no ACK, option1");
245 currData->type = COAP_OPTION_BLOCK1;
249 OIC_LOG(DEBUG, TAG, "no ACK, normal req");
252 else // response message
254 if (currData->block.m)
256 OIC_LOG(DEBUG, TAG, "ACK, option2");
257 currData->type = COAP_OPTION_BLOCK2;
261 OIC_LOG(DEBUG, TAG, "ACK, normal res");
268 CAResult_t CAReceiveBlockWiseData(const coap_pdu_t *pdu, const CAEndpoint_t *endpoint,
269 const CAData_t *receivedData, size_t dataLen)
271 OIC_LOG(DEBUG, TAG, "CAReceiveBlockWiseData");
272 VERIFY_NON_NULL(pdu, TAG, "pdu");
273 VERIFY_NON_NULL(pdu->hdr, TAG, "pdu->hdr");
274 VERIFY_NON_NULL(endpoint, TAG, "endpoint");
275 VERIFY_NON_NULL(receivedData, TAG, "receivedData");
277 // check if received message type is CA_MSG_RESET
278 if (CA_EMPTY == pdu->hdr->code)
280 OIC_LOG(DEBUG, TAG, "code is CA_EMPTY..");
282 // get token from block-wise transfer list when CA_EMPTY(RST/ACK) is received
283 CAResult_t res = CAGetTokenFromBlockDataList(pdu, endpoint, receivedData->responseInfo);
284 if (CA_STATUS_OK != res)
286 OIC_LOG(ERROR, TAG, "fail to get token");
290 CARemoveBlockDataFromList((const unsigned char*) receivedData->responseInfo->info.token);
291 return CA_NOT_SUPPORTED;
294 // check if block option is set and get block data
295 coap_block_t block = {0};
296 if (coap_get_block(pdu, COAP_OPTION_BLOCK2, &block))
298 CAResult_t res = CASetNextBlockOption2(pdu, endpoint, receivedData, block, dataLen);
299 if (CA_STATUS_OK != res)
301 OIC_LOG(ERROR, TAG, "setting has failed");
305 else if (coap_get_block(pdu, COAP_OPTION_BLOCK1, &block)) // block1 option
307 CAResult_t res = CASetNextBlockOption1(pdu, endpoint, receivedData, block, dataLen);
308 if (CA_STATUS_OK != res)
310 OIC_LOG(ERROR, TAG, "setting has failed");
316 uint32_t code = CA_RESPONSE_CODE(pdu->hdr->code);
317 if (CA_REQUEST_ENTITY_INCOMPLETE == code)
319 CABlockData_t *data = CAGetBlockDataFromBlockDataList(pdu->hdr->token);
322 OIC_LOG(ERROR, TAG, "getting has failed");
323 return CA_STATUS_FAILED;
326 coap_block_t *block = CAGetBlockOption(pdu->hdr->token);
329 OIC_LOG(ERROR, TAG, "block is null");
330 return CA_STATUS_FAILED;
333 if (COAP_OPTION_BLOCK2 == data->type)
335 CAResult_t res = CASetNextBlockOption2(pdu, endpoint, receivedData, *block,
337 if (CA_STATUS_OK != res)
339 OIC_LOG(ERROR, TAG, "setting has failed");
343 else if (COAP_OPTION_BLOCK1 == data->type)
345 CAResult_t res = CASetNextBlockOption1(pdu, endpoint, receivedData, *block,
347 if (CA_STATUS_OK != res)
349 OIC_LOG(ERROR, TAG, "setting has failed");
357 OIC_LOG(DEBUG, TAG, "it's normal pdu");
358 return CA_NOT_SUPPORTED;
365 CAResult_t CAProcessNextStep(const coap_pdu_t *pdu, const CAData_t *receivedData,
366 uint8_t blockWiseStatus)
368 VERIFY_NON_NULL(pdu, TAG, "pdu");
369 VERIFY_NON_NULL(pdu->hdr, TAG, "pdu->hdr");
371 CAResult_t res = CA_STATUS_OK;
372 CAData_t *data = NULL;
374 // process blockWiseStatus
375 switch (blockWiseStatus)
377 case CA_OPTION2_FIRST_BLOCK:
378 res = CAAddSendThreadQueue(receivedData, pdu->hdr->token);
379 if (CA_STATUS_OK != res)
381 OIC_LOG(ERROR, TAG, "add has failed");
387 // add data to send thread
388 data = CAGetDataSetFromBlockDataList(pdu->hdr->token);
391 OIC_LOG(ERROR, TAG, "it's unavailable");
392 return CA_STATUS_FAILED;
395 if (data->requestInfo)
397 data->requestInfo->info.messageId = pdu->hdr->id;
400 if (data->responseInfo)
402 data->responseInfo->info.messageId = pdu->hdr->id;
405 res = CAAddSendThreadQueue(data, pdu->hdr->token);
406 if (CA_STATUS_OK != res)
408 OIC_LOG(ERROR, TAG, "add has failed");
416 case CA_SENT_PREVIOUS_NON_MSG:
417 res = CASendBlockMessage(pdu, CA_MSG_CONFIRM, blockWiseStatus);
418 if (CA_STATUS_OK != res)
420 OIC_LOG(ERROR, TAG, "send has failed");
425 case CA_OPTION2_LAST_BLOCK:
426 // process last block and send upper layer
427 res = CAReceiveLastBlock(pdu, receivedData);
428 if (CA_STATUS_OK != res)
430 OIC_LOG(ERROR, TAG, "receive has failed");
434 // remove data from list
435 res = CARemoveBlockDataFromList(pdu->hdr->token);
436 if (CA_STATUS_OK != res)
438 OIC_LOG(ERROR, TAG, "remove has failed");
443 case CA_OPTION1_NO_ACK_LAST_BLOCK:
444 // process last block and send upper layer
445 res = CAReceiveLastBlock(pdu, receivedData);
446 if (CA_STATUS_OK != res)
448 OIC_LOG(ERROR, TAG, "receive has failed");
452 if (CA_MSG_CONFIRM == pdu->hdr->type)
454 // send ack message to remote device
455 res = CASendBlockMessage(pdu, CA_MSG_ACKNOWLEDGE, blockWiseStatus);
456 if (CA_STATUS_OK != res)
458 OIC_LOG(ERROR, TAG, "send has failed");
464 case CA_OPTION1_NO_ACK_BLOCK:
465 if (CA_MSG_CONFIRM == pdu->hdr->type)
467 // add data to send thread
468 res = CASendBlockMessage(pdu, CA_MSG_ACKNOWLEDGE, blockWiseStatus);
469 if (CA_STATUS_OK != res)
471 OIC_LOG(ERROR, TAG, "send has failed");
477 case CA_BLOCK_INCOMPLETE:
478 if (CA_MSG_CONFIRM == pdu->hdr->type || CA_MSG_ACKNOWLEDGE == pdu->hdr->type)
480 // add data to send thread
481 res = CASendErrorMessage(pdu, blockWiseStatus, CA_REQUEST_ENTITY_INCOMPLETE);
482 if (CA_STATUS_OK != res)
484 OIC_LOG(ERROR, TAG, "send has failed");
490 case CA_BLOCK_TOO_LARGE:
491 if (CA_MSG_ACKNOWLEDGE == pdu->hdr->type)
493 res = CASendBlockMessage(pdu, CA_MSG_CONFIRM, blockWiseStatus);
494 if (CA_STATUS_OK != res)
496 OIC_LOG(ERROR, TAG, "send has failed");
500 else if (CA_MSG_CONFIRM == pdu->hdr->type)
502 res = CASendErrorMessage(pdu, blockWiseStatus, CA_REQUEST_ENTITY_TOO_LARGE);
503 if (CA_STATUS_OK != res)
505 OIC_LOG(ERROR, TAG, "send has failed");
511 OIC_LOG_V(ERROR, TAG, "no logic [%d]", blockWiseStatus);
516 CAResult_t CASendBlockMessage(const coap_pdu_t *pdu, CAMessageType_t msgType, uint8_t status)
518 VERIFY_NON_NULL(pdu, TAG, "pdu");
519 VERIFY_NON_NULL(pdu->hdr, TAG, "pdu->hdr");
521 CAData_t *data = CAGetDataSetFromBlockDataList(pdu->hdr->token);
524 OIC_LOG(ERROR, TAG, "CAData is unavailable");
525 return CA_STATUS_FAILED;
528 if (CA_MSG_CONFIRM == msgType)
530 OIC_LOG(DEBUG, TAG, "need new msgID");
531 if (data->requestInfo)
533 data->requestInfo->info.messageId = 0;
536 if (data->responseInfo)
538 data->responseInfo->info.messageId = 0;
541 else if (CA_MSG_ACKNOWLEDGE == msgType)
543 if (data->responseInfo)
545 OIC_LOG(DEBUG, TAG, "set ACK message");
546 data->responseInfo->info.messageId = pdu->hdr->id;
547 data->responseInfo->info.type = CA_MSG_ACKNOWLEDGE;
548 if (CA_OPTION1_NO_ACK_LAST_BLOCK == status)
550 data->responseInfo->result = CA_CHANGED;
552 else if (CA_OPTION1_NO_ACK_BLOCK == status)
554 data->responseInfo->result = CA_CONTINUE;
559 // add data to send thread
560 CAResult_t res = CAAddSendThreadQueue(data, pdu->hdr->token);
561 if (CA_STATUS_OK != res)
563 OIC_LOG(ERROR, TAG, "add has failed");
569 CAResult_t CASendErrorMessage(const coap_pdu_t *pdu, uint8_t status,
570 CAResponseResult_t responseResult)
572 VERIFY_NON_NULL(pdu, TAG, "pdu");
573 VERIFY_NON_NULL(pdu->hdr, TAG, "pdu->hdr");
575 // create error responseInfo
576 CABlockData_t *data = CAGetBlockDataFromBlockDataList(pdu->hdr->token);
579 OIC_LOG(ERROR, TAG, "data is unavailable");
580 return CA_STATUS_FAILED;
583 CAData_t *cloneData = NULL;
584 if (data->sentData && data->sentData->responseInfo)
586 data->sentData->responseInfo->info.messageId = pdu->hdr->id;
587 data->sentData->responseInfo->info.type = CA_MSG_ACKNOWLEDGE;
588 data->sentData->responseInfo->result = responseResult;
589 cloneData = CACloneCAData(data->sentData);
590 if (NULL == cloneData)
592 OIC_LOG(ERROR, TAG, "clone has failed");
593 return CA_MEMORY_ALLOC_FAILED;
595 OIC_LOG(DEBUG, TAG, "set ACK message");
599 cloneData = CACreateNewDataSet(pdu, CACloneEndpoint(data->sentData->remoteEndpoint));
600 cloneData->responseInfo->info.type = CA_MSG_CONFIRM;
601 cloneData->responseInfo->result = responseResult;
602 OIC_LOG(DEBUG, TAG, "set CON message");
605 // add data to send thread
606 if (g_context.sendThreadFunc)
608 ca_mutex_lock(g_context.blockDataSenderMutex);
609 g_context.sendThreadFunc(cloneData);
610 ca_mutex_unlock(g_context.blockDataSenderMutex);
613 // if error code is 4.08, remove the stored payload and initialize block number
614 if (CA_BLOCK_INCOMPLETE == status)
616 OICFree(data->payload);
617 data->payload = NULL;
618 data->payloadLength = 0;
625 CAResult_t CAReceiveLastBlock(const coap_pdu_t *pdu, const CAData_t *receivedData)
627 VERIFY_NON_NULL(pdu, TAG, "pdu");
628 VERIFY_NON_NULL(pdu->hdr, TAG, "pdu->hdr");
629 VERIFY_NON_NULL(receivedData, TAG, "receivedData");
631 // total block data have to notify to Application
632 CAData_t *cloneData = CACloneCAData(receivedData);
633 if (NULL == cloneData)
635 OIC_LOG(ERROR, TAG, "clone has failed");
636 return CA_MEMORY_ALLOC_FAILED;
640 size_t fullPayloadLen = 0;
641 CAPayload_t fullPayload = CAGetPayloadFromBlockDataList(pdu->hdr->token, &fullPayloadLen);
642 if (NULL != fullPayload)
644 CAResult_t res = CAUpdatePayloadToCAData(cloneData, fullPayload, fullPayloadLen);
645 if (CA_STATUS_OK != res)
647 OIC_LOG(ERROR, TAG, "update has failed");
648 return CA_STATUS_FAILED;
652 if (g_context.receivedThreadFunc)
654 g_context.receivedThreadFunc(cloneData);
660 CAResult_t CASetNextBlockOption1(const coap_pdu_t *pdu, const CAEndpoint_t *endpoint,
661 const CAData_t *receivedData, coap_block_t block,
664 OIC_LOG(INFO, TAG, "CASetNextBlockOption1");
665 VERIFY_NON_NULL(pdu, TAG, "pdu");
666 VERIFY_NON_NULL(pdu->hdr, TAG, "pdu->hdr");
667 VERIFY_NON_NULL(endpoint, TAG, "endpoint");
668 VERIFY_NON_NULL(receivedData, TAG, "receivedData");
670 OIC_LOG_V(INFO, TAG, "num:%d, M:%d, sze:%d", block.num, block.m, block.szx);
672 // BlockData data is created if it not existed
673 if (!CAIsBlockDataInList(pdu))
675 OIC_LOG(DEBUG, TAG, "no message in list");
677 CAData_t *data = CACreateNewDataSet(pdu, endpoint);
680 OIC_LOG(ERROR, TAG, "data is null");
681 return CA_STATUS_FAILED;
684 CABlockData_t *currData = CACreateNewBlockData(data);
685 if (NULL == currData)
687 OIC_LOG(ERROR, TAG, "currData is null");
688 CADestroyDataSet(data);
689 return CA_STATUS_FAILED;
693 // update BLOCK OPTION1 type
694 CAResult_t res = CAUpdateBlockOptionType(pdu->hdr->token, COAP_OPTION_BLOCK1);
695 if (CA_STATUS_OK != res)
697 OIC_LOG(ERROR, TAG, "update has failed");
698 CARemoveBlockDataFromList(pdu->hdr->token);
702 CABlockData_t *data = CAGetBlockDataFromBlockDataList(pdu->hdr->token);
705 OIC_LOG(ERROR, TAG, "getting has failed");
706 return CA_STATUS_FAILED;
709 uint8_t blockWiseStatus = CA_BLOCK_UNKNOWN;
710 // received type from remote device
711 if (CA_MSG_ACKNOWLEDGE == pdu->hdr->type)
713 uint32_t code = CA_RESPONSE_CODE(pdu->hdr->code);
715 (CA_REQUEST_ENTITY_INCOMPLETE != code && CA_REQUEST_ENTITY_TOO_LARGE != code))
717 OIC_LOG(INFO, TAG, "Data has sent");
718 // initialize block number for response message
723 blockWiseStatus = CA_OPTION1_ACK;
724 res = CAUpdateBlockOptionItems(data, pdu, &block, COAP_OPTION_BLOCK1, blockWiseStatus);
725 if (CA_STATUS_OK != res)
727 OIC_LOG(ERROR, TAG, "update has failed");
731 res = CAUpdateBlockData(data, block);
732 if (CA_STATUS_OK != res)
734 OIC_LOG(ERROR, TAG, "update has failed");
735 CARemoveBlockDataFromList(pdu->hdr->token);
739 else // CON or NON message
741 OIC_LOG_V(INFO, TAG, "num:%d, M:%d", block.num, block.m);
743 // check the size option
744 bool isSizeOption = CAIsPayloadLengthInPduWithBlockSizeOption(pdu,
746 &(data->payloadLength));
748 // check if received payload is exact
749 if (CA_MSG_CONFIRM == pdu->hdr->type)
751 blockWiseStatus = CACheckBlockErrorType(data, &block, receivedData,
752 COAP_OPTION_BLOCK1, dataLen);
755 if (CA_BLOCK_RECEIVED_ALREADY != blockWiseStatus)
757 // store the received payload and merge
758 res = CAUpdatePayloadData(data, receivedData, blockWiseStatus, isSizeOption);
759 if (CA_STATUS_OK != res)
761 OIC_LOG(ERROR, TAG, "update has failed");
762 CARemoveBlockDataFromList(pdu->hdr->token);
766 res = CAUpdateBlockOptionItems(data, pdu, &block, COAP_OPTION_BLOCK1, blockWiseStatus);
767 if (CA_STATUS_OK != res)
769 OIC_LOG(ERROR, TAG, "update has failed");
770 CARemoveBlockDataFromList(pdu->hdr->token);
775 res = CAUpdateBlockData(data, block);
776 if (CA_STATUS_OK != res)
778 OIC_LOG(ERROR, TAG, "update has failed");
779 CARemoveBlockDataFromList(pdu->hdr->token);
784 // check the blcok-wise transfer status for next step
785 if (CA_BLOCK_UNKNOWN == blockWiseStatus || CA_BLOCK_RECEIVED_ALREADY == blockWiseStatus)
787 if (0 == block.m) // Last block is received
789 OIC_LOG(DEBUG, TAG, "M bit is 0");
790 blockWiseStatus = CA_OPTION1_NO_ACK_LAST_BLOCK;
794 OIC_LOG(DEBUG, TAG, "M bit is 1");
795 blockWiseStatus = CA_OPTION1_NO_ACK_BLOCK;
800 res = CAProcessNextStep(pdu, receivedData, blockWiseStatus);
801 if (CA_STATUS_OK != res)
803 OIC_LOG(ERROR, TAG, "setting has failed");
804 CARemoveBlockDataFromList(pdu->hdr->token);
810 CAResult_t CASetNextBlockOption2(const coap_pdu_t *pdu, const CAEndpoint_t *endpoint,
811 const CAData_t *receivedData, coap_block_t block,
814 OIC_LOG(DEBUG, TAG, "CASetNextBlockOption2");
815 OIC_LOG_V(INFO, TAG, "num:%d, M:%d, sze:%d", block.num, block.m, block.szx);
817 VERIFY_NON_NULL(pdu, TAG, "pdu");
818 VERIFY_NON_NULL(pdu->hdr, TAG, "pdu->hdr");
819 VERIFY_NON_NULL(endpoint, TAG, "endpoint");
820 VERIFY_NON_NULL(receivedData, TAG, "receivedData");
822 // BlockData data is created if it not existed
823 if (!CAIsBlockDataInList(pdu))
825 OIC_LOG(DEBUG, TAG, "no msg in list.");
827 CAData_t *data = CACreateNewDataSet(pdu, endpoint);
830 OIC_LOG(ERROR, TAG, "data is null");
831 return CA_STATUS_FAILED;
834 CABlockData_t *currData = CACreateNewBlockData(data);
835 if (NULL == currData)
837 OIC_LOG(ERROR, TAG, "data is null");
838 CADestroyDataSet(data);
839 return CA_STATUS_FAILED;
843 // set Block Option Type
844 CAResult_t res = CAUpdateBlockOptionType(pdu->hdr->token, COAP_OPTION_BLOCK2);
845 if (CA_STATUS_OK != res)
847 OIC_LOG(ERROR, TAG, "update has failed");
848 CARemoveBlockDataFromList(pdu->hdr->token);
852 CABlockData_t *data = CAGetBlockDataFromBlockDataList(pdu->hdr->token);
855 OIC_LOG(ERROR, TAG, "getting has failed");
856 return CA_STATUS_FAILED;
859 uint8_t blockWiseStatus = CA_BLOCK_UNKNOWN;
860 if (0 == block.num && CA_GET == pdu->hdr->code && 0 == block.m)
862 OIC_LOG(INFO, TAG, "first block number");
864 res = CAUpdateBlockOptionItems(data, pdu, &block, COAP_OPTION_BLOCK2, blockWiseStatus);
865 if (CA_STATUS_OK != res)
867 OIC_LOG(ERROR, TAG, "update has failed");
871 // first block data have to notify to Application
872 res = CAUpdateBlockData(data, block);
873 if (CA_STATUS_OK != res)
875 OIC_LOG(ERROR, TAG, "update has failed");
876 CARemoveBlockDataFromList(pdu->hdr->token);
879 blockWiseStatus = CA_OPTION2_FIRST_BLOCK;
883 // received type from remote device
884 if (CA_MSG_ACKNOWLEDGE == pdu->hdr->type ||
885 (CA_MSG_NONCONFIRM == pdu->hdr->type && NULL != receivedData->responseInfo))
887 OIC_LOG(DEBUG, TAG, "received ACK or NON");
889 // check the size option
890 bool isSizeOption = CAIsPayloadLengthInPduWithBlockSizeOption(pdu,
892 &(data->payloadLength));
894 // check if received payload is exact
895 if (CA_MSG_ACKNOWLEDGE == pdu->hdr->type)
897 blockWiseStatus = CACheckBlockErrorType(data, &block, receivedData,
898 COAP_OPTION_BLOCK2, dataLen);
901 if (CA_BLOCK_RECEIVED_ALREADY != blockWiseStatus)
903 // store the received payload and merge
904 res = CAUpdatePayloadData(data, receivedData, blockWiseStatus, isSizeOption);
905 if (CA_STATUS_OK != res)
907 OIC_LOG(ERROR, TAG, "update has failed");
908 CARemoveBlockDataFromList(pdu->hdr->token);
913 if (0 == block.m && CA_BLOCK_UNKNOWN == blockWiseStatus) // Last block is received
915 OIC_LOG(DEBUG, TAG, "M bit is 0");
916 blockWiseStatus = CA_OPTION2_LAST_BLOCK;
920 if (CA_BLOCK_UNKNOWN == blockWiseStatus ||
921 CA_BLOCK_RECEIVED_ALREADY == blockWiseStatus)
923 OIC_LOG(DEBUG, TAG, "M bit is 1");
925 if (CA_MSG_ACKNOWLEDGE == pdu->hdr->type)
927 blockWiseStatus = CA_OPTION2_ACK;
931 blockWiseStatus = CA_OPTION2_NON;
935 res = CAUpdateBlockOptionItems(data, pdu, &block, COAP_OPTION_BLOCK2,
937 if (CA_STATUS_OK != res)
939 OIC_LOG(ERROR, TAG, "update has failed");
940 CARemoveBlockDataFromList(pdu->hdr->token);
944 res = CAUpdateBlockData(data, block);
945 if (CA_STATUS_OK != res)
947 OIC_LOG(ERROR, TAG, "update has failed");
948 CARemoveBlockDataFromList(pdu->hdr->token);
953 else // CON message and so on.
955 OIC_LOG_V(INFO, TAG, "num:%d, M:%d", block.num, block.m);
957 blockWiseStatus = CA_OPTION2_CON;
959 res = CAUpdateBlockOptionItems(data, pdu, &block, COAP_OPTION_BLOCK2, blockWiseStatus);
960 if (CA_STATUS_OK != res)
962 OIC_LOG(ERROR, TAG, "update has failed");
963 CARemoveBlockDataFromList(pdu->hdr->token);
967 res = CAUpdateBlockData(data, block);
968 if (CA_STATUS_OK != res)
970 OIC_LOG(ERROR, TAG, "update has failed");
971 CARemoveBlockDataFromList(pdu->hdr->token);
977 res = CAProcessNextStep(pdu, receivedData, blockWiseStatus);
978 if (CA_STATUS_OK != res)
980 OIC_LOG(ERROR, TAG, "setting has failed");
981 CARemoveBlockDataFromList(pdu->hdr->token);
988 CAResult_t CAUpdateBlockOptionItems(CABlockData_t *currData, const coap_pdu_t *pdu,
989 coap_block_t *block, uint16_t blockType,
992 VERIFY_NON_NULL(currData, TAG, "currData");
993 VERIFY_NON_NULL(pdu, TAG, "pdu");
994 VERIFY_NON_NULL(block, TAG, "block");
997 CAResult_t res = CA_STATUS_OK;
998 uint32_t code = CA_RESPONSE_CODE(pdu->hdr->code);
1000 if (CA_REQUEST_ENTITY_INCOMPLETE == code || CA_REQUEST_ENTITY_TOO_LARGE == code)
1002 // response error code of the received block message
1003 res = CAHandleBlockErrorResponse(block, blockType, code);
1004 if (CA_STATUS_OK != res)
1006 OIC_LOG(ERROR, TAG, "error handle has failed");
1012 // update block option items
1015 case CA_OPTION1_ACK:
1016 if (currData->block.num > block->num)
1018 OIC_LOG(ERROR, TAG, "received incorrect block num");
1019 return CA_STATUS_FAILED;
1023 case CA_OPTION2_NON:
1027 case CA_OPTION2_CON:
1030 case CA_OPTION2_ACK:
1031 if (currData->block.num > block->num)
1033 OIC_LOG(ERROR, TAG, "received incorrect block num");
1034 return CA_STATUS_FAILED;
1039 case CA_BLOCK_TOO_LARGE:
1040 // if state of received block message is CA_BLOCK_TOO_LARGE or CA_BLOCK_INCOMPLETE
1041 // we set the response error code appropriately and send
1042 if (COAP_OPTION_BLOCK2 == blockType)
1047 block->szx = currData->block.szx;
1050 OIC_LOG_V(ERROR, TAG, "no logic [%d]", status);
1053 if (CA_BLOCK_INCOMPLETE != status && CA_BLOCK_TOO_LARGE != status)
1055 // negotiate block size
1056 res = CANegotiateBlockSize(currData, block, pdu->hdr->type, blockType);
1057 if (CA_STATUS_OK != res)
1059 OIC_LOG(ERROR, TAG, "negotiation has failed");
1067 CAResult_t CAGetMoreBitFromBlock(size_t payloadLen, coap_block_t *block)
1069 VERIFY_NON_NULL(block, TAG, "block");
1071 if (((block->num + 1) << (block->szx + BLOCK_NUMBER_IDX)) < payloadLen)
1073 OIC_LOG(DEBUG, TAG, "Set the M-bit(1)");
1078 OIC_LOG(DEBUG, TAG, "Set the M-bit(0)");
1082 return CA_STATUS_OK;
1085 CAResult_t CANegotiateBlockSize(CABlockData_t *currData, coap_block_t *block,
1086 CAMessageType_t msgType, uint16_t blockType)
1088 OIC_LOG(DEBUG, TAG, "IN-NegotiateBlockSize");
1090 VERIFY_NON_NULL(currData, TAG, "currData");
1091 VERIFY_NON_NULL(block, TAG, "block");
1093 // #1. check the block option type
1094 if (COAP_OPTION_BLOCK2 == blockType)
1096 // #2. check the message type
1097 if (CA_MSG_ACKNOWLEDGE == msgType)
1099 if (block->szx > currData->block.szx)
1101 OIC_LOG(DEBUG, TAG, "sze is big");
1103 // #3. calculate new block number from block size
1104 unsigned int blockNum = BLOCK_SIZE(block->szx) /
1105 BLOCK_SIZE(currData->block.szx) - 1;
1106 OIC_LOG(DEBUG, TAG, "num is set as Negotiation");
1107 block->num += blockNum;
1108 block->szx = currData->block.szx;
1109 OIC_LOG_V(DEBUG, TAG, "updated block num: %d", block->num);
1114 if (block->szx > currData->block.szx)
1116 OIC_LOG(DEBUG, TAG, "sze is big");
1117 block->szx = currData->block.szx;
1121 else if (COAP_OPTION_BLOCK1 == blockType)
1123 if (CA_MSG_ACKNOWLEDGE == msgType)
1125 if (block->szx < currData->block.szx)
1127 OIC_LOG(DEBUG, TAG, "sze is small");
1129 unsigned int blockNum = BLOCK_SIZE(currData->block.szx) /
1130 BLOCK_SIZE(block->szx) - 1;
1131 block->num += blockNum;
1132 OIC_LOG_V(DEBUG, TAG, "updated block num: %d", block->num);
1137 if (block->szx > currData->block.szx)
1139 OIC_LOG(DEBUG, TAG, "sze is big");
1140 block->szx = currData->block.szx;
1146 OIC_LOG(DEBUG, TAG, "Invalid block option");
1147 return CA_STATUS_FAILED;
1150 OIC_LOG(DEBUG, TAG, "OUT-NegotiateBlockSize");
1152 return CA_STATUS_OK;
1155 CAResult_t CAUpdateBlockData(CABlockData_t *currData, coap_block_t block)
1157 VERIFY_NON_NULL(currData, TAG, "currData");
1159 // check if block size is bigger than CABlockSize_t
1160 if (block.szx > CA_BLOCK_SIZE_1024_BYTE)
1162 OIC_LOG(DEBUG, TAG, "invalid block szx");
1163 return CA_STATUS_FAILED;
1166 // update block option
1167 currData->block = block;
1169 OIC_LOG(DEBUG, TAG, "data has updated");
1170 return CA_STATUS_OK;
1173 CAResult_t CAUpdateMessageId(coap_pdu_t *pdu)
1175 VERIFY_NON_NULL(pdu, TAG, "pdu");
1177 // if CON message is sent, update messageId in block-wise transfer list
1178 if (CA_MSG_CONFIRM == pdu->hdr->type)
1180 CAData_t * cadata = CAGetDataSetFromBlockDataList(pdu->hdr->token);
1183 OIC_LOG(ERROR, TAG, "CAData is unavailable");
1184 return CA_STATUS_FAILED;
1187 if (NULL != cadata->requestInfo)
1189 cadata->requestInfo->info.messageId = pdu->hdr->id;
1193 return CA_STATUS_OK;
1196 CAResult_t CAAddBlockOption(coap_pdu_t **pdu, CAInfo_t info)
1198 OIC_LOG(DEBUG, TAG, "IN-AddBlockOption");
1199 VERIFY_NON_NULL(pdu, TAG, "pdu");
1200 VERIFY_NON_NULL((*pdu), TAG, "(*pdu)");
1201 VERIFY_NON_NULL((*pdu)->hdr, TAG, "(*pdu)->hdr");
1203 size_t dataLength = 0;
1206 dataLength = info.payloadSize;
1207 OIC_LOG_V(DEBUG, TAG, "dataLength - %d", dataLength);
1210 OIC_LOG_V(DEBUG, TAG, "previous payload - %s", (*pdu)->data);
1212 uint32_t code = CA_RESPONSE_CODE((*pdu)->hdr->code);
1213 if (CA_REQUEST_ENTITY_INCOMPLETE == code)
1215 OIC_LOG(INFO, TAG, "don't use option");
1216 return CA_STATUS_OK;
1219 uint8_t blockType = CAGetBlockOptionType((*pdu)->hdr->token);
1220 if (COAP_OPTION_BLOCK2 == blockType)
1222 CAResult_t res = CAAddBlockOption2(pdu, info, dataLength);
1223 if (CA_STATUS_OK != res)
1225 OIC_LOG(ERROR, TAG, "add has failed");
1229 else if (COAP_OPTION_BLOCK1 == blockType)
1231 CAResult_t res = CAAddBlockOption1(pdu, info, dataLength);
1232 if (CA_STATUS_OK != res)
1234 OIC_LOG(ERROR, TAG, "add has failed");
1240 OIC_LOG(DEBUG, TAG, "no BLOCK option");
1241 // if response data is so large. it have to send as block transfer
1242 if (!coap_add_data(*pdu, dataLength, (const unsigned char *) info.payload))
1244 OIC_LOG(INFO, TAG, "it have to use block");
1248 OIC_LOG(INFO, TAG, "not Blockwise Transfer");
1252 CAResult_t res = CAUpdateMessageId(*pdu);
1253 if (CA_STATUS_OK != res)
1255 OIC_LOG(ERROR, TAG, "fail to update CON message id ");
1259 OIC_LOG(DEBUG, TAG, "OUT-AddBlockOption");
1260 return CA_STATUS_OK;
1263 CAResult_t CAAddBlockOption2(coap_pdu_t **pdu, CAInfo_t info, size_t dataLength)
1265 OIC_LOG(DEBUG, TAG, "IN-AddBlockOption2");
1266 VERIFY_NON_NULL(pdu, TAG, "pdu");
1267 VERIFY_NON_NULL((*pdu), TAG, "(*pdu)");
1268 VERIFY_NON_NULL((*pdu)->hdr, TAG, "(*pdu)->hdr");
1270 // get set block data from CABlock list-set.
1271 coap_block_t *block = CAGetBlockOption((*pdu)->hdr->token);
1274 OIC_LOG(ERROR, TAG, "getting has failed");
1275 return CA_STATUS_FAILED;
1278 CALogBlockInfo(block);
1281 if (CA_MSG_ACKNOWLEDGE == (*pdu)->hdr->type ||
1282 (CA_MSG_NONCONFIRM == (*pdu)->hdr->type && CA_GET != (*pdu)->hdr->code))
1284 int32_t res = coap_write_block_opt(block, COAP_OPTION_BLOCK2, *pdu, dataLength);
1287 case -2: /* illegal block */
1288 code = COAP_RESPONSE_CODE(CA_BAD_REQ);
1289 OIC_LOG(ERROR, TAG, "write block option : -2");
1291 case -1: /* should really not happen */
1292 OIC_LOG(ERROR, TAG, "write block option : -1");
1294 case -3: /* cannot handle request */
1295 code = COAP_RESPONSE_CODE(CA_INTERNAL_SERVER_ERROR);
1296 OIC_LOG(ERROR, TAG, "write block option : -3");
1299 OIC_LOG(INFO, TAG, "success write block option");
1301 CALogBlockInfo(block);
1303 // if block number is 0, add size2 option
1304 if (0 == block->num)
1306 res = CAAddBlockSizeOption(*pdu, COAP_OPTION_SIZE2, dataLength);
1307 if (CA_STATUS_OK != res)
1309 OIC_LOG(ERROR, TAG, "add has failed");
1310 CARemoveBlockDataFromList((*pdu)->hdr->token);
1315 if (!coap_add_block(*pdu, dataLength, (const unsigned char *) info.payload,
1316 block->num, block->szx))
1318 OIC_LOG(ERROR, TAG, "Data length is smaller than the start index");
1319 return CA_STATUS_FAILED;
1322 if (CA_MSG_NONCONFIRM == (*pdu)->hdr->type)
1326 OIC_LOG(DEBUG, TAG, "NON, send next block..");
1327 // update block data
1329 CAResult_t res = CAProcessNextStep(*pdu, NULL, CA_SENT_PREVIOUS_NON_MSG);
1330 if (CA_STATUS_OK != res)
1332 OIC_LOG(ERROR, TAG, "failed to process next step");
1333 CARemoveBlockDataFromList((*pdu)->hdr->token);
1339 CARemoveBlockDataFromList((*pdu)->hdr->token);
1345 OIC_LOG(DEBUG, TAG, "option2, not ACK msg");
1346 CAResult_t res = CAAddBlockOptionImpl(*pdu, block, COAP_OPTION_BLOCK2);
1347 if (CA_STATUS_OK != res)
1349 OIC_LOG(ERROR, TAG, "add has failed");
1350 CARemoveBlockDataFromList((*pdu)->hdr->token);
1355 return CA_STATUS_OK;
1358 OIC_LOG_V(ERROR, TAG, "error : %d", code);
1359 coap_add_data(*pdu, strlen(coap_response_phrase(code)),
1360 (unsigned char *) coap_response_phrase(code));
1361 return CA_STATUS_FAILED;
1364 CAResult_t CAAddBlockOption1(coap_pdu_t **pdu, CAInfo_t info, size_t dataLength)
1366 OIC_LOG(DEBUG, TAG, "IN-AddBlockOption1");
1367 VERIFY_NON_NULL(pdu, TAG, "pdu");
1368 VERIFY_NON_NULL((*pdu), TAG, "(*pdu)");
1369 VERIFY_NON_NULL((*pdu)->hdr, TAG, "(*pdu)->hdr");
1371 // get set block data from CABlock list-set.
1372 coap_block_t *block = CAGetBlockOption((*pdu)->hdr->token);
1375 OIC_LOG(ERROR, TAG, "getting has failed");
1376 return CA_STATUS_FAILED;
1379 CALogBlockInfo(block);
1381 if (CA_MSG_ACKNOWLEDGE == (*pdu)->hdr->type)
1383 OIC_LOG(DEBUG, TAG, "option1 and ACK msg..");
1384 CAResult_t res = CAAddBlockOptionImpl(*pdu, block, COAP_OPTION_BLOCK1);
1385 if (CA_STATUS_OK != res)
1387 OIC_LOG(ERROR, TAG, "add has failed");
1388 CARemoveBlockDataFromList((*pdu)->hdr->token);
1392 // reset block-list after write block
1395 // remove data from list
1396 CAResult_t res = CARemoveBlockDataFromList((*pdu)->hdr->token);
1397 if (CA_STATUS_OK != res)
1399 OIC_LOG(ERROR, TAG, "remove has failed");
1406 CAGetMoreBitFromBlock(dataLength, block);
1407 CAResult_t res = CAAddBlockOptionImpl(*pdu, block, COAP_OPTION_BLOCK1);
1408 if (CA_STATUS_OK != res)
1410 OIC_LOG(ERROR, TAG, "add has failed");
1411 CARemoveBlockDataFromList((*pdu)->hdr->token);
1414 CALogBlockInfo(block);
1416 // if block number is 0, add size1 option
1417 if (0 == block->num)
1419 res = CAAddBlockSizeOption(*pdu, COAP_OPTION_SIZE1, dataLength);
1420 if (CA_STATUS_OK != res)
1422 OIC_LOG(ERROR, TAG, "add has failed");
1423 CARemoveBlockDataFromList((*pdu)->hdr->token);
1428 if (!coap_add_block(*pdu, dataLength, (const unsigned char *) info.payload,
1429 block->num, block->szx))
1431 OIC_LOG(ERROR, TAG, "Data length is smaller than the start index");
1432 return CA_STATUS_FAILED;
1435 // check the message type and if message type is NON, next block message will be sent
1436 if (CA_MSG_NONCONFIRM == (*pdu)->hdr->type)
1440 OIC_LOG(DEBUG, TAG, "NON, send next block..");
1441 // update block data
1443 CAResult_t res = CAProcessNextStep(*pdu, NULL, CA_SENT_PREVIOUS_NON_MSG);
1444 if (CA_STATUS_OK != res)
1446 OIC_LOG(ERROR, TAG, "failed to process next step");
1447 CARemoveBlockDataFromList((*pdu)->hdr->token);
1453 CARemoveBlockDataFromList((*pdu)->hdr->token);
1458 OIC_LOG(DEBUG, TAG, "OUT-AddBlockOption1");
1460 return CA_STATUS_OK;
1463 CAResult_t CAAddBlockOptionImpl(coap_pdu_t *pdu, coap_block_t *block, uint8_t blockType)
1465 OIC_LOG(DEBUG, TAG, "IN-AddBlockOptionImpl");
1466 VERIFY_NON_NULL(pdu, TAG, "pdu");
1467 VERIFY_NON_NULL(block, TAG, "block");
1469 coap_option *option = (coap_option *) OICMalloc(sizeof(coap_option));
1472 OIC_LOG(ERROR, TAG, "out of memory");
1473 return CA_MEMORY_ALLOC_FAILED;
1476 unsigned char buf[BLOCKWISE_OPTION_BUFFER] = { 0 };
1477 option->key = blockType;
1478 option->length = coap_encode_var_bytes(buf,
1479 ((block->num << BLOCK_NUMBER_IDX)
1480 | (block->m << BLOCK_M_BIT_IDX) | block->szx));
1481 if (!coap_add_option(pdu, option->key, option->length, buf))
1483 OIC_LOG(ERROR, TAG, "coap_add_option has failed");
1485 return CA_STATUS_FAILED;
1490 OIC_LOG(DEBUG, TAG, "OUT-AddBlockOptionImpl");
1491 return CA_STATUS_OK;
1494 CAResult_t CAAddBlockSizeOption(coap_pdu_t *pdu, uint16_t sizeType, size_t dataLength)
1496 OIC_LOG(DEBUG, TAG, "IN-CAAddBlockSizeOption");
1497 VERIFY_NON_NULL(pdu, TAG, "pdu");
1499 if (sizeType != COAP_OPTION_SIZE1 && sizeType != COAP_OPTION_SIZE2)
1501 OIC_LOG(ERROR, TAG, "unknown option type");
1502 return CA_STATUS_FAILED;
1505 unsigned char value[BLOCKWISE_OPTION_BUFFER] = { 0 };
1506 coap_option *option = (coap_option *) OICMalloc(sizeof(coap_option));
1509 OIC_LOG(ERROR, TAG, "out of memory");
1510 return CA_MEMORY_ALLOC_FAILED;
1513 option->key = sizeType;
1514 option->length = coap_encode_var_bytes(value, dataLength);
1516 if (!coap_add_option(pdu, option->key, option->length, value))
1518 OIC_LOG(ERROR, TAG, "failed to add size option");
1520 return CA_STATUS_FAILED;
1523 OIC_LOG(DEBUG, TAG, "OUT-CAAddBlockSizeOption");
1525 return CA_STATUS_OK;
1528 bool CAIsPayloadLengthInPduWithBlockSizeOption(const coap_pdu_t *pdu,
1530 size_t *totalPayloadLen)
1532 OIC_LOG(DEBUG, TAG, "IN-CAIsPayloadLengthInPduWithBlockSizeOption");
1533 VERIFY_NON_NULL(pdu, TAG, "pdu");
1534 VERIFY_NON_NULL(totalPayloadLen, TAG, "totalPayloadLen");
1536 if (sizeType != COAP_OPTION_SIZE1 && sizeType != COAP_OPTION_SIZE2)
1538 OIC_LOG(ERROR, TAG, "unknown option type");
1539 return CA_STATUS_FAILED;
1542 coap_opt_iterator_t opt_iter;
1543 coap_opt_t *option = coap_check_option(pdu, sizeType, &opt_iter);
1546 OIC_LOG(DEBUG, TAG, "get size option from pdu");
1547 *totalPayloadLen = coap_decode_var_bytes(COAP_OPT_VALUE(option),
1548 COAP_OPT_LENGTH(option));
1550 OIC_LOG_V(DEBUG, TAG, "the total payload length to be received is [%d]bytes",
1556 OIC_LOG(DEBUG, TAG, "OUT-CAIsPayloadLengthInPduWithBlockSizeOption");
1561 uint8_t CACheckBlockErrorType(CABlockData_t *currData, coap_block_t *receivedBlock,
1562 const CAData_t *receivedData, uint16_t blockType,
1565 OIC_LOG(DEBUG, TAG, "IN-CheckBlockError");
1567 VERIFY_NON_NULL(currData, TAG, "currData is NULL");
1568 VERIFY_NON_NULL(receivedBlock, TAG, "receivedBlock is NULL");
1569 VERIFY_NON_NULL(receivedData, TAG, "receivedData is NULL");
1571 // #1. check the received payload length
1572 size_t blockPayloadLen = 0;
1573 CAGetPayloadInfo(receivedData, &blockPayloadLen);
1575 // #2. check if the block sequence is right
1576 if (COAP_OPTION_BLOCK1 == blockType)
1578 size_t prePayloadLen = currData->receivedPayloadLen;
1579 if (prePayloadLen != BLOCK_SIZE(receivedBlock->szx) * receivedBlock->num)
1581 if (receivedBlock->num > currData->block.num + 1)
1583 // 408 Error handling of block loss
1584 OIC_LOG(ERROR, TAG, "option1: error 4.08");
1585 OIC_LOG(ERROR, TAG, "it didn't order");
1586 return CA_BLOCK_INCOMPLETE;
1588 return CA_BLOCK_RECEIVED_ALREADY;
1591 else if (COAP_OPTION_BLOCK2 == blockType)
1593 if (receivedBlock->num != currData->block.num)
1595 if (receivedBlock->num > currData->block.num)
1597 // 408 Error handling of block loss
1598 OIC_LOG(ERROR, TAG, "option2: error 4.08");
1599 OIC_LOG(ERROR, TAG, "it didn't order");
1600 return CA_BLOCK_INCOMPLETE;
1602 return CA_BLOCK_RECEIVED_ALREADY;
1606 // #3. check if error check logic is required
1607 size_t optionLen = dataLen - blockPayloadLen;
1608 if (receivedBlock->m && blockPayloadLen != BLOCK_SIZE(receivedBlock->szx))
1610 // 413 Error handling of too large entity
1611 if (COAP_MAX_PDU_SIZE < BLOCK_SIZE(receivedBlock->szx) + optionLen)
1613 // buffer size is smaller than received block size
1614 OIC_LOG(ERROR, TAG, "error type 4.13");
1615 OIC_LOG(ERROR, TAG, "too large size");
1617 // set the block size to be smaller than COAP_MAX_PDU_SIZE
1618 for (int32_t size = CA_DEFAULT_BLOCK_SIZE; size >= 0; size--)
1620 if (COAP_MAX_PDU_SIZE >= BLOCK_SIZE(size) + optionLen)
1622 OIC_LOG_V(ERROR, TAG, "replace sze with %d", size);
1623 currData->block.szx = size;
1627 return CA_BLOCK_TOO_LARGE;
1631 // 408 Error handling of payload loss
1632 OIC_LOG(ERROR, TAG, "error type 4.08");
1633 OIC_LOG(ERROR, TAG, "payload len != block sze");
1634 return CA_BLOCK_INCOMPLETE;
1637 else if (0 == receivedBlock->m && 0 != currData->payloadLength)
1639 // if the received block is last block, check the total payload length
1640 size_t receivedPayloadLen = currData->receivedPayloadLen;
1641 receivedPayloadLen += blockPayloadLen;
1643 if (receivedPayloadLen != currData->payloadLength)
1645 OIC_LOG(ERROR, TAG, "error type 4.08");
1646 OIC_LOG(ERROR, TAG, "total payload length is wrong");
1647 return CA_BLOCK_INCOMPLETE;
1651 OIC_LOG(DEBUG, TAG, "received all data normally");
1653 OIC_LOG(DEBUG, TAG, "OUT-CheckBlockError");
1655 return CA_BLOCK_UNKNOWN;
1658 CAResult_t CAUpdatePayloadData(CABlockData_t *currData, const CAData_t *receivedData,
1659 uint8_t status, bool isSizeOption)
1661 OIC_LOG(DEBUG, TAG, "IN-UpdatePayloadData");
1663 VERIFY_NON_NULL(currData, TAG, "currData");
1664 VERIFY_NON_NULL(receivedData, TAG, "receivedData");
1666 // if error code is 4.08, do not update payload
1667 if (CA_BLOCK_INCOMPLETE == status)
1669 OIC_LOG(ERROR, TAG, "no require to update");
1670 return CA_STATUS_OK;
1673 size_t blockPayloadLen = 0;
1674 CAPayload_t blockPayload = CAGetPayloadInfo(receivedData, &blockPayloadLen);
1676 if (CA_BLOCK_TOO_LARGE == status)
1678 blockPayloadLen = BLOCK_SIZE(currData->block.szx);
1681 // memory allocation for the received block payload
1682 size_t prePayloadLen = currData->receivedPayloadLen;
1683 if (NULL != blockPayload)
1685 if (0 != currData->payloadLength)
1687 // in case the block message has the size option
1688 // allocate the memory for the total payload
1689 if (true == isSizeOption)
1691 CAPayload_t prePayload = currData->payload;
1693 OIC_LOG(DEBUG, TAG, "allocate memory for the total payload");
1694 currData->payload = (CAPayload_t) OICCalloc(currData->payloadLength + 1,
1696 if (NULL == currData->payload)
1698 OIC_LOG(ERROR, TAG, "out of memory");
1699 return CA_MEMORY_ALLOC_FAILED;
1701 memcpy(currData->payload, prePayload, prePayloadLen);
1702 OICFree(prePayload);
1705 // update the total payload
1706 memcpy(currData->payload + prePayloadLen, blockPayload, blockPayloadLen);
1710 OIC_LOG(DEBUG, TAG, "allocate memory for the received block payload");
1712 size_t totalPayloadLen = prePayloadLen + blockPayloadLen + 1;
1713 void *newPayload = realloc(currData->payload, totalPayloadLen);
1714 if (NULL == newPayload)
1716 OIC_LOG(ERROR, TAG, "out of memory");
1717 return CA_MEMORY_ALLOC_FAILED;
1720 // update the total payload
1721 memset(newPayload + prePayloadLen, 0, blockPayloadLen + 1);
1722 currData->payload = newPayload;
1723 memcpy(currData->payload + prePayloadLen, blockPayload, blockPayloadLen);
1726 // update received payload length
1727 currData->receivedPayloadLen += blockPayloadLen;
1729 OIC_LOG_V(DEBUG, TAG, "updated payload: %s, len: %d", currData->payload,
1730 currData->receivedPayloadLen);
1733 OIC_LOG(DEBUG, TAG, "OUT-UpdatePayloadData");
1734 return CA_STATUS_OK;
1737 CAData_t* CACreateNewDataSet(const coap_pdu_t *pdu, const CAEndpoint_t *endpoint)
1739 VERIFY_NON_NULL_RET(pdu, TAG, "pdu", NULL);
1740 VERIFY_NON_NULL_RET(pdu->hdr, TAG, "pdu->hdr", NULL);
1741 VERIFY_NON_NULL_RET(endpoint, TAG, "endpoint", NULL);
1743 CAInfo_t responseData = { 0 };
1744 responseData.token = (CAToken_t) OICMalloc(pdu->hdr->token_length);
1745 if (NULL == responseData.token)
1747 OIC_LOG(ERROR, TAG, "out of memory");
1750 memcpy(responseData.token, pdu->hdr->token, pdu->hdr->token_length);
1751 responseData.tokenLength = pdu->hdr->token_length;
1752 CAResponseInfo_t* responseInfo = (CAResponseInfo_t*) OICCalloc(1, sizeof(CAResponseInfo_t));
1753 if (NULL == responseInfo)
1755 OIC_LOG(ERROR, TAG, "out of memory");
1758 responseInfo->info = responseData;
1760 CAData_t *data = (CAData_t *) OICCalloc(1, sizeof(CAData_t));
1763 OIC_LOG(ERROR, TAG, "out of memory");
1764 OICFree(responseInfo);
1768 data->requestInfo = NULL;
1769 data->responseInfo = responseInfo;
1770 data->remoteEndpoint = CACloneEndpoint(endpoint);
1771 data->type = SEND_TYPE_UNICAST;
1776 CAData_t *CACloneCAData(const CAData_t *data)
1778 VERIFY_NON_NULL_RET(data, TAG, "data", NULL);
1780 CAData_t *clone = (CAData_t *) OICCalloc(1, sizeof(CAData_t));
1783 OIC_LOG(ERROR, TAG, "out of memory");
1786 memcpy(clone, data, sizeof(CAData_t));
1788 if (data->requestInfo)
1790 clone->requestInfo = CACloneRequestInfo(data->requestInfo);
1793 if (data->responseInfo)
1795 clone->responseInfo = CACloneResponseInfo(data->responseInfo);
1798 if (data->remoteEndpoint)
1800 clone->remoteEndpoint = CACloneEndpoint(data->remoteEndpoint);
1803 if (NULL != data->options && 0 < data->numOptions)
1806 CAHeaderOption_t *headerOption = (CAHeaderOption_t *) OICMalloc(sizeof(CAHeaderOption_t)
1807 * data->numOptions);
1808 if (NULL == headerOption)
1810 OIC_LOG(ERROR, TAG, "Out of memory");
1811 CADestroyDataSet(clone);
1814 memcpy(headerOption, data->options, sizeof(CAHeaderOption_t) * data->numOptions);
1816 clone->options = headerOption;
1822 CAResult_t CAUpdatePayloadToCAData(CAData_t *data, const CAPayload_t payload,
1825 OIC_LOG(DEBUG, TAG, "IN-UpdatePayload");
1827 VERIFY_NON_NULL(data, TAG, "data is NULL");
1828 VERIFY_NON_NULL(payload, TAG, "payload is NULL");
1830 if (NULL != data->requestInfo)
1832 // allocate payload field
1833 if (NULL != data->requestInfo->info.payload)
1835 char *temp = (char *) OICCalloc(payloadLen, sizeof(char));
1838 OIC_LOG(ERROR, TAG, "out of memory");
1839 return CA_STATUS_FAILED;
1841 memcpy(temp, payload, payloadLen);
1843 // save the full payload
1844 OICFree(data->requestInfo->info.payload);
1845 data->requestInfo->info.payload = (CAPayload_t) temp;
1847 data->requestInfo->info.payloadSize = payloadLen;
1850 if (NULL != data->responseInfo)
1852 // allocate payload field
1853 if (NULL != data->responseInfo->info.payload)
1855 char *temp = (char *) OICCalloc(payloadLen, sizeof(char));
1858 OIC_LOG(ERROR, TAG, "out of memory");
1859 return CA_STATUS_FAILED;
1861 memcpy(temp, payload, payloadLen);
1863 // save the full payload
1864 OICFree(data->responseInfo->info.payload);
1865 data->responseInfo->info.payload = (CAPayload_t) temp;
1867 data->responseInfo->info.payloadSize = payloadLen;
1870 OIC_LOG(DEBUG, TAG, "OUT-UpdatePayload");
1872 return CA_STATUS_OK;
1875 CAPayload_t CAGetPayloadInfo(const CAData_t *data, size_t *payloadLen)
1877 VERIFY_NON_NULL_RET(data, TAG, "data", NULL);
1878 VERIFY_NON_NULL_RET(payloadLen, TAG, "payloadLen", NULL);
1880 if (NULL != data->requestInfo)
1882 if (NULL != data->requestInfo->info.payload)
1884 *payloadLen = data->requestInfo->info.payloadSize;
1885 return data->requestInfo->info.payload;
1890 if (NULL != data->responseInfo->info.payload)
1892 *payloadLen = data->responseInfo->info.payloadSize;
1893 return data->responseInfo->info.payload;
1900 CAResult_t CAHandleBlockErrorResponse(coap_block_t *block, uint16_t blockType,
1901 uint32_t responseResult)
1903 OIC_LOG(DEBUG, TAG, "IN-HandleBlockErrorRes");
1904 VERIFY_NON_NULL(block, TAG, "block is NULL");
1906 // update block data
1907 switch (responseResult)
1909 case CA_REQUEST_ENTITY_INCOMPLETE:
1912 case CA_REQUEST_ENTITY_TOO_LARGE:
1913 if (COAP_OPTION_BLOCK1 == blockType)
1920 OIC_LOG_V(ERROR, TAG, "there is no Error Code of BWT[%d]", responseResult);
1923 OIC_LOG(DEBUG, TAG, "OUT-HandleBlockErrorRes");
1924 return CA_STATUS_OK;
1927 CAResult_t CAUpdateBlockOptionType(const unsigned char* token, uint8_t blockType)
1929 OIC_LOG(DEBUG, TAG, "IN-UpdateBlockOptionType");
1930 VERIFY_NON_NULL(token, TAG, "token");
1932 ca_mutex_lock(g_context.blockDataListMutex);
1934 size_t len = u_arraylist_length(g_context.dataList);
1935 for (size_t i = 0; i < len; i++)
1937 CABlockData_t *currData = (CABlockData_t *) u_arraylist_get(g_context.dataList, i);
1938 if (currData && currData->token)
1940 if (!strncmp(currData->token, (const char *) token, currData->tokenLength))
1942 currData->type = blockType;
1943 ca_mutex_unlock(g_context.blockDataListMutex);
1944 OIC_LOG(DEBUG, TAG, "OUT-UpdateBlockOptionType");
1945 return CA_STATUS_OK;
1949 ca_mutex_unlock(g_context.blockDataListMutex);
1951 OIC_LOG(DEBUG, TAG, "OUT-UpdateBlockOptionType");
1952 return CA_STATUS_FAILED;
1955 uint8_t CAGetBlockOptionType(const unsigned char* token)
1957 OIC_LOG(DEBUG, TAG, "IN-GetBlockOptionType");
1958 VERIFY_NON_NULL(token, TAG, "token");
1960 ca_mutex_lock(g_context.blockDataListMutex);
1962 size_t len = u_arraylist_length(g_context.dataList);
1963 for (size_t i = 0; i < len; i++)
1965 CABlockData_t *currData = (CABlockData_t *) u_arraylist_get(g_context.dataList, i);
1966 if (currData && currData->token)
1968 if (!strncmp(currData->token, (const char *) token, currData->tokenLength))
1970 ca_mutex_unlock(g_context.blockDataListMutex);
1971 OIC_LOG(DEBUG, TAG, "OUT-GetBlockOptionType");
1972 return currData->type;
1976 ca_mutex_unlock(g_context.blockDataListMutex);
1978 OIC_LOG(DEBUG, TAG, "OUT-GetBlockOptionType");
1982 CAData_t *CAGetDataSetFromBlockDataList(const unsigned char* token)
1984 VERIFY_NON_NULL_RET(token, TAG, "token", NULL);
1986 ca_mutex_lock(g_context.blockDataListMutex);
1988 size_t len = u_arraylist_length(g_context.dataList);
1989 for (size_t i = 0; i < len; i++)
1991 CABlockData_t *currData = (CABlockData_t *) u_arraylist_get(g_context.dataList, i);
1992 if (currData && currData->token)
1994 if (!strncmp(currData->token, (const char *) token, currData->tokenLength))
1996 ca_mutex_unlock(g_context.blockDataListMutex);
1997 return currData->sentData;
2001 ca_mutex_unlock(g_context.blockDataListMutex);
2006 CAResult_t CAGetTokenFromBlockDataList(const coap_pdu_t *pdu, const CAEndpoint_t *endpoint,
2007 CAResponseInfo_t *responseInfo)
2009 OIC_LOG(DEBUG, TAG, "IN-CAGetTokenFromBlockDataList");
2010 VERIFY_NON_NULL(pdu, TAG, "pdu");
2011 VERIFY_NON_NULL(endpoint, TAG, "endpoint");
2012 VERIFY_NON_NULL(responseInfo, TAG, "responseInfo");
2014 ca_mutex_lock(g_context.blockDataListMutex);
2016 size_t len = u_arraylist_length(g_context.dataList);
2017 for (size_t i = 0; i < len; i++)
2019 CABlockData_t *currData = (CABlockData_t *) u_arraylist_get(g_context.dataList, i);
2020 if (NULL == currData)
2025 if (NULL != currData->sentData && NULL != currData->sentData->requestInfo)
2027 if (pdu->hdr->id == currData->sentData->requestInfo->info.messageId &&
2028 endpoint->adapter == currData->sentData->remoteEndpoint->adapter)
2030 if (NULL != currData->token)
2032 responseInfo->info.tokenLength = currData->tokenLength;
2033 responseInfo->info.token = (char *) OICMalloc(currData->tokenLength);
2034 if (NULL == responseInfo->info.token)
2036 OIC_LOG(ERROR, TAG, "out of memory");
2037 ca_mutex_unlock(g_context.blockDataListMutex);
2038 return CA_MEMORY_ALLOC_FAILED;
2040 memcpy(responseInfo->info.token, currData->token,
2041 responseInfo->info.tokenLength);
2043 ca_mutex_unlock(g_context.blockDataListMutex);
2044 OIC_LOG(DEBUG, TAG, "OUT-CAGetTokenFromBlockDataList");
2045 return CA_STATUS_OK;
2051 ca_mutex_unlock(g_context.blockDataListMutex);
2053 OIC_LOG(DEBUG, TAG, "OUT-CAGetTokenFromBlockDataList");
2054 return CA_STATUS_FAILED;
2057 CAResult_t CACheckBlockDataValidation(const CAData_t *sendData, CABlockData_t **blockData)
2059 VERIFY_NON_NULL(sendData, TAG, "sendData");
2060 VERIFY_NON_NULL(blockData, TAG, "blockData");
2062 ca_mutex_lock(g_context.blockDataListMutex);
2064 size_t len = u_arraylist_length(g_context.dataList);
2065 for (size_t i = 0; i < len; i++)
2067 CABlockData_t *currData = (CABlockData_t *) u_arraylist_get(g_context.dataList, i);
2069 if ((NULL == currData) || (NULL == currData->token))
2074 if (NULL != sendData->requestInfo) // sendData is requestMessage
2076 OIC_LOG(DEBUG, TAG, "Send request");
2077 if (NULL != currData->token && NULL != sendData->requestInfo->info.token)
2079 if (!strncmp(currData->token, sendData->requestInfo->info.token,
2080 currData->tokenLength))
2082 OIC_LOG(ERROR, TAG, "already sent");
2087 else if (NULL != sendData->responseInfo) // sendData is responseMessage
2089 OIC_LOG(DEBUG, TAG, "Send response");
2090 if (NULL != currData->token && NULL != sendData->responseInfo->info.token)
2092 if (!strncmp(currData->token, sendData->responseInfo->info.token,
2093 currData->tokenLength))
2096 if (NULL != currData->sentData)
2098 OIC_LOG(DEBUG, TAG, "init block number");
2099 currData->block.num = 0;
2100 CADestroyDataSet(currData->sentData);
2102 currData->sentData = CACloneCAData(sendData);
2103 *blockData = currData;
2104 ca_mutex_unlock(g_context.blockDataListMutex);
2105 return CA_STATUS_OK;
2111 OIC_LOG(ERROR, TAG, "no CAInfo data");
2115 ca_mutex_unlock(g_context.blockDataListMutex);
2117 return CA_STATUS_FAILED;
2120 CABlockData_t *CAGetBlockDataFromBlockDataList(const unsigned char* token)
2122 VERIFY_NON_NULL_RET(token, TAG, "token", NULL);
2124 ca_mutex_lock(g_context.blockDataListMutex);
2126 size_t len = u_arraylist_length(g_context.dataList);
2127 for (size_t i = 0; i < len; i++)
2129 CABlockData_t *currData = (CABlockData_t *) u_arraylist_get(g_context.dataList, i);
2130 if (currData && currData->token)
2132 if (!strncmp(currData->token, (const char *) token, currData->tokenLength))
2134 ca_mutex_unlock(g_context.blockDataListMutex);
2139 ca_mutex_unlock(g_context.blockDataListMutex);
2144 coap_block_t *CAGetBlockOption(const unsigned char* token)
2146 OIC_LOG(DEBUG, TAG, "IN-GetBlockOption");
2147 VERIFY_NON_NULL_RET(token, TAG, "token", NULL);
2149 ca_mutex_lock(g_context.blockDataListMutex);
2151 size_t len = u_arraylist_length(g_context.dataList);
2152 for (size_t i = 0; i < len; i++)
2154 CABlockData_t *currData = (CABlockData_t *) u_arraylist_get(g_context.dataList, i);
2155 if (currData && currData->token)
2157 if (!strncmp(currData->token, (const char *) token, currData->tokenLength))
2159 ca_mutex_unlock(g_context.blockDataListMutex);
2160 OIC_LOG(DEBUG, TAG, "OUT-GetBlockOption");
2161 return &currData->block;
2165 ca_mutex_unlock(g_context.blockDataListMutex);
2167 OIC_LOG(DEBUG, TAG, "OUT-GetBlockOption");
2171 CAPayload_t CAGetPayloadFromBlockDataList(const unsigned char* token, size_t *fullPayloadLen)
2173 OIC_LOG(DEBUG, TAG, "IN-GetFullPayload");
2174 VERIFY_NON_NULL_RET(token, TAG, "token", NULL);
2175 VERIFY_NON_NULL_RET(fullPayloadLen, TAG, "fullPayloadLen", NULL);
2177 ca_mutex_lock(g_context.blockDataListMutex);
2179 size_t len = u_arraylist_length(g_context.dataList);
2180 for (size_t i = 0; i < len; i++)
2182 CABlockData_t *currData = (CABlockData_t *) u_arraylist_get(g_context.dataList, i);
2183 if (currData && currData->token)
2185 if (!strncmp(currData->token, (const char *) token, currData->tokenLength))
2187 ca_mutex_unlock(g_context.blockDataListMutex);
2188 *fullPayloadLen = currData->receivedPayloadLen;
2189 OIC_LOG(DEBUG, TAG, "OUT-GetFullPayload");
2190 return currData->payload;
2194 ca_mutex_unlock(g_context.blockDataListMutex);
2196 OIC_LOG(DEBUG, TAG, "OUT-GetFullPayload");
2200 CABlockData_t *CACreateNewBlockData(const CAData_t *sendData)
2202 OIC_LOG(DEBUG, TAG, "IN-CreateBlockData");
2203 VERIFY_NON_NULL_RET(sendData, TAG, "sendData", NULL);
2205 // create block data
2206 CABlockData_t *data = (CABlockData_t *) OICCalloc(1, sizeof(CABlockData_t));
2209 OIC_LOG(ERROR, TAG, "memory alloc has failed");
2213 data->block.num = 0;
2215 data->block.szx = CA_DEFAULT_BLOCK_SIZE;
2217 data->sentData = CACloneCAData(sendData);
2218 data->payload = NULL;
2219 data->payloadLength = 0;
2220 data->receivedPayloadLen = 0;
2222 if (data->sentData->requestInfo)
2224 // update token info
2225 uint8_t tokenLength = data->sentData->requestInfo->info.tokenLength;
2227 data->tokenLength = tokenLength;
2228 data->token = (char *) OICMalloc(tokenLength * sizeof(char));
2231 OIC_LOG(ERROR, TAG, "memory alloc has failed");
2235 memcpy(data->token, data->sentData->requestInfo->info.token, tokenLength);
2237 else if(data->sentData->responseInfo)
2239 uint8_t tokenLength = data->sentData->responseInfo->info.tokenLength;
2241 data->tokenLength = tokenLength;
2242 data->token = (char *) OICMalloc(tokenLength * sizeof(char));
2245 OIC_LOG(ERROR, TAG, "memory alloc has failed");
2249 memcpy(data->token, data->sentData->responseInfo->info.token, tokenLength);
2252 ca_mutex_lock(g_context.blockDataListMutex);
2254 CAResult_t res = u_arraylist_add(g_context.dataList, (void *) data);
2255 if (CA_STATUS_OK != res)
2257 OIC_LOG(ERROR, TAG, "add has failed");
2258 OICFree(data->token);
2260 ca_mutex_unlock(g_context.blockDataListMutex);
2263 ca_mutex_unlock(g_context.blockDataListMutex);
2265 OIC_LOG(DEBUG, TAG, "OUT-CreateBlockData");
2269 CAResult_t CARemoveBlockDataFromList(const unsigned char* token)
2271 OIC_LOG(DEBUG, TAG, "CARemoveBlockData");
2272 VERIFY_NON_NULL(token, TAG, "token");
2274 ca_mutex_lock(g_context.blockDataListMutex);
2276 size_t len = u_arraylist_length(g_context.dataList);
2277 for (size_t i = 0; i < len; i++)
2279 CABlockData_t *currData = (CABlockData_t *) u_arraylist_get(g_context.dataList, i);
2280 if (currData && currData->token)
2282 if (!strncmp(currData->token, (const char *) token, currData->tokenLength))
2284 CABlockData_t *removedData = u_arraylist_remove(g_context.dataList, i);
2285 if (NULL == removedData)
2287 OIC_LOG(ERROR, TAG, "data is NULL");
2288 ca_mutex_unlock(g_context.blockDataListMutex);
2289 return CA_STATUS_FAILED;
2293 if (currData->sentData)
2295 CADestroyDataSet(currData->sentData);
2297 OICFree(currData->payload);
2298 OICFree(currData->token);
2299 ca_mutex_unlock(g_context.blockDataListMutex);
2300 return CA_STATUS_OK;
2304 ca_mutex_unlock(g_context.blockDataListMutex);
2306 return CA_STATUS_OK;
2309 bool CAIsBlockDataInList(const coap_pdu_t *pdu)
2311 OIC_LOG(DEBUG, TAG, "IN-IsBlockDataInList");
2312 VERIFY_NON_NULL_RET(pdu, TAG, "pdu", false);
2313 VERIFY_NON_NULL_RET(pdu->hdr, TAG, "pdu->hdr", false);
2315 ca_mutex_lock(g_context.blockDataListMutex);
2317 size_t len = u_arraylist_length(g_context.dataList);
2318 for (size_t i = 0; i < len; i++)
2320 CABlockData_t *currData = (CABlockData_t *) u_arraylist_get(g_context.dataList, i);
2321 if (currData && currData->token)
2323 if (!strncmp(currData->token, (const char *) pdu->hdr->token, currData->tokenLength))
2325 OIC_LOG(DEBUG, TAG, "found block data");
2326 ca_mutex_unlock(g_context.blockDataListMutex);
2331 ca_mutex_unlock(g_context.blockDataListMutex);
2333 OIC_LOG(DEBUG, TAG, "OUT-IsBlockDataInList");
2337 void CADestroyDataSet(CAData_t* data)
2339 VERIFY_NON_NULL_VOID(data, TAG, "data");
2341 CAFreeEndpoint(data->remoteEndpoint);
2342 CADestroyRequestInfoInternal(data->requestInfo);
2343 CADestroyResponseInfoInternal(data->responseInfo);
2344 OICFree(data->options);
2348 void CALogBlockInfo(coap_block_t *block)
2350 VERIFY_NON_NULL_VOID(block, TAG, "block");
2352 OIC_LOG(DEBUG, TAG, "block option info");
2354 OIC_LOG_V(DEBUG, TAG, "block option-num : %d", block->num);
2356 OIC_LOG_V(DEBUG, TAG, "block option-m : %d", block->m);
2358 OIC_LOG_V(DEBUG, TAG, "block option-szx : %d", block->szx);