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