Merge branch 'master' into cloud-interface
[platform/upstream/iotivity.git] / resource / csdk / connectivity / inc / cablockwisetransfer.h
1 /* *****************************************************************
2  *
3  * Copyright 2015 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 /**
22  * @file
23  * This file contains common function for block messages.
24  */
25
26 #ifndef CA_BLOCKWISETRANSFER_H_
27 #define CA_BLOCKWISETRANSFER_H_
28
29 #include <stdint.h>
30
31 #include "coap.h"
32 #include "cathreadpool.h"
33 #include "camutex.h"
34 #include "uarraylist.h"
35 #include "cacommon.h"
36 #include "caprotocolmessage.h"
37 #include "camessagehandler.h"
38
39 #ifdef __cplusplus
40 extern "C"
41 {
42 #endif
43
44 /**
45  * Callback to send block data.
46  * @param[in]   data    send data.
47  */
48 typedef void (*CASendThreadFunc)(CAData_t *data);
49
50 /**
51  * Callback to notify received data from the remote endpoint.
52  * @param[in]   data    received data.
53  */
54 typedef void (*CAReceiveThreadFunc)(CAData_t *data);
55
56 /**
57  * context of blockwise transfer.
58  */
59 typedef struct
60 {
61     /** send method for block data. **/
62     CASendThreadFunc sendThreadFunc;
63
64     /** callback function for received message. **/
65     CAReceiveThreadFunc receivedThreadFunc;
66
67     /** array list on which the thread is operating. **/
68     u_arraylist_t *dataList;
69
70     /** data list mutex for synchronization. **/
71     ca_mutex blockDataListMutex;
72
73     /** sender mutex for synchronization. **/
74     ca_mutex blockDataSenderMutex;
75 } CABlockWiseContext_t;
76
77 /**
78  * ID set of Blockwise transfer data set(::CABlockData_t).
79  */
80 typedef struct
81 {
82     uint8_t* id;                       /**< blockData ID for CA. */
83     size_t idLength;                   /**< length of blockData ID. */
84 } CABlockDataID_t;
85
86 /**
87  * Block Data Set.
88  */
89 typedef struct
90 {
91     coap_block_t block1;                /**< block1 option. */
92     coap_block_t block2;                /**< block2 option. */
93     uint16_t type;                      /**< block option type. */
94     CABlockDataID_t* blockDataId;        /**< ID set of CABlockData. */
95     CAData_t *sentData;                 /**< sent request or response data information. */
96     CAPayload_t payload;                /**< payload buffer. */
97     size_t payloadLength;               /**< the total payload length to be received. */
98     size_t receivedPayloadLen;          /**< currently received payload length. */
99 } CABlockData_t;
100
101 /**
102  * state of received block message from remote endpoint.
103  */
104 typedef enum
105 {
106     CA_BLOCK_UNKNOWN = 0,
107     CA_OPTION1_RESPONSE,
108     CA_OPTION1_REQUEST_LAST_BLOCK,
109     CA_OPTION1_REQUEST_BLOCK,
110     CA_OPTION2_FIRST_BLOCK,
111     CA_OPTION2_LAST_BLOCK,
112     CA_OPTION2_RESPONSE,
113     CA_OPTION2_REQUEST,
114     CA_BLOCK_INCOMPLETE,
115     CA_BLOCK_TOO_LARGE,
116     CA_BLOCK_RECEIVED_ALREADY
117 } CABlockState_t;
118
119 /**
120  * Initializes the block-wise transfer context.
121  * @param[in]  CASendThreadFunc    function point to add data in send queue thread.
122  * @param[in]  CAReceiveThreadFunc function point to add data in receive queue thread.
123  * @return ::CASTATUS_OK or ERROR CODES (::CAResult_t error codes in cacommon.h).
124  */
125 CAResult_t CAInitializeBlockWiseTransfer(CASendThreadFunc blockSendMethod,
126                                          CAReceiveThreadFunc receivedDataCallback);
127
128 /**
129  * Terminate the block-wise transfer context.
130  * @return ::CASTATUS_OK or ERROR CODES (::CAResult_t error codes in cacommon.h).
131  */
132 CAResult_t CATerminateBlockWiseTransfer();
133
134 /**
135  * initialize mutex.
136  * @return ::CASTATUS_OK or ERROR CODES (::CAResult_t error codes in cacommon.h).
137  */
138 CAResult_t CAInitBlockWiseMutexVariables();
139
140 /**
141  * terminate mutex.
142  */
143 void CATerminateBlockWiseMutexVariables();
144
145 /**
146  * Pass the bulk data. if block-wise transfer process need,
147  *          bulk data will be sent to block messages.
148  * @param[in]   data    data for sending.
149  * @return ::CASTATUS_OK or ERROR CODES (::CAResult_t error codes in cacommon.h).
150  */
151 CAResult_t CASendBlockWiseData(const CAData_t *data);
152
153 /**
154  * Add the data to send thread queue.
155  * @param[in]   sendData    data for sending.
156  * @param[in]   blockID     ID set of CABlockData.
157  * @return ::CASTATUS_OK or ERROR CODES (::CAResult_t error codes in cacommon.h).
158  */
159 CAResult_t CAAddSendThreadQueue(const CAData_t *sendData, const CABlockDataID_t *blockID);
160
161 /**
162  * Check the block option type. If it has to be sent to a block,
163  *          block option will be set.
164  * @param[in]   currData    block data.
165  * @return ::CASTATUS_OK or ERROR CODES (::CAResult_t error codes in cacommon.h).
166  */
167 CAResult_t CACheckBlockOptionType(CABlockData_t *currData);
168
169 /**
170  * Pass the received pdu data. and check if block option is set.
171  * @param[in]   pdu    received pdu binary data.
172  * @param[in]   endpoint    information of remote device.
173  * @param[in]   receivedData    received CAData.
174  * @param[in]   dataLen    received data length.
175  * @return ::CASTATUS_OK or ERROR CODES (::CAResult_t error codes in cacommon.h).
176  */
177 CAResult_t CAReceiveBlockWiseData(coap_pdu_t *pdu, const CAEndpoint_t *endpoint,
178                                   const CAData_t *receivedData, size_t dataLen);
179
180 /**
181  * process next step by block-wise state.
182  * @param[in]   pdu    received pdu binary data.
183  * @param[in]   receivedData    received CAData.
184  * @param[in]   blockWiseStatus    block-wise state to move next step.
185  * @param[in]   blockID     ID set of CABlockData.
186  * @return ::CASTATUS_OK or ERROR CODES (::CAResult_t error codes in cacommon.h).
187  */
188 CAResult_t CAProcessNextStep(const coap_pdu_t *pdu, const CAData_t *receivedData,
189                              uint8_t blockWiseStatus, const CABlockDataID_t *blockID);
190
191 /**
192  * send block message to remote device.
193  * @param[in]   pdu    received pdu binary data.
194  * @param[in]   msgType    the message type of the block.
195  * @param[in]   blockID     ID set of CABlockData.
196  * @return ::CASTATUS_OK or ERROR CODES (::CAResult_t error codes in cacommon.h).
197  */
198 CAResult_t CASendBlockMessage(const coap_pdu_t *pdu, CAMessageType_t msgType,
199                               const CABlockDataID_t *blockID);
200
201 /**
202  * send error message to remote device.
203  * @param[in]   pdu    received pdu binary data.
204  * @param[in]   status    block-wise state to move next step.
205  * @param[in]   responseResult   response result code.
206  * @param[in]   blockID     ID set of CABlockData.
207  * @return ::CASTATUS_OK or ERROR CODES (::CAResult_t error codes in cacommon.h).
208  */
209 CAResult_t CASendErrorMessage(const coap_pdu_t *pdu, uint8_t status,
210                               CAResponseResult_t responseResult,
211                               const CABlockDataID_t *blockID);
212
213 /**
214  * receive last block data.
215  * @param[in]   blockID     ID set of CABlockData.
216  * @param[in]   receivedData    received CAData.
217  * @return ::CASTATUS_OK or ERROR CODES (::CAResult_t error codes in cacommon.h).
218  */
219 CAResult_t CAReceiveLastBlock(const CABlockDataID_t *blockID,
220                               const CAData_t *receivedData);
221
222 /**
223  * set next block option 1.
224  * @param[in]   pdu received pdu binary data.
225  * @param[in]   endpoint  information of remote device.
226  * @param[in]   receivedData    received CAData.
227  * @param[in]   block   block option data.
228  * @param[in]   dataLen received data length.
229  * @return ::CASTATUS_OK or ERROR CODES (::CAResult_t error codes in cacommon.h).
230  */
231 CAResult_t CASetNextBlockOption1(coap_pdu_t *pdu, const CAEndpoint_t *endpoint,
232                                  const CAData_t *receivedData, coap_block_t block,
233                                  size_t dataLen);
234
235 /**
236  * set next block option 2.
237  * @param[in]   pdu received pdu binary data.
238  * @param[in]   endpoint    information of remote device.
239  * @param[in]   receivedData    received CAData.
240  * @param[in]   block   block option data.
241  * @param[in]   dataLen received data length.
242  * @return ::CASTATUS_OK or ERROR CODES (::CAResult_t error codes in cacommon.h).
243  */
244 CAResult_t CASetNextBlockOption2(coap_pdu_t *pdu, const CAEndpoint_t *endpoint,
245                                  const CAData_t *receivedData, coap_block_t block,
246                                  size_t dataLen);
247
248 /**
249  * Update the block option in block-wise transfer list.
250  * @param[in]   currData   stored block data information.
251  * @param[in]   block   block option to update.
252  * @param[in]   msgType message type of pdu.
253  * @param[in]   blockType   block option type.
254  * @return ::CASTATUS_OK or ERROR CODES (::CAResult_t error codes in cacommon.h).
255  */
256 CAResult_t CANegotiateBlockSize(CABlockData_t *currData, coap_block_t *block,
257                                 const coap_pdu_t *pdu, uint16_t blockType);
258
259 /**
260  * Update the block option in block-wise transfer list.
261  * @param[in]   currData    stored block data information.
262  * @param[in]   block   block option of current message.
263  * @param[in]   blockType   block option type.
264  * @return ::CASTATUS_OK or ERROR CODES (::CAResult_t error codes in cacommon.h).
265  */
266 CAResult_t CAUpdateBlockData(CABlockData_t *currData, coap_block_t block,
267                              uint16_t blockType);
268
269 /**
270  * Update the messageId in block-wise transfer list.
271  * @param[in]   pdu   received pdu binary data.
272  * @param[in]   blockID     ID set of CABlockData.
273  * @return ::CASTATUS_OK or ERROR CODES (::CAResult_t error codes in cacommon.h).
274  */
275 CAResult_t CAUpdateMessageId(coap_pdu_t *pdu, const CABlockDataID_t *blockID);
276
277 /**
278  * Update the block option items.
279  * @param[in]   currData    stored block data information.
280  * @param[in]   pdu received pdu binary data.
281  * @param[in/out]   block   block option of current message.
282  * @param[in]   blockType  block option type.
283  * @param[in]   status  current flow status for block-wise transfer.
284  * @return ::CASTATUS_OK or ERROR CODES (::CAResult_t error codes in cacommon.h).
285  */
286 CAResult_t CAUpdateBlockOptionItems(CABlockData_t *currData, const coap_pdu_t *pdu,
287                                     coap_block_t *block, uint16_t blockType,
288                                     uint32_t status);
289 /**
290  * Set the M-bit of block option.
291  * @param[in]   payloadLen  payload length of current bulk data.
292  * @param[out]  block   block option.
293  * @return ::CASTATUS_OK or ERROR CODES (::CAResult_t error codes in cacommon.h).
294  */
295 CAResult_t CASetMoreBitFromBlock(size_t payloadLen, coap_block_t *block);
296
297 /**
298  * check the block option what kind of option have to set.
299  * @param[out]  pdu pdu object.
300  * @param[in]   info    information of the request/response.
301  * @param[in]   endpoint    port of transport.
302  * @return ::CASTATUS_OK or ERROR CODES (::CAResult_t error codes in cacommon.h).
303  */
304 CAResult_t CAAddBlockOption(coap_pdu_t **pdu, const CAInfo_t *info,
305                             const CAEndpoint_t *endpoint, coap_list_t **options);
306
307 /**
308  * Write the block option2 in pdu binary data.
309  * @param[out]  pdu   pdu object.
310  * @param[in]   info    information of the request/response.
311  * @param[in]   dataLength  length of payload.
312  * @param[in]   blockID     ID set of CABlockData.
313  * @return ::CASTATUS_OK or ERROR CODES (::CAResult_t error codes in cacommon.h).
314  */
315 CAResult_t CAAddBlockOption2(coap_pdu_t **pdu, const CAInfo_t *info, size_t dataLength,
316                              const CABlockDataID_t *blockID, coap_list_t **options);
317
318 /**
319  * Write the block option1 in pdu binary data.
320  * @param[out]  pdu    pdu object.
321  * @param[in]   info    information of the request/response.
322  * @param[in]   dataLength length of payload.
323  * @param[in]   blockID     ID set of CABlockData.
324  * @return ::CASTATUS_OK or ERROR CODES (::CAResult_t error codes in cacommon.h).
325  */
326 CAResult_t CAAddBlockOption1(coap_pdu_t **pdu, const CAInfo_t *info, size_t dataLength,
327                              const CABlockDataID_t *blockID, coap_list_t **options);
328
329 /**
330  * Add the block option in option list.
331  * @param[out]  block    block data.
332  * @param[in]   blockType   block option type.
333  * @param[out]  options   option list.
334  * @return ::CASTATUS_OK or ERROR CODES (::CAResult_t error codes in cacommon.h).
335  */
336 CAResult_t CAAddBlockOptionImpl(coap_block_t *block, uint8_t blockType,
337                                 coap_list_t **options);
338
339 /**
340  * Add the option list in pdu data.
341  * @param[out]  pdu    pdu object.
342  * @param[out]  options   option list.
343  * @return ::CASTATUS_OK or ERROR CODES (::CAResult_t error codes in cacommon.h).
344  */
345 CAResult_t CAAddOptionToPDU(coap_pdu_t *pdu, coap_list_t **options);
346
347 /**
348  * Add the size option in pdu data.
349  * @param[in/out]   pdu    pdu object.
350  * @param[in]   sizeType    size option type.
351  * @param[in]   dataLength the total payload length to be sent.
352  * @return ::CASTATUS_OK or ERROR CODES (::CAResult_t error codes in cacommon.h).
353  */
354 CAResult_t CAAddBlockSizeOption(coap_pdu_t *pdu, uint16_t sizeType, size_t dataLength,
355                                 coap_list_t **options);
356
357 /**
358  * Get the size option from pdu data.
359  * @param[in]   pdu    pdu object.
360  * @param[in]   sizeType    size option type.
361  * @param[out]  totalPayloadLen the total payload length to be received.
362  * @return true or false.
363  */
364 bool CAIsPayloadLengthInPduWithBlockSizeOption(coap_pdu_t *pdu,
365                                                uint16_t sizeType,
366                                                size_t *totalPayloadLen);
367
368 /**
369  * update the total payload with the received payload.
370  * @param[in]   currData    stored block data information.
371  * @param[in]   receivedData    received CAData.
372  * @param[in]   status  block-wise state.
373  * @param[in]   isSizeOption    size option.
374  * @param[in]   blockType    block option type.
375  * @return ::CASTATUS_OK or ERROR CODES (::CAResult_t error codes in cacommon.h).
376  */
377 CAResult_t CAUpdatePayloadData(CABlockData_t *currData, const CAData_t *receivedData,
378                                uint8_t status, bool isSizeOption, uint16_t blockType);
379
380 /**
381  * Generate CAData structure  from the given information.
382  * @param[in]   pdu    pdu object.
383  * @param[in]   endpoint    information of remote device.
384  * @return generated CAData.
385  */
386 CAData_t* CACreateNewDataSet(const coap_pdu_t *pdu, const CAEndpoint_t *endpoint);
387
388 /**
389  * Update the block option items.
390  * @param[in/out]   blockblock option of current message.
391  * @param[in]   blockType   block option type.
392  * @param[in]   responseResult  result code of pdu.
393  * @return ::CASTATUS_OK or ERROR CODES (::CAResult_t error codes in cacommon.h).
394  */
395 CAResult_t CAHandleBlockErrorResponse(coap_block_t *block, uint16_t blockType,
396                                       uint32_t responseResult);
397
398 /**
399  * Check the received payload and if an error happens, return error type.
400  * @param[in/out]   currData    stored block data information.
401  * @param[in]   receivedBlock   received block option.
402  * @param[in]   receivedData    message type of pdu.
403  * @param[in]   blockType   block option type.
404  * @param[in]   dataLen received data length.
405  * @return block state.
406  */
407 uint8_t CACheckBlockErrorType(CABlockData_t *currData, coap_block_t *receivedBlock,
408                               const CAData_t *receivedData, uint16_t blockType,
409                               size_t dataLen);
410
411 /**
412  * Destroys the given CAData.
413  * @param[in]   data    CAData to destroy.
414  * @return generated CAData.
415  */
416 void CADestroyDataSet(CAData_t* data);
417
418 /**
419  * Create the blockId for CABlockData.
420  * @param[in]   token   token of current message.
421  * @param[in]   tokenLength   token length of current message.
422  * @param[in]   portNumber   port.
423  * @return ID set of CABlockData.
424  */
425 CABlockDataID_t* CACreateBlockDatablockId(const CAToken_t token, uint8_t tokenLength,
426                                           uint16_t portNumber);
427
428 /**
429  * Destroy the blockId set.
430  * @param[in]   blockID     ID set of CABlockData.
431  */
432 void CADestroyBlockID(CABlockDataID_t *blockID);
433
434 /**
435  * check whether Block ID is matched or not.
436  * @param[in]   currData    block data.
437  * @param[in]   blockID     ID set of CABlockData.
438  * @return true or false.
439  */
440 bool CABlockidMatches(const CABlockData_t *currData, const CABlockDataID_t *blockID);
441 /**
442  * Print the given block option information.
443  * @param[in]   block   block option information.
444  */
445 void CALogBlockInfo(coap_block_t *block);
446
447 /**
448  * Create new CAData structure from the input information.
449  * @param[in]   data    CAData information that needs to be duplicated.
450  * @return created CAData structure.
451  */
452 CAData_t *CACloneCAData(const CAData_t *data);
453
454 /**
455  * Update payload from the input information.
456  * @param[in]   data    CAData information that needs to be updated.
457  * @param[in]   payload received new payload from the remote endpoint.
458  * @param[in]   payloadLen  received full payload length.
459  * @return ::CASTATUS_OK or ERROR CODES (::CAResult_t error codes in cacommon.h).
460  */
461 CAResult_t CAUpdatePayloadToCAData(CAData_t *data, const CAPayload_t payload,
462                                    size_t payloadLen);
463
464 /**
465  * Get payload and payload length from the input information.
466  * @param[in]   data    CAData information.
467  * @param[out]  payloadLen  The payload length is stored.
468  * @return payload.
469  */
470 CAPayload_t CAGetPayloadInfo(const CAData_t *data, size_t *payloadLen);
471
472 /**
473  * Set the block option type.
474  * @param[in]   blockID     ID set of CABlockData.
475  * @param[in]   blockType   block option type.
476  * @return ::CASTATUS_OK or ERROR CODES (::CAResult_t error codes in cacommon.h).
477  */
478 CAResult_t CAUpdateBlockOptionType(const CABlockDataID_t *blockID,
479                                    uint8_t blockType);
480
481 /**
482  * Get the block option type from block-wise transfer list.
483  * @param[in]   blockID     ID set of CABlockData.
484  * @return block option type.
485  */
486 uint8_t CAGetBlockOptionType(const CABlockDataID_t *blockID);
487
488 /**
489  * Get the block data from block-wise transfer list.
490  * @param[in]   blockID     ID set of CABlockData.
491  * @return CAData structure.
492  */
493 CAData_t *CAGetDataSetFromBlockDataList(const CABlockDataID_t *blockID);
494
495 /**
496  * Get token from block-wise transfer list.
497  * @param[in]   pdu    received pdu binary data.
498  * @param[in]   endpoint    remote endpoint information.
499  * @param[in]   responseInfo    received response information.
500  * @return ::CASTATUS_OK or ERROR CODES (::CAResult_t error codes in cacommon.h).
501  */
502 CAResult_t CAGetTokenFromBlockDataList(const coap_pdu_t *pdu, const CAEndpoint_t *endpoint,
503                                        CAResponseInfo_t *responseInfo);
504
505 /**
506  * check whether the block data is valid or not.
507  * @param[in]   sendData    CAData information.
508  * @param[out]  blockData   block data when it is valid.
509  * @return ::CASTATUS_OK or ERROR CODES (::CAResult_t error codes in cacommon.h).
510  */
511 CAResult_t CACheckBlockDataValidation(const CAData_t *sendData, CABlockData_t **blockData);
512
513 /**
514  * Get the block data from block-wise transfer list.
515  * @param[in]   blockID     ID set of CABlockData.
516  * @return CABlockData_t structure.
517  */
518 CABlockData_t *CAGetBlockDataFromBlockDataList(const CABlockDataID_t *blockID);
519
520 /**
521  * Get the block option from block-wise transfer list.
522  * @param[in]   blockID     ID set of CABlockData.
523  * @param[in]   blockType    block option type.
524  * @return coap_block_t structure.
525  */
526 coap_block_t *CAGetBlockOption(const CABlockDataID_t *blockID,
527                                uint16_t blockType);
528
529 /**
530  * Get the full payload from block-wise list.
531  * @param[in]   blockID     ID set of CABlockData.
532  * @param[out]  fullPayloadLen  received full payload length.
533  * @return payload.
534  */
535 CAPayload_t CAGetPayloadFromBlockDataList(const CABlockDataID_t *blockID,
536                                           size_t *fullPayloadLen);
537
538 /**
539  * Create the block data from given data and add the data in block-wise transfer list.
540  * @param[in]   sendData    data to be added to a list.
541  * @return created CABlockData_t structure.
542  *         and NULL point will be returned if there is error case..
543  */
544 CABlockData_t *CACreateNewBlockData(const CAData_t *sendData);
545
546 /**
547  * Remove the block data in block-wise transfer list.
548  * @param[in]   blockID     ID set of CABlockData.
549  * @return ::CASTATUS_OK or ERROR CODES (::CAResult_t error codes in cacommon.h).
550  */
551 CAResult_t CARemoveBlockDataFromList(const CABlockDataID_t *blockID);
552
553 /**
554  * Remove all block data in block-wise transfer list.
555  * @return ::CASTATUS_OK or ERROR CODES (::CAResult_t error codes in cacommon.h).
556  */
557 CAResult_t CARemoveAllBlockDataFromList();
558
559 /**
560  * Find the block data with seed info and remove it from block-wise transfer list.
561  * @param[in]   token         token of the message.
562  * @param[in]   tokenLength   token length of the message.
563  * @param[in]   portNumber    port.
564  * @return ::CASTATUS_OK or ERROR CODES (::CAResult_t error codes in cacommon.h).
565  */
566 CAResult_t CARemoveBlockDataFromListWithSeed(const CAToken_t token, uint8_t tokenLength,
567                                              uint16_t portNumber);
568
569 #ifdef __cplusplus
570 } /* extern "C" */
571 #endif
572
573 #endif  // CA_BLOCKWISETRANSFER_H_