From c3331ed3aceb433f9b6024feb9014b24debebc73 Mon Sep 17 00:00:00 2001 From: "jihwan.seo" Date: Thu, 13 Aug 2015 17:35:29 +0900 Subject: [PATCH] base code related to coap header of 'CoAP Over TCP' in libcoap. - length field of coap header can be consist 8/16/32 bit with unsigned integer. - https://wiki.iotivity.org/proposal_for_cloud_interface_in_iotivity Change-Id: Ieedaa8d7812f0375e40d5d6e13c6f332d22d68bd Signed-off-by: jihwan.seo Reviewed-on: https://gerrit.iotivity.org/gerrit/2196 Reviewed-by: Jaehong Jo Reviewed-by: Jon A. Cruz Tested-by: Jon A. Cruz --- resource/csdk/connectivity/api/cacommon.h | 7 + resource/csdk/connectivity/inc/caadapterutils.h | 5 - resource/csdk/connectivity/inc/camessagehandler.h | 3 +- resource/csdk/connectivity/inc/caprotocolmessage.h | 24 +- .../csdk/connectivity/lib/libcoap-4.1.1/async.c | 12 +- .../csdk/connectivity/lib/libcoap-4.1.1/block.c | 3 +- resource/csdk/connectivity/lib/libcoap-4.1.1/net.c | 125 +++--- .../csdk/connectivity/lib/libcoap-4.1.1/option.c | 76 +++- .../csdk/connectivity/lib/libcoap-4.1.1/option.h | 4 +- resource/csdk/connectivity/lib/libcoap-4.1.1/pdu.c | 498 ++++++++++++++++++--- resource/csdk/connectivity/lib/libcoap-4.1.1/pdu.h | 220 +++++++-- .../csdk/connectivity/lib/libcoap-4.1.1/resource.c | 19 +- .../connectivity/src/adapter_util/caadapterutils.c | 14 - .../csdk/connectivity/src/cablockwisetransfer.c | 87 ++-- resource/csdk/connectivity/src/camessagehandler.c | 142 ++++-- resource/csdk/connectivity/src/caprotocolmessage.c | 217 ++++++--- 16 files changed, 1118 insertions(+), 338 deletions(-) diff --git a/resource/csdk/connectivity/api/cacommon.h b/resource/csdk/connectivity/api/cacommon.h index cc261ce..02fd501 100644 --- a/resource/csdk/connectivity/api/cacommon.h +++ b/resource/csdk/connectivity/api/cacommon.h @@ -141,6 +141,10 @@ typedef enum CA_ADAPTER_REMOTE_ACCESS = (1 << 3), // Remote Access over XMPP. #endif + #ifdef CI_ADAPTER + CA_ADAPTER_CLOUD_INTERFACE = (1 << 4), // CoAP over TCP for Cloud Interface + #endif + CA_ALL_ADAPTERS = 0xffffffff } CATransportAdapter_t; @@ -155,6 +159,9 @@ typedef enum CA_IPV4 = (1 << 6), // IP adapter only // Indication that a message was received by multicast. CA_MULTICAST = (1 << 7), + #ifdef CI_ADAPTER + CA_IPV4_TCP = (1 << 8), + #endif // Link-Local multicast is the default multicast scope for IPv6. // These correspond in both value and position to the IPv6 address bits. CA_SCOPE_INTERFACE = 0x1, // IPv6 Interface-Local scope diff --git a/resource/csdk/connectivity/inc/caadapterutils.h b/resource/csdk/connectivity/inc/caadapterutils.h index c1e17c7..7c9611b 100644 --- a/resource/csdk/connectivity/inc/caadapterutils.h +++ b/resource/csdk/connectivity/inc/caadapterutils.h @@ -107,11 +107,6 @@ typedef struct } CAServerInfo_t; /** - * To log the PDU data. - */ -void CALogPDUData(coap_pdu_t *pdu); - -/** * To parse the IP address and port from "ipaddress:port". * @param[in] ipAddrStr IP address to be parsed. * @param[out] ipAddr Parsed IP address. diff --git a/resource/csdk/connectivity/inc/camessagehandler.h b/resource/csdk/connectivity/inc/camessagehandler.h index 45f9f64..ad152c0 100644 --- a/resource/csdk/connectivity/inc/camessagehandler.h +++ b/resource/csdk/connectivity/inc/camessagehandler.h @@ -129,8 +129,9 @@ void CAHandleRequestResponseCallbacks(); /** * To log the PDU data. * @param[in] pdu pdu data. + * @param[in] flags transport type. */ -void CALogPDUInfo(coap_pdu_t *pdu); +void CALogPDUInfo(coap_pdu_t *pdu, CATransportFlags_t flags); #ifdef WITH_BWT /** diff --git a/resource/csdk/connectivity/inc/caprotocolmessage.h b/resource/csdk/connectivity/inc/caprotocolmessage.h index d97af0d..c757de8 100644 --- a/resource/csdk/connectivity/inc/caprotocolmessage.h +++ b/resource/csdk/connectivity/inc/caprotocolmessage.h @@ -62,25 +62,31 @@ coap_pdu_t *CAGeneratePDU(uint32_t code, const CAInfo_t *info, const CAEndpoint_ * extracts request information from received pdu. * @param[in] pdu received pdu. * @param[out] outReqInfo request info structure made from received pdu. + * @param[in] flags transport type. * @return CA_STATUS_OK or ERROR CODES (CAResult_t error codes in cacommon.h). */ -CAResult_t CAGetRequestInfoFromPDU(const coap_pdu_t *pdu, CARequestInfo_t *outReqInfo); +CAResult_t CAGetRequestInfoFromPDU(const coap_pdu_t *pdu, CARequestInfo_t *outReqInfo, + CATransportFlags_t flags); /** * extracts response information from received pdu. * @param[in] pdu received pdu. * @param[out] outResInfo response info structure made from received pdu. + * @param[in] flags transport type. * @return CA_STATUS_OK or ERROR CODES (CAResult_t error codes in cacommon.h). */ -CAResult_t CAGetResponseInfoFromPDU(const coap_pdu_t *pdu, CAResponseInfo_t *outResInfo); +CAResult_t CAGetResponseInfoFromPDU(const coap_pdu_t *pdu, CAResponseInfo_t *outResInfo, + CATransportFlags_t flags); /** * extracts error information from received pdu. * @param[in] pdu received pdu. * @param[out] errorInfo error info structure made from received pdu. + * @param[in] flags transport type. * @return CA_STATUS_OK or ERROR CODES (CAResult_t error codes in cacommon.h). */ -CAResult_t CAGetErrorInfoFromPDU(const coap_pdu_t *pdu, CAErrorInfo_t *errorInfo); +CAResult_t CAGetErrorInfoFromPDU(const coap_pdu_t *pdu, CAErrorInfo_t *errorInfo, + CATransportFlags_t flags); /** * creates pdu from the request information. @@ -164,26 +170,32 @@ uint32_t CAGetOptionData(const uint8_t *data, uint32_t len, uint8_t *option, uin * @param[in] pdu received pdu. * @param[out] outCode code of the received pdu. * @param[out] outInfo request info structure made from received pdu. + * @param[in] flags transport type. * @return CA_STATUS_OK or ERROR CODES (CAResult_t error codes in cacommon.h). */ -CAResult_t CAGetInfoFromPDU(const coap_pdu_t *pdu, uint32_t *outCode, CAInfo_t *outInfo); +CAResult_t CAGetInfoFromPDU(const coap_pdu_t *pdu, uint32_t *outCode, CAInfo_t *outInfo, + CATransportFlags_t flags); /** * create pdu from received data. * @param[in] data received data. * @param[in] length length of the data received. * @param[out] outCode code received. + * @param[in] flags transport type. * @return coap_pdu_t value. */ -coap_pdu_t *CAParsePDU(const char *data, uint32_t length, uint32_t *outCode); +coap_pdu_t *CAParsePDU(const char *data, uint32_t length, uint32_t *outCode, + CATransportFlags_t flags); /** * get Token from received data(pdu). * @param[in] pdu_hdr header of received pdu. * @param[out] outInfo information with token received. + * @param[in] flags transport type. * @return CA_STATUS_OK or ERROR CODES (CAResult_t error codes in cacommon.h). */ -CAResult_t CAGetTokenFromPDU(const coap_hdr_t *pdu_hdr, CAInfo_t *outInfo); +CAResult_t CAGetTokenFromPDU(const coap_hdr_t *pdu_hdr, CAInfo_t *outInfo, + CATransportFlags_t flags); /** * generates the token. diff --git a/resource/csdk/connectivity/lib/libcoap-4.1.1/async.c b/resource/csdk/connectivity/lib/libcoap-4.1.1/async.c index 08cdb86..5bf5d95 100644 --- a/resource/csdk/connectivity/lib/libcoap-4.1.1/async.c +++ b/resource/csdk/connectivity/lib/libcoap-4.1.1/async.c @@ -41,28 +41,28 @@ coap_register_async(coap_context_t *context, coap_address_t *peer, coap_pdu_t *r /* store information for handling the asynchronous task */ s = (coap_async_state_t *) coap_malloc(sizeof(coap_async_state_t) + - request->hdr->token_length); + request->hdr->coap_hdr_udp_t.token_length); if (!s) { coap_log(LOG_CRIT, "coap_register_async: insufficient memory\n"); return NULL; } - memset(s, 0, sizeof(coap_async_state_t) + request->hdr->token_length); + memset(s, 0, sizeof(coap_async_state_t) + request->hdr->coap_hdr_udp_t.token_length); /* set COAP_ASYNC_CONFIRM according to request's type */ s->flags = flags & ~COAP_ASYNC_CONFIRM; - if (request->hdr->type == COAP_MESSAGE_CON) + if (request->hdr->coap_hdr_udp_t.type == COAP_MESSAGE_CON) s->flags |= COAP_ASYNC_CONFIRM; s->appdata = data; memcpy(&s->peer, peer, sizeof(coap_address_t)); - if (request->hdr->token_length) + if (request->hdr->coap_hdr_udp_t.token_length) { - s->tokenlen = request->hdr->token_length; - memcpy(s->token, request->hdr->token, request->hdr->token_length); + s->tokenlen = request->hdr->coap_hdr_udp_t.token_length; + memcpy(s->token, request->hdr->coap_hdr_udp_t.token, request->hdr->coap_hdr_udp_t.token_length); } memcpy(&s->id, &id, sizeof(coap_tid_t)); diff --git a/resource/csdk/connectivity/lib/libcoap-4.1.1/block.c b/resource/csdk/connectivity/lib/libcoap-4.1.1/block.c index c0373f7..de83a62 100644 --- a/resource/csdk/connectivity/lib/libcoap-4.1.1/block.c +++ b/resource/csdk/connectivity/lib/libcoap-4.1.1/block.c @@ -126,7 +126,8 @@ int coap_write_block_opt(coap_block_t *block, unsigned short type, coap_pdu_t *p /* to re-encode the block option */ coap_add_option(pdu, type, - coap_encode_var_bytes(buf, ((block->num << 4) | (block->m << 3) | block->szx)), buf); + coap_encode_var_bytes(buf, ((block->num << 4) | (block->m << 3) | block->szx)), buf, + coap_udp); return 1; } diff --git a/resource/csdk/connectivity/lib/libcoap-4.1.1/net.c b/resource/csdk/connectivity/lib/libcoap-4.1.1/net.c index af5f022..d3ea2ec 100644 --- a/resource/csdk/connectivity/lib/libcoap-4.1.1/net.c +++ b/resource/csdk/connectivity/lib/libcoap-4.1.1/net.c @@ -498,7 +498,7 @@ int coap_option_check_critical(coap_context_t *ctx, coap_pdu_t *pdu, coap_opt_fi coap_opt_iterator_t opt_iter; int ok = 1; - coap_option_iterator_init(pdu, &opt_iter, COAP_OPT_ALL); + coap_option_iterator_init(pdu, &opt_iter, COAP_OPT_ALL, coap_udp); while (coap_option_next(&opt_iter)) { @@ -562,7 +562,7 @@ void coap_transaction_id(const coap_address_t *peer, const coap_pdu_t *pdu, coap coap_hash((const unsigned char *)&peer->addr, sizeof(peer->addr), h); #endif /* WITH_LWIP || WITH_CONTIKI */ - coap_hash((const unsigned char *)&pdu->hdr->id, sizeof(unsigned short), h); + coap_hash((const unsigned char *)&pdu->hdr->coap_hdr_udp_t.id, sizeof(unsigned short), h); *id = ((h[0] << 8) | h[1]) ^ ((h[2] << 8) | h[3]); } @@ -572,9 +572,10 @@ coap_tid_t coap_send_ack(coap_context_t *context, const coap_address_t *dst, coa coap_pdu_t *response; coap_tid_t result = COAP_INVALID_TID; - if (request && request->hdr->type == COAP_MESSAGE_CON) + if (request && request->hdr->coap_hdr_udp_t.type == COAP_MESSAGE_CON) { - response = coap_pdu_init(COAP_MESSAGE_ACK, 0, request->hdr->id, sizeof(coap_pdu_t)); + response = coap_pdu_init(COAP_MESSAGE_ACK, 0, request->hdr->coap_hdr_udp_t.id, + sizeof(coap_pdu_t), coap_udp); if (response) { result = coap_send(context, dst, response); @@ -735,7 +736,8 @@ coap_tid_t coap_send_message_type(coap_context_t *context, const coap_address_t if (request) { - response = coap_pdu_init(type, 0, request->hdr->id, sizeof(coap_pdu_t)); + response = coap_pdu_init(type, 0, request->hdr->coap_hdr_udp_t.id, + sizeof(coap_pdu_t), coap_udp); if (response) { result = coap_send(context, dst, response); @@ -830,12 +832,14 @@ coap_tid_t coap_retransmit(coap_context_t *context, coap_queue_t *node) node->t = node->timeout << node->retransmit_cnt; coap_insert_node(&context->sendqueue, node); #ifdef WITH_LWIP - if (node == context->sendqueue) /* don't bother with timer stuff if there are earlier retransmits */ + /* don't bother with timer stuff if there are earlier retransmits */ + if (node == context->sendqueue) coap_retransmittimer_restart(context); #endif debug( - "** retransmission #%d of transaction %d\n", node->retransmit_cnt, ntohs(node->pdu->hdr->id)); + "** retransmission #%d of transaction %d\n", node->retransmit_cnt, + ntohs(node->pdu->hdr->coap_hdr_udp_t.id)); node->id = coap_send_impl(context, &node->remote, node->pdu); return node->id; @@ -850,13 +854,13 @@ coap_tid_t coap_retransmit(coap_context_t *context, coap_queue_t *node) #ifndef WITHOUT_OBSERVE /* Check if subscriptions exist that should be canceled after COAP_MAX_NOTIFY_FAILURES */ - if (node->pdu->hdr->code >= 64) + if (node->pdu->hdr->coap_hdr_udp_t.code >= 64) { str token = { 0, NULL }; - token.length = node->pdu->hdr->token_length; - token.s = node->pdu->hdr->token; + token.length = node->pdu->hdr->coap_hdr_udp_t.token_length; + token.s = node->pdu->hdr->coap_hdr_udp_t.token; coap_handle_failed_notify(context, &node->remote, &token); } @@ -947,7 +951,7 @@ int coap_read(coap_context_t *ctx) goto error_early; } - if (pdu->version != COAP_DEFAULT_VERSION) + if (pdu->coap_hdr_udp_t.version != COAP_DEFAULT_VERSION) { debug("coap_read: unknown protocol version\n"); goto error_early; @@ -961,7 +965,7 @@ int coap_read(coap_context_t *ctx) node->pdu = coap_pdu_from_pbuf(ctx->pending_package); ctx->pending_package = NULL; #else - node->pdu = coap_pdu_init(0, 0, 0, bytes_read); + node->pdu = coap_pdu_init(0, 0, 0, bytes_read, coap_udp); #endif if (!node->pdu) goto error; @@ -970,7 +974,7 @@ int coap_read(coap_context_t *ctx) memcpy(&node->local, &dst, sizeof(coap_address_t)); memcpy(&node->remote, &src, sizeof(coap_address_t)); - if (!coap_pdu_parse((unsigned char *) buf, bytes_read, node->pdu)) + if (!coap_pdu_parse((unsigned char *) buf, bytes_read, node->pdu, coap_udp)) { warn("discard malformed PDU"); goto error; @@ -1075,12 +1079,12 @@ void coap_cancel_all_messages(coap_context_t *context, const coap_address_t *dst debug("cancel_all_messages\n"); while (context->sendqueue && coap_address_equals(dst, &context->sendqueue->remote) - && token_match(token, token_length, context->sendqueue->pdu->hdr->token, - context->sendqueue->pdu->hdr->token_length)) + && token_match(token, token_length, context->sendqueue->pdu->hdr->coap_hdr_udp_t.token, + context->sendqueue->pdu->hdr->coap_hdr_udp_t.token_length)) { q = context->sendqueue; context->sendqueue = q->next; - debug("**** removed transaction %d\n", ntohs(q->pdu->hdr->id)); + debug("**** removed transaction %d\n", ntohs(q->pdu->hdr->coap_hdr_udp_t.id)); coap_delete_node(q); } @@ -1094,10 +1098,11 @@ void coap_cancel_all_messages(coap_context_t *context, const coap_address_t *dst while (q) { if (coap_address_equals(dst, &q->remote) - && token_match(token, token_length, q->pdu->hdr->token, q->pdu->hdr->token_length)) + && token_match(token, token_length, q->pdu->hdr->coap_hdr_udp_t.token, + q->pdu->hdr->coap_hdr_udp_t.token_length)) { p->next = q->next; - debug("**** removed transaction %d\n", ntohs(q->pdu->hdr->id)); + debug("**** removed transaction %d\n", ntohs(q->pdu->hdr->coap_hdr_udp_t.id)); coap_delete_node(q); q = p->next; } @@ -1123,7 +1128,7 @@ coap_new_error_response(coap_pdu_t *request, unsigned char code, coap_opt_filter { coap_opt_iterator_t opt_iter; coap_pdu_t *response; - size_t size = sizeof(coap_hdr_t) + request->hdr->token_length; + size_t size = sizeof(coap_hdr_t) + request->hdr->coap_hdr_udp_t.token_length; int type; coap_opt_t *option; unsigned short opt_type = 0; /* used for calculating delta-storage */ @@ -1139,14 +1144,14 @@ coap_new_error_response(coap_pdu_t *request, unsigned char code, coap_opt_filter assert(request); /* cannot send ACK if original request was not confirmable */ - type = request->hdr->type == COAP_MESSAGE_CON ? COAP_MESSAGE_ACK : COAP_MESSAGE_NON; + type = request->hdr->coap_hdr_udp_t.type == COAP_MESSAGE_CON ? COAP_MESSAGE_ACK : COAP_MESSAGE_NON; /* Estimate how much space we need for options to copy from * request. We always need the Token, for 4.02 the unknown critical * options must be included as well. */ coap_option_clrb(opts, COAP_OPTION_CONTENT_TYPE); /* we do not want this */ - coap_option_iterator_init(request, &opt_iter, opts); + coap_option_iterator_init(request, &opt_iter, opts, coap_udp); /* Add size of each unknown critical option. As known critical options as well as elective options are not copied, the delta @@ -1189,11 +1194,12 @@ coap_new_error_response(coap_pdu_t *request, unsigned char code, coap_opt_filter } /* Now create the response and fill with options and payload data. */ - response = coap_pdu_init(type, code, request->hdr->id, size); + response = coap_pdu_init(type, code, request->hdr->coap_hdr_udp_t.id, size, coap_udp); if (response) { /* copy token */ - if (!coap_add_token(response, request->hdr->token_length, request->hdr->token)) + if (!coap_add_token(response, request->hdr->coap_hdr_udp_t.token_length, + request->hdr->coap_hdr_udp_t.token, coap_udp)) { debug("cannot add token to error response\n"); coap_delete_pdu(response); @@ -1201,10 +1207,10 @@ coap_new_error_response(coap_pdu_t *request, unsigned char code, coap_opt_filter } /* copy all options */ - coap_option_iterator_init(request, &opt_iter, opts); + coap_option_iterator_init(request, &opt_iter, opts, coap_udp); while ((option = coap_option_next(&opt_iter))) coap_add_option(response, opt_iter.type, COAP_OPT_LENGTH(option), - COAP_OPT_VALUE(option)); + COAP_OPT_VALUE(option), coap_udp); #if COAP_ERROR_PHRASE_LENGTH > 0 /* note that diagnostic messages do not need a Content-Format option. */ @@ -1252,16 +1258,17 @@ wellknown_response(coap_context_t *context, coap_pdu_t *request) size_t offset = 0; resp = coap_pdu_init( - request->hdr->type == COAP_MESSAGE_CON ? COAP_MESSAGE_ACK : COAP_MESSAGE_NON, + request->hdr->coap_hdr_udp_t.type == COAP_MESSAGE_CON ? COAP_MESSAGE_ACK : COAP_MESSAGE_NON, COAP_RESPONSE_CODE(205), - request->hdr->id, COAP_MAX_PDU_SIZE); + request->hdr->coap_hdr_udp_t.id, COAP_MAX_PDU_SIZE, coap_udp); if (!resp) { debug("wellknown_response: cannot create PDU\n"); return NULL; } - if (!coap_add_token(resp, request->hdr->token_length, request->hdr->token)) + if (!coap_add_token(resp, request->hdr->coap_hdr_udp_t.token_length, + request->hdr->coap_hdr_udp_t.token, coap_udp)) { debug("wellknown_response: cannot add token\n"); goto error; @@ -1276,7 +1283,7 @@ wellknown_response(coap_context_t *context, coap_pdu_t *request) offset = block.num << (block.szx + 4); if (block.szx > 6) { /* invalid, MUST lead to 4.00 Bad Request */ - resp->hdr->code = COAP_RESPONSE_CODE(400); + resp->hdr->coap_hdr_udp_t.code = COAP_RESPONSE_CODE(400); return resp; } else if (block.szx > COAP_MAX_BLOCK_SZX) @@ -1302,7 +1309,7 @@ wellknown_response(coap_context_t *context, coap_pdu_t *request) * nothing should go wrong here. */ assert(coap_encode_var_bytes(buf, COAP_MEDIATYPE_APPLICATION_LINK_FORMAT) == 1); coap_add_option(resp, COAP_OPTION_CONTENT_FORMAT, - coap_encode_var_bytes(buf, COAP_MEDIATYPE_APPLICATION_LINK_FORMAT), buf); + coap_encode_var_bytes(buf, COAP_MEDIATYPE_APPLICATION_LINK_FORMAT), buf, coap_udp); /* check if Block2 option is required even if not requested */ if (!need_block2 && (resp->max_size - (size_t) resp->length < wkc_len)) @@ -1360,13 +1367,13 @@ wellknown_response(coap_context_t *context, coap_pdu_t *request) error: /* set error code 5.03 and remove all options and data from response */ - resp->hdr->code = COAP_RESPONSE_CODE(503); - resp->length = sizeof(coap_hdr_t) + resp->hdr->token_length; + resp->hdr->coap_hdr_udp_t.code = COAP_RESPONSE_CODE(503); + resp->length = sizeof(coap_hdr_t) + resp->hdr->coap_hdr_udp_t.token_length; return resp; } #define WANT_WKC(Pdu,Key) \ - (((Pdu)->hdr->code == COAP_REQUEST_GET) && is_wkc(Key)) + (((Pdu)->hdr->coap_hdr_udp_t.code == COAP_REQUEST_GET) && is_wkc(Key)) void handle_request(coap_context_t *context, coap_queue_t *node, const char* responseData) { @@ -1389,7 +1396,7 @@ void handle_request(coap_context_t *context, coap_queue_t *node, const char* res * be the well-known URI. In that case, we generate a default * response, otherwise, we return 4.04 */ - switch (node->pdu->hdr->code) + switch (node->pdu->hdr->coap_hdr_udp_t.code) { case COAP_REQUEST_GET: @@ -1429,41 +1436,43 @@ void handle_request(coap_context_t *context, coap_queue_t *node, const char* res } /* the resource was found, check if there is a registered handler */ - if ((size_t) node->pdu->hdr->code - 1 + if ((size_t) node->pdu->hdr->coap_hdr_udp_t.code - 1 < sizeof(resource->handler) / sizeof(coap_method_handler_t)) - h = resource->handler[node->pdu->hdr->code - 1]; + h = resource->handler[node->pdu->hdr->coap_hdr_udp_t.code - 1]; if (h) { debug( "call custom handler for resource 0x%02x%02x%02x%02x\n", key[0], key[1], key[2], key[3]); response = coap_pdu_init( - node->pdu->hdr->type == COAP_MESSAGE_CON ? COAP_MESSAGE_ACK : COAP_MESSAGE_NON, - 0, node->pdu->hdr->id, COAP_MAX_PDU_SIZE); + node->pdu->hdr->coap_hdr_udp_t.type == + COAP_MESSAGE_CON ? COAP_MESSAGE_ACK : COAP_MESSAGE_NON, + 0, node->pdu->hdr->coap_hdr_udp_t.id, COAP_MAX_PDU_SIZE, coap_udp); /* Implementation detail: coap_add_token() immediately returns 0 if response == NULL */ - if (coap_add_token(response, node->pdu->hdr->token_length, node->pdu->hdr->token)) + if (coap_add_token(response, node->pdu->hdr->coap_hdr_udp_t.token_length, + node->pdu->hdr->coap_hdr_udp_t.token, coap_udp)) { str token = - { node->pdu->hdr->token_length, node->pdu->hdr->token }; + { node->pdu->hdr->coap_hdr_udp_t.token_length, node->pdu->hdr->coap_hdr_udp_t.token }; h(context, resource, &node->remote, node->pdu, &token, response); unsigned char buf[3]; - response->hdr->code = COAP_RESPONSE_CODE(205); + response->hdr->coap_hdr_udp_t.code = COAP_RESPONSE_CODE(205); coap_add_option(response, COAP_OPTION_CONTENT_TYPE, - coap_encode_var_bytes(buf, COAP_MEDIATYPE_TEXT_PLAIN), buf); - coap_add_option(response, COAP_OPTION_MAXAGE, coap_encode_var_bytes(buf, 0x2ffff), buf); + coap_encode_var_bytes(buf, COAP_MEDIATYPE_TEXT_PLAIN), buf, coap_udp); + coap_add_option(response, COAP_OPTION_MAXAGE, coap_encode_var_bytes(buf, 0x2ffff), buf, coap_udp); coap_add_data(response, strlen(responseData), (unsigned char *) responseData); - if (response->hdr->type != COAP_MESSAGE_NON - || (response->hdr->code >= 64 && !coap_is_mcast(&node->local))) + if (response->hdr->coap_hdr_udp_t.type != COAP_MESSAGE_NON + || (response->hdr->coap_hdr_udp_t.code >= 64 && !coap_is_mcast(&node->local))) { if (coap_send(context, &node->remote, response) == COAP_INVALID_TID) { - debug("cannot send response for message %d\n", node->pdu->hdr->id); + debug("cannot send response for message %d\n", node->pdu->hdr->coap_hdr_udp_t.id); } } @@ -1541,7 +1550,8 @@ handle_locally(coap_context_t *context __attribute__ ((unused)), * get token from sent and try to find a matching resource. Uh! */ - COAP_SET_STR(&token, sent->pdu->hdr->token_length, sent->pdu->hdr->token); + COAP_SET_STR(&token, sent->pdu->hdr->coap_hdr_udp_t.token_length, + sent->pdu->hdr->coap_hdr_udp_t.token); #ifndef WITH_CONTIKI #ifdef COAP_RESOURCES_NOHASH @@ -1587,28 +1597,30 @@ handle_locally(coap_context_t *context __attribute__ ((unused)), context->recvqueue = context->recvqueue->next; rcvd->next = NULL; - if (rcvd->pdu->hdr->version != COAP_DEFAULT_VERSION) + if (rcvd->pdu->hdr->coap_hdr_udp_t.version != COAP_DEFAULT_VERSION) { - debug("dropped packet with unknown version %u\n", rcvd->pdu->hdr->version); + debug("dropped packet with unknown version %u\n", rcvd->pdu->hdr->coap_hdr_udp_t.version); goto cleanup; } - switch (rcvd->pdu->hdr->type) + switch (rcvd->pdu->hdr->coap_hdr_udp_t.type) { case COAP_MESSAGE_ACK: /* find transaction in sendqueue to stop retransmission */ coap_remove_from_queue(&context->sendqueue, rcvd->id, &sent); - if (rcvd->pdu->hdr->code == 0) + if (rcvd->pdu->hdr->coap_hdr_udp_t.code == 0) goto cleanup; /* FIXME: if sent code was >= 64 the message might have been a * notification. Then, we must flag the observer to be alive * by setting obs->fail_cnt = 0. */ - if (sent && COAP_RESPONSE_CLASS(sent->pdu->hdr->code) == 2) + if (sent && COAP_RESPONSE_CLASS(sent->pdu->hdr->coap_hdr_udp_t.code) == 2) { const str token = - { sent->pdu->hdr->token_length, sent->pdu->hdr->token }; + { sent->pdu->hdr->coap_hdr_udp_t.token_length, + sent->pdu->hdr->coap_hdr_udp_t.token }; + coap_touch_observer(context, &sent->remote, &token); } break; @@ -1618,7 +1630,8 @@ handle_locally(coap_context_t *context __attribute__ ((unused)), * not only the transaction but also the subscriptions we might * have. */ - coap_log(LOG_ALERT, "got RST for message %u\n", ntohs(rcvd->pdu->hdr->id)); + coap_log(LOG_ALERT, "got RST for message %u\n", + ntohs(rcvd->pdu->hdr->coap_hdr_udp_t.id)); /* find transaction in sendqueue to stop retransmission */ coap_remove_from_queue(&context->sendqueue, rcvd->id, &sent); @@ -1661,9 +1674,9 @@ handle_locally(coap_context_t *context __attribute__ ((unused)), * registered for a request that should be handled locally. */ if (handle_locally(context, rcvd)) { - if (COAP_MESSAGE_IS_REQUEST(rcvd->pdu->hdr)) + if (COAP_MESSAGE_IS_REQUEST(rcvd->pdu->hdr->coap_hdr_udp_t)) handle_request(context, rcvd, responseData); - else if (COAP_MESSAGE_IS_RESPONSE(rcvd->pdu->hdr)) + else if (COAP_MESSAGE_IS_RESPONSE(rcvd->pdu->hdr->coap_hdr_udp_t)) handle_response(context, sent, rcvd); else { diff --git a/resource/csdk/connectivity/lib/libcoap-4.1.1/option.c b/resource/csdk/connectivity/lib/libcoap-4.1.1/option.c index 3255020..04b8dee 100644 --- a/resource/csdk/connectivity/lib/libcoap-4.1.1/option.c +++ b/resource/csdk/connectivity/lib/libcoap-4.1.1/option.c @@ -20,16 +20,26 @@ #include "debug.h" coap_opt_t * -options_start(coap_pdu_t *pdu) +options_start(coap_pdu_t *pdu, coap_transport_type transport) { - - if (pdu && pdu->hdr - && (pdu->hdr->token + pdu->hdr->token_length < (unsigned char *) pdu->hdr + pdu->length)) + if (pdu && pdu->hdr) { - - coap_opt_t *opt = pdu->hdr->token + pdu->hdr->token_length; - return (*opt == COAP_PAYLOAD_START) ? NULL : opt; - + if (coap_udp == transport && (pdu->hdr->coap_hdr_udp_t.token + + pdu->hdr->coap_hdr_udp_t.token_length + < (unsigned char *) pdu->hdr + pdu->length)) + { + coap_opt_t *opt = pdu->hdr->coap_hdr_udp_t.token + + pdu->hdr->coap_hdr_udp_t.token_length; + return (*opt == COAP_PAYLOAD_START) ? NULL : opt; + } + else if(coap_tcp == transport && (pdu->hdr->coap_hdr_tcp_t.token + + pdu->hdr->coap_hdr_tcp_t.token_length + < (unsigned char *) pdu->hdr + pdu->length)) + { + coap_opt_t *opt = pdu->hdr->coap_hdr_tcp_t.token + + pdu->hdr->coap_hdr_tcp_t.token_length; + return (*opt == COAP_PAYLOAD_START) ? NULL : opt; + } } else return NULL; @@ -121,7 +131,8 @@ size_t coap_opt_parse(const coap_opt_t *opt, size_t length, coap_option_t *resul } coap_opt_iterator_t * -coap_option_iterator_init(coap_pdu_t *pdu, coap_opt_iterator_t *oi, const coap_opt_filter_t filter) +coap_option_iterator_init(coap_pdu_t *pdu, coap_opt_iterator_t *oi, + const coap_opt_filter_t filter, coap_transport_type transport) { assert(pdu); assert(pdu->hdr); @@ -129,16 +140,49 @@ coap_option_iterator_init(coap_pdu_t *pdu, coap_opt_iterator_t *oi, const coap_o memset(oi, 0, sizeof(coap_opt_iterator_t)); - oi->next_option = (unsigned char *) pdu->hdr + sizeof(coap_hdr_t) + pdu->hdr->token_length; - if ((unsigned char *) pdu->hdr + pdu->length <= oi->next_option) + unsigned int token_length; + unsigned int headerSize; + + switch(transport) { - oi->bad = 1; - return NULL; + case coap_tcp: + case coap_tcp_8bit: + case coap_tcp_16bit: + token_length = pdu->hdr->coap_hdr_tcp_t.token_length; + headerSize = sizeof(pdu->hdr->coap_hdr_tcp_t); + break; + case coap_tcp_32bit: + token_length = pdu->hdr->coap_hdr_tcp_32bit_t.header_data[0] & 0x0f; + headerSize = sizeof(pdu->hdr->coap_hdr_tcp_32bit_t); + break; + default: + token_length = pdu->hdr->coap_hdr_udp_t.token_length; + headerSize = sizeof(pdu->hdr->coap_hdr_udp_t); + break; + } + + oi->next_option = (unsigned char *) pdu->hdr + headerSize + token_length; + + if (coap_udp == transport) + { + if ((unsigned char *) &(pdu->hdr->coap_hdr_udp_t) + pdu->length <= oi->next_option) + { + oi->bad = 1; + return NULL; + } + } + else + { + if ((unsigned char *) &(pdu->hdr->coap_hdr_tcp_t) + pdu->length <= oi->next_option) + { + oi->bad = 1; + return NULL; + } } - assert((sizeof(coap_hdr_t) + pdu->hdr->token_length) <= pdu->length); + assert((headerSize + token_length) <= pdu->length); - oi->length = pdu->length - (sizeof(coap_hdr_t) + pdu->hdr->token_length); + oi->length = pdu->length - (headerSize + token_length); if (filter) { @@ -223,7 +267,7 @@ coap_check_option(coap_pdu_t *pdu, unsigned char type, coap_opt_iterator_t *oi) coap_option_filter_clear(f); coap_option_setb(f, type); - coap_option_iterator_init(pdu, oi, f); + coap_option_iterator_init(pdu, oi, f, coap_udp); return coap_option_next(oi); } diff --git a/resource/csdk/connectivity/lib/libcoap-4.1.1/option.h b/resource/csdk/connectivity/lib/libcoap-4.1.1/option.h index 77c964c..d592447 100644 --- a/resource/csdk/connectivity/lib/libcoap-4.1.1/option.h +++ b/resource/csdk/connectivity/lib/libcoap-4.1.1/option.h @@ -70,7 +70,7 @@ size_t coap_opt_size(const coap_opt_t *opt); * @param pdu The PDU containing the options. * @return A pointer to the first option if available, or @c NULL otherwise. */ -coap_opt_t *options_start(coap_pdu_t *pdu); +coap_opt_t *options_start(coap_pdu_t *pdu, coap_transport_type transport); /** * Interprets @p opt as pointer to a CoAP option and advances to @@ -194,7 +194,7 @@ typedef struct * @return The iterator object @p oi on success, @c NULL otherwise. */ coap_opt_iterator_t *coap_option_iterator_init(coap_pdu_t *pdu, coap_opt_iterator_t *oi, - const coap_opt_filter_t filter); + const coap_opt_filter_t filter, coap_transport_type transport); /** * Updates the iterator @p oi to point to the next option. This diff --git a/resource/csdk/connectivity/lib/libcoap-4.1.1/pdu.c b/resource/csdk/connectivity/lib/libcoap-4.1.1/pdu.c index d246654..f1847d8 100644 --- a/resource/csdk/connectivity/lib/libcoap-4.1.1/pdu.c +++ b/resource/csdk/connectivity/lib/libcoap-4.1.1/pdu.c @@ -44,17 +44,25 @@ coap_pdu_resources_init() #include "mem.h" #endif /* WITH_CONTIKI */ -void coap_pdu_clear(coap_pdu_t *pdu, size_t size) +void coap_pdu_clear(coap_pdu_t *pdu, size_t size, coap_transport_type transport, unsigned int length) { assert(pdu); memset(pdu, 0, sizeof(coap_pdu_t) + size); pdu->max_size = size; pdu->hdr = (coap_hdr_t *) ((unsigned char *) pdu + sizeof(coap_pdu_t)); - pdu->hdr->version = COAP_DEFAULT_VERSION; - /* data is NULL unless explicitly set by coap_add_data() */ - pdu->length = sizeof(coap_hdr_t); + if (coap_udp == transport) + { + pdu->hdr->coap_hdr_udp_t.version = COAP_DEFAULT_VERSION; + /* data is NULL unless explicitly set by coap_add_data() */ + pdu->length = sizeof(pdu->hdr->coap_hdr_udp_t); + } + else + { + /* data is NULL unless explicitly set by coap_add_data() */ + pdu->length = length; + } } #ifdef WITH_LWIP @@ -84,16 +92,39 @@ coap_pdu_from_pbuf(struct pbuf *pbuf) #endif coap_pdu_t * -coap_pdu_init(unsigned char type, unsigned char code, unsigned short id, size_t size) +coap_pdu_init(unsigned char type, unsigned char code, unsigned short id, + size_t size, coap_transport_type transport) { coap_pdu_t *pdu; #ifdef WITH_LWIP struct pbuf *p; #endif + unsigned int length = 0; + switch(transport) + { + case coap_udp: + length = sizeof(pdu->hdr->coap_hdr_udp_t); + break; + case coap_tcp: + length = COAP_TCP_HEADER_NO_FIELD; + break; + case coap_tcp_8bit: + length = COAP_TCP_HEADER_8_BIT; + break; + case coap_tcp_16bit: + length = COAP_TCP_HEADER_16_BIT; + break; + case coap_tcp_32bit: + length = COAP_TCP_HEADER_32_BIT; + break; + default: + debug("it has wrong type\n"); + } + assert(size <= COAP_MAX_PDU_SIZE); /* Size must be large enough to fit the header. */ - if (size < sizeof(coap_hdr_t) || size > COAP_MAX_PDU_SIZE) + if (size < length || size > COAP_MAX_PDU_SIZE) return NULL; /* size must be large enough for hdr */ @@ -120,10 +151,37 @@ coap_pdu_init(unsigned char type, unsigned char code, unsigned short id, size_t #endif if (pdu) { - coap_pdu_clear(pdu, size); - pdu->hdr->id = id; - pdu->hdr->type = type; - pdu->hdr->code = code; + coap_pdu_clear(pdu, size, transport, length); + + switch(transport) + { + case coap_udp: + pdu->hdr->coap_hdr_udp_t.id = id; + pdu->hdr->coap_hdr_udp_t.type = type; + pdu->hdr->coap_hdr_udp_t.code = code; + break; + case coap_tcp: + pdu->hdr->coap_hdr_tcp_t.message_length = 0; + pdu->hdr->coap_hdr_tcp_t.code = code; + break; + case coap_tcp_8bit: + pdu->hdr->coap_hdr_tcp_8bit_t.message_length = COAP_TCP_LENGTH_FIELD_NUM_8_BIT; + pdu->hdr->coap_hdr_tcp_8bit_t.length_byte = 0; + pdu->hdr->coap_hdr_tcp_8bit_t.code = code; + break; + case coap_tcp_16bit: + pdu->hdr->coap_hdr_tcp_16bit_t.message_length = COAP_TCP_LENGTH_FIELD_NUM_16_BIT; + pdu->hdr->coap_hdr_tcp_16bit_t.length_byte = 0; + pdu->hdr->coap_hdr_tcp_16bit_t.code = code; + break; + case coap_tcp_32bit: + pdu->hdr->coap_hdr_tcp_32bit_t.header_data[0] = COAP_TCP_LENGTH_FIELD_NUM_32_BIT << 4; + pdu->hdr->coap_hdr_tcp_32bit_t.header_data[5] = code; + break; + default: + debug("it has wrong type\n"); + } + #ifdef WITH_LWIP pdu->pbuf = p; #endif @@ -132,14 +190,16 @@ coap_pdu_init(unsigned char type, unsigned char code, unsigned short id, size_t } coap_pdu_t * -coap_new_pdu() +coap_new_pdu(coap_transport_type transport) { coap_pdu_t *pdu; #ifndef WITH_CONTIKI - pdu = coap_pdu_init(0, 0, ntohs(COAP_INVALID_TID), COAP_MAX_PDU_SIZE); + pdu = coap_pdu_init(0, 0, + ntohs(COAP_INVALID_TID), + COAP_MAX_PDU_SIZE, transport); #else /* WITH_CONTIKI */ - pdu = coap_pdu_init(0, 0, uip_ntohs(COAP_INVALID_TID), COAP_MAX_PDU_SIZE); + pdu = coap_pdu_init(0, 0, uip_ntohs(COAP_INVALID_TID), COAP_MAX_PDU_SIZE, transport); #endif /* WITH_CONTIKI */ #ifndef NDEBUG @@ -163,26 +223,256 @@ void coap_delete_pdu(coap_pdu_t *pdu) #endif } -int coap_add_token(coap_pdu_t *pdu, size_t len, const unsigned char *data) +coap_transport_type coap_get_tcp_header_type_from_size(unsigned int size) +{ + if (COAP_TCP_LENGTH_LIMIT_8_BIT < size && COAP_TCP_LENGTH_LIMIT_16_BIT >= size) + { + return coap_tcp_8bit; + } + else if (COAP_TCP_LENGTH_LIMIT_16_BIT < size && COAP_TCP_LENGTH_LIMIT_32_BIT >= size) + { + return coap_tcp_16bit; + } + else if (COAP_TCP_LENGTH_LIMIT_32_BIT < size) + { + return coap_tcp_32bit; + } + else + { + return coap_tcp; + } +} + +coap_transport_type coap_get_tcp_header_type_from_initbyte(unsigned int length) +{ + coap_transport_type type; + switch(length) + { + case COAP_TCP_LENGTH_FIELD_NUM_8_BIT: + type = coap_tcp_8bit; + break; + case COAP_TCP_LENGTH_FIELD_NUM_16_BIT: + type = coap_tcp_16bit; + break; + case COAP_TCP_LENGTH_FIELD_NUM_32_BIT: + type = coap_tcp_32bit; + break; + default: + type = coap_tcp; + } + return type; +} + +void coap_add_length(const coap_pdu_t *pdu, coap_transport_type transport, unsigned int length) +{ + assert(pdu); + + switch(transport) + { + case coap_tcp_8bit: + if (length > COAP_TCP_LENGTH_FIELD_8_BIT) + { + pdu->hdr->coap_hdr_tcp_8bit_t.length_byte = + length - COAP_TCP_LENGTH_FIELD_8_BIT; + } + break; + case coap_tcp_16bit: + if (length > COAP_TCP_LENGTH_FIELD_16_BIT) + { + pdu->hdr->coap_hdr_tcp_16bit_t.length_byte = + length - COAP_TCP_LENGTH_FIELD_16_BIT; + } + break; + case coap_tcp_32bit: + if (length > COAP_TCP_LENGTH_FIELD_32_BIT) + { + unsigned int total_length = length - COAP_TCP_LENGTH_FIELD_32_BIT; + pdu->hdr->coap_hdr_tcp_32bit_t.header_data[1] = total_length >> 24; + pdu->hdr->coap_hdr_tcp_32bit_t.header_data[2] = (total_length >> 16) & 0x00ff; + pdu->hdr->coap_hdr_tcp_32bit_t.header_data[3] = (total_length >> 8) & 0x0000ff; + pdu->hdr->coap_hdr_tcp_32bit_t.header_data[4] = total_length & 0x000000ff; + } + break; + default: + debug("it has wrong type\n"); + } +} + +unsigned int coap_get_length(const coap_pdu_t *pdu, coap_transport_type transport) +{ + assert(pdu); + + unsigned int length = 0; + unsigned int length_field_data = 0; + switch(transport) + { + case coap_tcp_8bit: + length = pdu->hdr->coap_hdr_tcp_8bit_t.length_byte + COAP_TCP_LENGTH_FIELD_8_BIT; + break; + case coap_tcp_16bit: + length_field_data = + ((unsigned char *)(&pdu->hdr->coap_hdr_tcp_16bit_t))[2] << 8 | + ((unsigned char *)(&pdu->hdr->coap_hdr_tcp_16bit_t))[1]; + length = length_field_data + COAP_TCP_LENGTH_FIELD_16_BIT; + break; + case coap_tcp_32bit: + length_field_data = + pdu->hdr->coap_hdr_tcp_32bit_t.header_data[1] << 24 | + pdu->hdr->coap_hdr_tcp_32bit_t.header_data[2] << 16 | + pdu->hdr->coap_hdr_tcp_32bit_t.header_data[3] << 8 | + pdu->hdr->coap_hdr_tcp_32bit_t.header_data[4]; + length = length_field_data + COAP_TCP_LENGTH_FIELD_32_BIT; + break; + default: + debug("it has wrong type\n"); + } + + return length; +} + +void coap_add_code(const coap_pdu_t *pdu, coap_transport_type transport, unsigned int code) +{ + assert(pdu); + + switch(transport) + { + case coap_udp: + pdu->hdr->coap_hdr_udp_t.code = COAP_RESPONSE_CODE(code); + break; + case coap_tcp: + pdu->hdr->coap_hdr_tcp_t.code = COAP_RESPONSE_CODE(code); + break; + case coap_tcp_8bit: + pdu->hdr->coap_hdr_tcp_8bit_t.code = COAP_RESPONSE_CODE(code); + break; + case coap_tcp_16bit: + pdu->hdr->coap_hdr_tcp_16bit_t.code = COAP_RESPONSE_CODE(code); + break; + case coap_tcp_32bit: + pdu->hdr->coap_hdr_tcp_32bit_t.header_data[5] = COAP_RESPONSE_CODE(code); + break; + default: + debug("it has wrong type\n"); + } +} + +unsigned int coap_get_code(const coap_pdu_t *pdu, coap_transport_type transport) +{ + assert(pdu); + + unsigned int code = 0; + switch(transport) + { + case coap_udp: + code = pdu->hdr->coap_hdr_udp_t.code; + break; + case coap_tcp: + code = pdu->hdr->coap_hdr_tcp_t.code; + break; + case coap_tcp_8bit: + code = pdu->hdr->coap_hdr_tcp_8bit_t.code; + break; + case coap_tcp_16bit: + code = pdu->hdr->coap_hdr_tcp_16bit_t.code; + break; + case coap_tcp_32bit: + code = pdu->hdr->coap_hdr_tcp_32bit_t.header_data[5]; + break; + default: + debug("it has wrong type\n"); + } + return code; +} + +int coap_add_token(coap_pdu_t *pdu, size_t len, const unsigned char *data, + coap_transport_type transport) { const size_t HEADERLENGTH = len + 4; /* must allow for pdu == NULL as callers may rely on this */ if (!pdu || len > 8 || pdu->max_size < HEADERLENGTH) return 0; - pdu->hdr->token_length = len; + unsigned char* token = NULL; + switch(transport) + { + case coap_udp: + pdu->hdr->coap_hdr_udp_t.token_length = len; + token = pdu->hdr->coap_hdr_udp_t.token; + pdu->length = HEADERLENGTH; + break; + case coap_tcp: + pdu->hdr->coap_hdr_tcp_t.token_length = len; + token = pdu->hdr->coap_hdr_tcp_t.token; + pdu->length = HEADERLENGTH; + break; + case coap_tcp_8bit: + pdu->hdr->coap_hdr_tcp_8bit_t.token_length = len; + token = pdu->hdr->coap_hdr_tcp_8bit_t.token; + pdu->length = HEADERLENGTH; + break; + case coap_tcp_16bit: + pdu->hdr->coap_hdr_tcp_16bit_t.token_length = len; + token = pdu->hdr->coap_hdr_tcp_16bit_t.token; + pdu->length = HEADERLENGTH; + break; + case coap_tcp_32bit: + pdu->hdr->coap_hdr_tcp_32bit_t.header_data[0] = + pdu->hdr->coap_hdr_tcp_32bit_t.header_data[0] | len; + token = pdu->hdr->coap_hdr_tcp_32bit_t.token; + pdu->length = len + COAP_TCP_HEADER_32_BIT; + break; + default: + debug("it has wrong type\n"); + } + if (len) - memcpy(pdu->hdr->token, data, len); + { + memcpy(token, data, len); + } + pdu->max_delta = 0; - pdu->length = HEADERLENGTH; pdu->data = NULL; return 1; } +void coap_get_token(const coap_hdr_t *pdu_hdr, coap_transport_type transport, + unsigned char **token, unsigned int *token_length) +{ + assert(pdu); + assert(token); + assert(token_length); + + switch(transport) + { + case coap_udp: + *token_length = pdu_hdr->coap_hdr_udp_t.token_length; + *token = (unsigned char *)pdu_hdr->coap_hdr_udp_t.token; + break; + case coap_tcp: + *token_length = pdu_hdr->coap_hdr_tcp_t.token_length; + *token = (unsigned char *)pdu_hdr->coap_hdr_tcp_t.token; + break; + case coap_tcp_8bit: + *token_length = pdu_hdr->coap_hdr_tcp_8bit_t.token_length; + *token = (unsigned char *)pdu_hdr->coap_hdr_tcp_8bit_t.token; + break; + case coap_tcp_16bit: + *token_length = pdu_hdr->coap_hdr_tcp_16bit_t.token_length; + *token = (unsigned char *)pdu_hdr->coap_hdr_tcp_16bit_t.token; + break; + case coap_tcp_32bit: + *token_length = (pdu_hdr->coap_hdr_tcp_32bit_t.header_data[0]) & 0x0f; + *token = (unsigned char *)pdu_hdr->coap_hdr_tcp_32bit_t.token; + break; + default: + debug("it has wrong type\n"); + } +} + /** @FIXME de-duplicate code with coap_add_option_later */ size_t coap_add_option(coap_pdu_t *pdu, unsigned short type, unsigned int len, - const unsigned char *data) + const unsigned char *data, coap_transport_type transport) { size_t optsize; coap_opt_t *opt; @@ -196,7 +486,24 @@ size_t coap_add_option(coap_pdu_t *pdu, unsigned short type, unsigned int len, return 0; } - opt = (unsigned char *) pdu->hdr + pdu->length; + switch(transport) + { + case coap_tcp: + opt = (unsigned char *) &(pdu->hdr->coap_hdr_tcp_t) + pdu->length; + break; + case coap_tcp_8bit: + opt = (unsigned char *) &(pdu->hdr->coap_hdr_tcp_8bit_t) + pdu->length; + break; + case coap_tcp_16bit: + opt = (unsigned char *) &(pdu->hdr->coap_hdr_tcp_16bit_t) + pdu->length; + break; + case coap_tcp_32bit: + opt = (unsigned char *) &(pdu->hdr->coap_hdr_tcp_32bit_t) + pdu->length; + break; + default: + opt = (unsigned char *) &(pdu->hdr->coap_hdr_udp_t) + pdu->length; + break; + } /* encode option and check length */ optsize = coap_opt_encode(opt, pdu->max_size - pdu->length, type - pdu->max_delta, data, len); @@ -368,10 +675,9 @@ static size_t next_option_safe(coap_opt_t **optp, size_t *length, coap_option_t* return optsize; } -int coap_pdu_parse(unsigned char *data, size_t length, coap_pdu_t *pdu) +int coap_pdu_parse(unsigned char *data, size_t length, coap_pdu_t *pdu, + coap_transport_type transport) { - coap_opt_t *opt; - assert(data); assert(pdu); @@ -379,58 +685,133 @@ int coap_pdu_parse(unsigned char *data, size_t length, coap_pdu_t *pdu) { debug("insufficient space to store parsed PDU\n"); printf("[COAP] insufficient space to store parsed PDU\n"); - return 0; + return -1; } - if (length < sizeof(coap_hdr_t)) + unsigned int headerSize = 0; + switch(transport) + { + case coap_tcp: + headerSize = COAP_TCP_HEADER_NO_FIELD; + break; + case coap_tcp_8bit: + headerSize = COAP_TCP_HEADER_8_BIT; + break; + case coap_tcp_16bit: + headerSize = COAP_TCP_HEADER_16_BIT; + break; + case coap_tcp_32bit: + headerSize = COAP_TCP_HEADER_32_BIT; + break; + default: + headerSize = sizeof(pdu->hdr->coap_hdr_udp_t); + break; + } + + if (length < headerSize) { debug("discarded invalid PDU\n"); } - pdu->hdr->version = data[0] >> 6; - pdu->hdr->type = (data[0] >> 4) & 0x03; - pdu->hdr->token_length = data[0] & 0x0f; - pdu->hdr->code = data[1]; - /* - printf("[COAP] pdu - version : %d\n", pdu->hdr->version); - printf("[COAP] pdu - type : %d\n", pdu->hdr->type); - printf("[COAP] pdu - token_length : %d\n", pdu->hdr->token_length); - printf("[COAP] pdu - code : %d\n", pdu->hdr->code); - */ - pdu->data = NULL; + coap_opt_t *opt = NULL; + unsigned int tokenLength = 0; + switch(transport) + { + case coap_tcp: + pdu->hdr->coap_hdr_tcp_t.message_length = data[0] >> 4; + pdu->hdr->coap_hdr_tcp_t.token_length = data[0] & 0x0f; + pdu->hdr->coap_hdr_tcp_t.code = data[1]; + tokenLength = pdu->hdr->coap_hdr_tcp_t.token_length; + opt = (unsigned char *) (&(pdu->hdr->coap_hdr_tcp_t) + 1) + tokenLength; + break; + case coap_tcp_8bit: + pdu->hdr->coap_hdr_tcp_8bit_t.message_length = data[0] >> 4; + pdu->hdr->coap_hdr_tcp_8bit_t.token_length = data[0] & 0x0f; + pdu->hdr->coap_hdr_tcp_8bit_t.length_byte = data[1]; + pdu->hdr->coap_hdr_tcp_8bit_t.code = data[2]; + tokenLength = pdu->hdr->coap_hdr_tcp_8bit_t.token_length; + opt = (unsigned char *) (&(pdu->hdr->coap_hdr_tcp_8bit_t) + 1) + tokenLength; + break; + case coap_tcp_16bit: + pdu->hdr->coap_hdr_tcp_16bit_t.message_length = data[0] >> 4; + pdu->hdr->coap_hdr_tcp_16bit_t.token_length = data[0] & 0x0f; + pdu->hdr->coap_hdr_tcp_16bit_t.length_byte = (data[2] << 8 | data[1]); + pdu->hdr->coap_hdr_tcp_16bit_t.code = data[3]; + tokenLength = pdu->hdr->coap_hdr_tcp_16bit_t.token_length; + opt = (unsigned char *) (&(pdu->hdr->coap_hdr_tcp_16bit_t) + 1) + tokenLength; + break; + case coap_tcp_32bit: + for (size_t i = 0 ; i < headerSize ; i++) + { + pdu->hdr->coap_hdr_tcp_32bit_t.header_data[i] = data[i]; + } + + tokenLength = data[0] & 0x0f; + opt = ((unsigned char *) &(pdu->hdr->coap_hdr_tcp_32bit_t)) + + headerSize + tokenLength; + break; + default: + debug("it has wrong type\n"); + } + pdu->length = length; - /* sanity checks */ - if (pdu->hdr->code == 0) + if (coap_udp == transport) { - if (length != sizeof(coap_hdr_t) || pdu->hdr->token_length) + pdu->hdr->coap_hdr_udp_t.version = data[0] >> 6; + pdu->hdr->coap_hdr_udp_t.type = (data[0] >> 4) & 0x03; + pdu->hdr->coap_hdr_udp_t.token_length = data[0] & 0x0f; + pdu->hdr->coap_hdr_udp_t.code = data[1]; + pdu->data = NULL; + + tokenLength = pdu->hdr->coap_hdr_udp_t.token_length; + + /* sanity checks */ + if (pdu->hdr->coap_hdr_udp_t.code == 0) { - debug("coap_pdu_parse: empty message is not empty\n"); + if (length != headerSize || tokenLength) + { + debug("coap_pdu_parse: empty message is not empty\n"); + goto discard; + } + } + + if (length < headerSize + tokenLength || tokenLength > 8) + { + debug("coap_pdu_parse: invalid Token\n"); goto discard; } - } - if (length < sizeof(coap_hdr_t) + pdu->hdr->token_length || pdu->hdr->token_length > 8) - { - debug("coap_pdu_parse: invalid Token\n"); - goto discard; - } + memcpy(&pdu->hdr->coap_hdr_udp_t.id, data + 2, 2); - /* Copy message id in network byte order, so we can easily write the - * response back to the network. */ - memcpy(&pdu->hdr->id, data + 2, 2); + /* Finally calculate beginning of data block and thereby check integrity + * of the PDU structure. */ - //printf("[COAP] pdu - id : %d\n", pdu->hdr->id); + /* append data (including the Token) to pdu structure */ + memcpy(&(pdu->hdr->coap_hdr_udp_t) + 1, data + headerSize, length - headerSize); - /* append data (including the Token) to pdu structure */ - memcpy(pdu->hdr + 1, data + sizeof(coap_hdr_t), length - sizeof(coap_hdr_t)); - pdu->length = length; + /* skip header + token */ + length -= (tokenLength + headerSize); + opt = (unsigned char *) (&(pdu->hdr->coap_hdr_udp_t) + 1) + tokenLength; + } + else // common for tcp header setting + { + pdu->data = NULL; + + if (length < headerSize + tokenLength || tokenLength > 8) + { + debug("coap_pdu_parse: invalid Token\n"); + goto discard; + } + /* Finally calculate beginning of data block and thereby check integrity + * of the PDU structure. */ - /* Finally calculate beginning of data block and thereby check integrity - * of the PDU structure. */ + /* append data (including the Token) to pdu structure */ + memcpy(((unsigned char *) pdu->hdr) + headerSize, + data + headerSize, length - headerSize); - /* skip header + token */ - length -= (pdu->hdr->token_length + sizeof(coap_hdr_t)); - opt = (unsigned char *) (pdu->hdr + 1) + pdu->hdr->token_length; + /* skip header + token */ + length -= (tokenLength + headerSize); + } while (length && *opt != COAP_PAYLOAD_START) { @@ -457,7 +838,8 @@ int coap_pdu_parse(unsigned char *data, size_t length, coap_pdu_t *pdu) } debug( - "set data to %p (pdu ends at %p)\n", (unsigned char *)opt, (unsigned char *)pdu->hdr + pdu->length); + "set data to %p (pdu ends at %p)\n", (unsigned char *)opt, + (unsigned char *)pdu->hdr + pdu->length); pdu->data = (unsigned char *) opt; //printf("[COAP] pdu - data : %s\n", pdu->data); } diff --git a/resource/csdk/connectivity/lib/libcoap-4.1.1/pdu.h b/resource/csdk/connectivity/lib/libcoap-4.1.1/pdu.h index 792ee92..bb94e4d 100644 --- a/resource/csdk/connectivity/lib/libcoap-4.1.1/pdu.h +++ b/resource/csdk/connectivity/lib/libcoap-4.1.1/pdu.h @@ -160,32 +160,131 @@ char *coap_response_phrase(unsigned char code); typedef int coap_tid_t; #define COAP_INVALID_TID -1 +#define COAP_TCP_HEADER_NO_FIELD 2 +#define COAP_TCP_HEADER_8_BIT 3 +#define COAP_TCP_HEADER_16_BIT 4 +#define COAP_TCP_HEADER_32_BIT 6 + +#define COAP_TCP_LENGTH_FIELD_8_BIT 13 +#define COAP_TCP_LENGTH_FIELD_16_BIT 269 +#define COAP_TCP_LENGTH_FIELD_32_BIT 65805 + +#define COAP_TCP_LENGTH_LIMIT_8_BIT 13 +#define COAP_TCP_LENGTH_LIMIT_16_BIT 256 +#define COAP_TCP_LENGTH_LIMIT_32_BIT 65535 + +#define COAP_TCP_LENGTH_FIELD_NUM_8_BIT 13 +#define COAP_TCP_LENGTH_FIELD_NUM_16_BIT 14 +#define COAP_TCP_LENGTH_FIELD_NUM_32_BIT 15 + +typedef enum +{ + coap_udp = 0, + coap_tcp, + coap_tcp_8bit, + coap_tcp_16bit, + coap_tcp_32bit +} coap_transport_type; + #ifdef WORDS_BIGENDIAN -typedef struct +typedef union { - unsigned int version:2; /* protocol version */ - unsigned int type:2; /* type flag */ - unsigned int token_length:4; /* length of Token */ - unsigned int code:8; /* request method (value 1--10) or response code (value 40-255) */ - unsigned short id; /* message id */ - unsigned char token[]; /* the actual token, if any */ -}coap_hdr_t; + typedef struct + { + unsigned int version:2; /* protocol version */ + unsigned int type:2; /* type flag */ + unsigned int token_length:4; /* length of Token */ + unsigned int code:8; /* request method (value 1--10) or response code (value 40-255) */ + unsigned short id; /* message id */ + unsigned char token[]; /* the actual token, if any */ + } coap_hdr_udp_t; + + + struct + { + unsigned int message_length :4; /* length of message */ + unsigned int token_length :4; /* length of Token */ + unsigned int code :8; /* request method (value 1--10) or response code (value 40-255) */ + unsigned char token[]; /* the actual token, if any */ + } coap_hdr_tcp_t; + + struct + { + unsigned int message_length :4; /* length of message */ + unsigned int token_length :4; /* length of Token */ + unsigned int length_byte :8; /* extend length of message */ + unsigned int code :8; /* request method (value 1--10) or response code (value 40-255) */ + unsigned char token[]; /* the actual token, if any */ + } coap_hdr_tcp_8bit_t; + + struct + { + unsigned int message_length :4; /* length of message */ + unsigned int token_length :4; /* length of Token */ + unsigned short length_byte :16; /* extend length of message */ + unsigned int code :8; /* request method (value 1--10) or response code (value 40-255) */ + unsigned char token[]; /* the actual token, if any */ + } coap_hdr_tcp_16bit_t; + + struct + { + unsigned char header_data[6]; + unsigned char token[]; /* the actual token, if any */ + } coap_hdr_tcp_32bit_t; + +} coap_hdr_t; #else -typedef struct +typedef union { - unsigned int token_length :4; /* length of Token */ - unsigned int type :2; /* type flag */ - unsigned int version :2; /* protocol version */ - unsigned int code :8; /* request method (value 1--10) or response code (value 40-255) */ - unsigned short id; /* transaction id (network byte order!) */ - unsigned char token[]; /* the actual token, if any */ + struct + { + unsigned int token_length :4; /* length of Token */ + unsigned int type :2; /* type flag */ + unsigned int version :2; /* protocol version */ + unsigned int code :8; /* request method (value 1--10) or response code (value 40-255) */ + unsigned short id; /* transaction id (network byte order!) */ + unsigned char token[]; /* the actual token, if any */ + } coap_hdr_udp_t; + + struct + { + unsigned int token_length :4; /* length of Token */ + unsigned int message_length :4; /* length of message */ + unsigned int code :8; /* request method (value 1--10) or response code (value 40-255) */ + unsigned char token[]; /* the actual token, if any */ + } coap_hdr_tcp_t; + + struct + { + unsigned int token_length :4; /* length of Token */ + unsigned int message_length :4; /* length of message */ + unsigned int length_byte :8; /* extend length of message */ + unsigned int code :8; /* request method (value 1--10) or response code (value 40-255) */ + unsigned char token[]; /* the actual token, if any */ + } coap_hdr_tcp_8bit_t; + + struct + { + unsigned int token_length :4; /* length of Token */ + unsigned int message_length :4; /* length of message */ + unsigned int length_byte :16; /* extend length of message */ + unsigned int code :8; /* request method (value 1--10) or response code (value 40-255) */ + unsigned char token[]; /* the actual token, if any */ + } coap_hdr_tcp_16bit_t; + + struct + { + unsigned char header_data[6]; /* coap header which 32bit payload length*/ + unsigned char token[]; /* the actual token, if any */ + } coap_hdr_tcp_32bit_t; + } coap_hdr_t; #endif -#define COAP_MESSAGE_IS_EMPTY(MSG) ((MSG)->code == 0) +#define COAP_MESSAGE_IS_EMPTY(MSG) ((MSG).code == 0) #define COAP_MESSAGE_IS_REQUEST(MSG) (!COAP_MESSAGE_IS_EMPTY(MSG) \ - && ((MSG)->code < 32)) -#define COAP_MESSAGE_IS_RESPONSE(MSG) ((MSG)->code >= 64 && (MSG)->code <= 191) + && ((MSG).code < 32)) +#define COAP_MESSAGE_IS_RESPONSE(MSG) ((MSG).code >= 64 && (MSG).code <= 191) #define COAP_OPT_LONG 0x0F /* OC == 0b1111 indicates that the option list in a * CoAP message is limited by 0b11110000 marker */ @@ -262,11 +361,13 @@ coap_pdu_t * coap_pdu_from_pbuf(struct pbuf *pbuf); * @param code The message code. * @param id The message id to set or COAP_INVALID_TID if unknown. * @param size The number of bytes to allocate for the actual message. + * @param transport The transport type. * * @return A pointer to the new PDU object or @c NULL on error. */ coap_pdu_t * -coap_pdu_init(unsigned char type, unsigned char code, unsigned short id, size_t size); +coap_pdu_init(unsigned char type, unsigned char code, unsigned short id, + size_t size, coap_transport_type transport); /** * Clears any contents from @p pdu and resets @c version field, @c @@ -274,7 +375,8 @@ coap_pdu_init(unsigned char type, unsigned char code, unsigned short id, size_t * other field is set to @c 0. Note that @p pdu must be a valid * pointer to a coap_pdu_t object created e.g. by coap_pdu_init(). */ -void coap_pdu_clear(coap_pdu_t *pdu, size_t size); +void coap_pdu_clear(coap_pdu_t *pdu, size_t size, coap_transport_type transport, + unsigned int length); /** * Creates a new CoAP PDU. The object is created on the heap and must be released @@ -283,7 +385,7 @@ void coap_pdu_clear(coap_pdu_t *pdu, size_t size); * @deprecated This function allocates the maximum storage for each * PDU. Use coap_pdu_init() instead. */ -coap_pdu_t *coap_new_pdu(); +coap_pdu_t *coap_new_pdu(coap_transport_type transport); void coap_delete_pdu(coap_pdu_t *); @@ -297,23 +399,91 @@ void coap_delete_pdu(coap_pdu_t *); * @param result The PDU structure to fill. Note that the structure must * provide space for at least @p length bytes to hold the * entire CoAP PDU. + * @param transport The transport type. * @return A value greater than zero on success or @c 0 on error. */ -int coap_pdu_parse(unsigned char *data, size_t length, coap_pdu_t *result); +int coap_pdu_parse(unsigned char *data, size_t length, coap_pdu_t *pdu, + coap_transport_type transport); + +/** + * Get transport type of coap header for coap over tcp through payload size. + * + * @param size payload size of pdu. + * @return The transport type. + */ +coap_transport_type coap_get_tcp_header_type_from_size(unsigned int size); + +/** + * Get transport type of coap header for coap over tcp through init-byte. + * + * @param legnth length value of init byte. +* @return The transport type. + */ +coap_transport_type coap_get_tcp_header_type_from_initbyte(unsigned int length); /** + * Add length value in field of coap header for coap over tcp. + * + * @param pdu The pdu pointer. + * @param transport The transport type. + * @param length length value of init byte. + */ +void coap_add_length(const coap_pdu_t *pdu, coap_transport_type transport, + unsigned int length); + +/** + * Get length value of coap header for coap over tcp. + * + * @param pdu The pdu pointer. + * @param transport The transport type. + * @return length value of init byte. + */ +unsigned int coap_get_length(const coap_pdu_t *pdu, coap_transport_type transport); + +/** + * Add code in coap header. + * + * @param pdu The pdu pointer. + * @param transport The transport type. + * @param code The message code. + */ +void coap_add_code(const coap_pdu_t *pdu, coap_transport_type transport, + unsigned int code); + +/** + * Get message code from coap header + * + * @param pdu The pdu pointer. + * @param transport The transport type. + * @return The message code. + */ +unsigned int coap_get_code(const coap_pdu_t *pdu, coap_transport_type transport); +/** * Adds token of length @p len to @p pdu. Adding the token destroys * any following contents of the pdu. Hence options and data must be * added after coap_add_token() has been called. In @p pdu, length is * set to @p len + @c 4, and max_delta is set to @c 0. This funtion * returns @c 0 on error or a value greater than zero on success. * - * @param pdu The PDU where the token is to be added. + * @param pdu The pdu pointer. * @param len The length of the new token. * @param data The token to add. + * @param transport The transport type. * @return A value greater than zero on success, or @c 0 on error. */ -int coap_add_token(coap_pdu_t *pdu, size_t len, const unsigned char *data); +int coap_add_token(coap_pdu_t *pdu, size_t len, const unsigned char *data, + coap_transport_type transport); + +/** + * Get token from coap header base on transport type + * + * @param pdu_hdr The header pointer of PDU. + * @param transport The transport type. + * @param token out parameter to get token. + * @param token_length out parameter to get token length. + */ +void coap_get_token(const coap_hdr_t *pdu_hdr, coap_transport_type transport, + unsigned char **token, unsigned int *token_length); /** * Adds option of given type to pdu that is passed as first @@ -324,7 +494,7 @@ int coap_add_token(coap_pdu_t *pdu, size_t len, const unsigned char *data); * This function returns the number of bytes written or @c 0 on error. */ size_t coap_add_option(coap_pdu_t *pdu, unsigned short type, unsigned int len, - const unsigned char *data); + const unsigned char *data, coap_transport_type transport); /** * Adds option of given type to pdu that is passed as first diff --git a/resource/csdk/connectivity/lib/libcoap-4.1.1/resource.c b/resource/csdk/connectivity/lib/libcoap-4.1.1/resource.c index 8c3a3ec..26c2f1b 100644 --- a/resource/csdk/connectivity/lib/libcoap-4.1.1/resource.c +++ b/resource/csdk/connectivity/lib/libcoap-4.1.1/resource.c @@ -469,7 +469,7 @@ void coap_hash_request_uri(const coap_pdu_t *request, coap_key_t key) coap_option_filter_clear(filter); coap_option_setb(filter, COAP_OPTION_URI_PATH); - coap_option_iterator_init((coap_pdu_t *) request, &opt_iter, filter); + coap_option_iterator_init((coap_pdu_t *) request, &opt_iter, filter, coap_udp); while ((option = coap_option_next(&opt_iter))) coap_hash(COAP_OPT_VALUE(option), COAP_OPT_LENGTH(option), key); } @@ -757,13 +757,14 @@ static void coap_notify_observers(coap_context_t *context, coap_resource_t *r) obs; obs = (coap_subscription_t *) list_item_next((void *) obs)) { if (r->dirty == 0 && obs->dirty == 0) - /* running this resource due to partiallydirty, but this observation's notification was already enqueued */ + /* running this resource due to partiallydirty, + * but this observation's notification was already enqueued */ continue; coap_tid_t tid = COAP_INVALID_TID; obs->dirty = 0; /* initialize response */ - response = coap_pdu_init(COAP_MESSAGE_CON, 0, 0, COAP_MAX_PDU_SIZE); + response = coap_pdu_init(COAP_MESSAGE_CON, 0, 0, COAP_MAX_PDU_SIZE, coap_udp); if (!response) { obs->dirty = 1; @@ -772,7 +773,7 @@ static void coap_notify_observers(coap_context_t *context, coap_resource_t *r) continue; } - if (!coap_add_token(response, obs->token_length, obs->token)) + if (!coap_add_token(response, obs->token_length, obs->token, coap_udp)) { obs->dirty = 1; r->partiallydirty = 1; @@ -784,19 +785,19 @@ static void coap_notify_observers(coap_context_t *context, coap_resource_t *r) token.length = obs->token_length; token.s = obs->token; - response->hdr->id = coap_new_message_id(context); + response->hdr->coap_hdr_udp_t.id = coap_new_message_id(context); if (obs->non && obs->non_cnt < COAP_OBS_MAX_NON) { - response->hdr->type = COAP_MESSAGE_NON; + response->hdr->coap_hdr_udp_t.type = COAP_MESSAGE_NON; } else { - response->hdr->type = COAP_MESSAGE_CON; + response->hdr->coap_hdr_udp_t.type = COAP_MESSAGE_CON; } /* fill with observer-specific data */ h(context, r, &obs->subscriber, NULL, &token, response); - if (response->hdr->type == COAP_MESSAGE_CON) + if (response->hdr->coap_hdr_udp_t.type == COAP_MESSAGE_CON) { tid = coap_send_confirmed(context, &obs->subscriber, response); obs->non_cnt = 0; @@ -807,7 +808,7 @@ static void coap_notify_observers(coap_context_t *context, coap_resource_t *r) obs->non_cnt++; } - if (COAP_INVALID_TID == tid || response->hdr->type != COAP_MESSAGE_CON) + if (COAP_INVALID_TID == tid || response->hdr->coap_hdr_udp_t.type != COAP_MESSAGE_CON) coap_delete_pdu(response); if (COAP_INVALID_TID == tid) { diff --git a/resource/csdk/connectivity/src/adapter_util/caadapterutils.c b/resource/csdk/connectivity/src/adapter_util/caadapterutils.c index 56cbe70..4d8e442 100644 --- a/resource/csdk/connectivity/src/adapter_util/caadapterutils.c +++ b/resource/csdk/connectivity/src/adapter_util/caadapterutils.c @@ -52,20 +52,6 @@ static JavaVM *g_jvm = NULL; static jobject g_Context = NULL; #endif -void CALogPDUData(coap_pdu_t *pdu) -{ - VERIFY_NON_NULL_VOID(pdu, CA_ADAPTER_UTILS_TAG, "pdu"); - OIC_LOG_V(DEBUG, CA_ADAPTER_UTILS_TAG, "PDU Maker - payload : %s", pdu->data); - - OIC_LOG_V(DEBUG, CA_ADAPTER_UTILS_TAG, "PDU Maker - type : %d", pdu->hdr->type); - - OIC_LOG_V(DEBUG, CA_ADAPTER_UTILS_TAG, "PDU Maker - code : %d", pdu->hdr->code); - - OIC_LOG_V(DEBUG, CA_ADAPTER_UTILS_TAG, "PDU Maker - id : %d", pdu->hdr->id); - - OIC_LOG_V(DEBUG, CA_ADAPTER_UTILS_TAG, "PDU Maker - token : %s", pdu->hdr->token); -} - #ifdef WITH_ARDUINO CAResult_t CAParseIPv4AddressInternal(const char *ipAddrStr, uint8_t *ipAddr, size_t ipAddrLen, uint16_t *port) diff --git a/resource/csdk/connectivity/src/cablockwisetransfer.c b/resource/csdk/connectivity/src/cablockwisetransfer.c index 80cd517..8a695d0 100644 --- a/resource/csdk/connectivity/src/cablockwisetransfer.c +++ b/resource/csdk/connectivity/src/cablockwisetransfer.c @@ -259,7 +259,7 @@ CAResult_t CAReceiveBlockWiseData(coap_pdu_t *pdu, const CAEndpoint_t *endpoint, VERIFY_NON_NULL(receivedData, TAG, "receivedData"); // check if received message type is CA_MSG_RESET - if (CA_EMPTY == pdu->hdr->code) + if (CA_EMPTY == pdu->hdr->coap_hdr_udp_t.code) { OIC_LOG(DEBUG, TAG, "code is CA_EMPTY.."); @@ -317,12 +317,12 @@ CAResult_t CAReceiveBlockWiseData(coap_pdu_t *pdu, const CAEndpoint_t *endpoint, // check if there is error code if (!isBlock1 && !isBlock2) { - uint32_t code = CA_RESPONSE_CODE(pdu->hdr->code); + uint32_t code = CA_RESPONSE_CODE(pdu->hdr->coap_hdr_udp_t.code); if (CA_REQUEST_ENTITY_INCOMPLETE == code) { CABlockDataID_t* blockDataID = CACreateBlockDatablockId( - (CAToken_t)pdu->hdr->token, - pdu->hdr->token_length, + (CAToken_t)pdu->hdr->coap_hdr_udp_t.token, + pdu->hdr->coap_hdr_udp_t.token_length, endpoint->port); if(NULL == blockDataID || NULL == blockDataID->id || blockDataID->idLength < 1) @@ -438,12 +438,12 @@ CAResult_t CAProcessNextStep(const coap_pdu_t *pdu, const CAData_t *receivedData if (data->requestInfo) { - data->requestInfo->info.messageId = pdu->hdr->id; + data->requestInfo->info.messageId = pdu->hdr->coap_hdr_udp_t.id; } if (data->responseInfo) { - data->responseInfo->info.messageId = pdu->hdr->id; + data->responseInfo->info.messageId = pdu->hdr->coap_hdr_udp_t.id; } res = CAAddSendThreadQueue(data, blockID); @@ -494,7 +494,7 @@ CAResult_t CAProcessNextStep(const coap_pdu_t *pdu, const CAData_t *receivedData return res; } - if (CA_MSG_NONCONFIRM == pdu->hdr->type) + if (CA_MSG_NONCONFIRM == pdu->hdr->coap_hdr_udp_t.type) { // remove data from list res = CARemoveBlockDataFromList(blockID); @@ -507,7 +507,7 @@ CAResult_t CAProcessNextStep(const coap_pdu_t *pdu, const CAData_t *receivedData break; case CA_OPTION1_NO_ACK_BLOCK: - if (CA_MSG_CONFIRM == pdu->hdr->type) + if (CA_MSG_CONFIRM == pdu->hdr->coap_hdr_udp_t.type) { // add data to send thread res = CASendBlockMessage(pdu, CA_MSG_ACKNOWLEDGE, blockWiseStatus, @@ -521,7 +521,8 @@ CAResult_t CAProcessNextStep(const coap_pdu_t *pdu, const CAData_t *receivedData break; case CA_BLOCK_INCOMPLETE: - if (CA_MSG_CONFIRM == pdu->hdr->type || CA_MSG_ACKNOWLEDGE == pdu->hdr->type) + if (CA_MSG_CONFIRM == pdu->hdr->coap_hdr_udp_t.type || + CA_MSG_ACKNOWLEDGE == pdu->hdr->coap_hdr_udp_t.type) { // add data to send thread res = CASendErrorMessage(pdu, blockWiseStatus, @@ -536,7 +537,7 @@ CAResult_t CAProcessNextStep(const coap_pdu_t *pdu, const CAData_t *receivedData break; case CA_BLOCK_TOO_LARGE: - if (CA_MSG_ACKNOWLEDGE == pdu->hdr->type) + if (CA_MSG_ACKNOWLEDGE == pdu->hdr->coap_hdr_udp_t.type) { res = CASendBlockMessage(pdu, CA_MSG_CONFIRM, blockWiseStatus, blockID); @@ -546,7 +547,7 @@ CAResult_t CAProcessNextStep(const coap_pdu_t *pdu, const CAData_t *receivedData return res; } } - else if (CA_MSG_CONFIRM == pdu->hdr->type) + else if (CA_MSG_CONFIRM == pdu->hdr->coap_hdr_udp_t.type) { res = CASendErrorMessage(pdu, blockWiseStatus, CA_REQUEST_ENTITY_TOO_LARGE, @@ -596,7 +597,7 @@ CAResult_t CASendBlockMessage(const coap_pdu_t *pdu, CAMessageType_t msgType, if (data->responseInfo) { OIC_LOG(DEBUG, TAG, "set ACK message"); - data->responseInfo->info.messageId = pdu->hdr->id; + data->responseInfo->info.messageId = pdu->hdr->coap_hdr_udp_t.id; data->responseInfo->info.type = CA_MSG_ACKNOWLEDGE; if (CA_OPTION1_NO_ACK_LAST_BLOCK == status) { @@ -638,7 +639,7 @@ CAResult_t CASendErrorMessage(const coap_pdu_t *pdu, uint8_t status, CAData_t *cloneData = NULL; if (data->sentData && data->sentData->responseInfo) { - data->sentData->responseInfo->info.messageId = pdu->hdr->id; + data->sentData->responseInfo->info.messageId = pdu->hdr->coap_hdr_udp_t.id; data->sentData->responseInfo->info.type = CA_MSG_ACKNOWLEDGE; data->sentData->responseInfo->result = responseResult; cloneData = CACloneCAData(data->sentData); @@ -750,8 +751,8 @@ CAResult_t CASetNextBlockOption1(coap_pdu_t *pdu, const CAEndpoint_t *endpoint, OIC_LOG_V(INFO, TAG, "num:%d, M:%d, sze:%d", block.num, block.m, block.szx); CABlockDataID_t* blockDataID = CACreateBlockDatablockId( - (CAToken_t)pdu->hdr->token, - pdu->hdr->token_length, + (CAToken_t)pdu->hdr->coap_hdr_udp_t.token, + pdu->hdr->coap_hdr_udp_t.token_length, endpoint->port); if(NULL == blockDataID || NULL == blockDataID->id || blockDataID->idLength < 1) @@ -805,9 +806,9 @@ CAResult_t CASetNextBlockOption1(coap_pdu_t *pdu, const CAEndpoint_t *endpoint, uint8_t blockWiseStatus = CA_BLOCK_UNKNOWN; // received type from remote device - if (CA_MSG_ACKNOWLEDGE == pdu->hdr->type) + if (CA_MSG_ACKNOWLEDGE == pdu->hdr->coap_hdr_udp_t.type) { - uint32_t code = CA_RESPONSE_CODE(pdu->hdr->code); + uint32_t code = CA_RESPONSE_CODE(pdu->hdr->coap_hdr_udp_t.code); if (0 == block.m && (CA_REQUEST_ENTITY_INCOMPLETE != code && CA_REQUEST_ENTITY_TOO_LARGE != code)) { @@ -846,7 +847,7 @@ CAResult_t CASetNextBlockOption1(coap_pdu_t *pdu, const CAEndpoint_t *endpoint, &(data->payloadLength)); // check if received payload is exact - if (CA_MSG_CONFIRM == pdu->hdr->type) + if (CA_MSG_CONFIRM == pdu->hdr->coap_hdr_udp_t.type) { blockWiseStatus = CACheckBlockErrorType(data, &block, receivedData, COAP_OPTION_BLOCK1, dataLen); @@ -926,8 +927,8 @@ CAResult_t CASetNextBlockOption2(coap_pdu_t *pdu, const CAEndpoint_t *endpoint, VERIFY_NON_NULL(receivedData, TAG, "receivedData"); CABlockDataID_t* blockDataID = CACreateBlockDatablockId( - (CAToken_t)pdu->hdr->token, - pdu->hdr->token_length, + (CAToken_t)pdu->hdr->coap_hdr_udp_t.token, + pdu->hdr->coap_hdr_udp_t.token_length, endpoint->port); if(NULL == blockDataID || NULL == blockDataID->id || blockDataID->idLength < 1) @@ -981,7 +982,7 @@ CAResult_t CASetNextBlockOption2(coap_pdu_t *pdu, const CAEndpoint_t *endpoint, } uint8_t blockWiseStatus = CA_BLOCK_UNKNOWN; - if (0 == block.num && CA_GET == pdu->hdr->code && 0 == block.m) + if (0 == block.num && CA_GET == pdu->hdr->coap_hdr_udp_t.code && 0 == block.m) { OIC_LOG(INFO, TAG, "first block number"); @@ -1008,8 +1009,9 @@ CAResult_t CASetNextBlockOption2(coap_pdu_t *pdu, const CAEndpoint_t *endpoint, else { // received type from remote device - if (CA_MSG_ACKNOWLEDGE == pdu->hdr->type || - (CA_MSG_NONCONFIRM == pdu->hdr->type && NULL != receivedData->responseInfo)) + if (CA_MSG_ACKNOWLEDGE == pdu->hdr->coap_hdr_udp_t.type || + (CA_MSG_NONCONFIRM == pdu->hdr->coap_hdr_udp_t.type && + NULL != receivedData->responseInfo)) { OIC_LOG(DEBUG, TAG, "received ACK or NON"); @@ -1019,7 +1021,7 @@ CAResult_t CASetNextBlockOption2(coap_pdu_t *pdu, const CAEndpoint_t *endpoint, &(data->payloadLength)); // check if received payload is exact - if (CA_MSG_ACKNOWLEDGE == pdu->hdr->type) + if (CA_MSG_ACKNOWLEDGE == pdu->hdr->coap_hdr_udp_t.type) { blockWiseStatus = CACheckBlockErrorType(data, &block, receivedData, COAP_OPTION_BLOCK2, dataLen); @@ -1051,7 +1053,7 @@ CAResult_t CASetNextBlockOption2(coap_pdu_t *pdu, const CAEndpoint_t *endpoint, { OIC_LOG(DEBUG, TAG, "M bit is 1"); - if (CA_MSG_ACKNOWLEDGE == pdu->hdr->type) + if (CA_MSG_ACKNOWLEDGE == pdu->hdr->coap_hdr_udp_t.type) { blockWiseStatus = CA_OPTION2_ACK; } @@ -1130,7 +1132,7 @@ CAResult_t CAUpdateBlockOptionItems(CABlockData_t *currData, const coap_pdu_t *p // update block data CAResult_t res = CA_STATUS_OK; - uint32_t code = CA_RESPONSE_CODE(pdu->hdr->code); + uint32_t code = CA_RESPONSE_CODE(pdu->hdr->coap_hdr_udp_t.code); if (CA_REQUEST_ENTITY_INCOMPLETE == code || CA_REQUEST_ENTITY_TOO_LARGE == code) { @@ -1192,7 +1194,7 @@ CAResult_t CAUpdateBlockOptionItems(CABlockData_t *currData, const coap_pdu_t *p if (CA_BLOCK_INCOMPLETE != status && CA_BLOCK_TOO_LARGE != status) { // negotiate block size - res = CANegotiateBlockSize(currData, block, pdu->hdr->type, blockType); + res = CANegotiateBlockSize(currData, block, pdu->hdr->coap_hdr_udp_t.type, blockType); if (CA_STATUS_OK != res) { OIC_LOG(ERROR, TAG, "negotiation has failed"); @@ -1324,7 +1326,7 @@ CAResult_t CAUpdateMessageId(coap_pdu_t *pdu, const CABlockDataID_t *blockID) VERIFY_NON_NULL(blockID, TAG, "blockID"); // if CON message is sent, update messageId in block-wise transfer list - if (CA_MSG_CONFIRM == pdu->hdr->type) + if (CA_MSG_CONFIRM == pdu->hdr->coap_hdr_udp_t.type) { CAData_t * cadata = CAGetDataSetFromBlockDataList(blockID); if (NULL == cadata) @@ -1335,7 +1337,7 @@ CAResult_t CAUpdateMessageId(coap_pdu_t *pdu, const CABlockDataID_t *blockID) if (NULL != cadata->requestInfo) { - cadata->requestInfo->info.messageId = pdu->hdr->id; + cadata->requestInfo->info.messageId = pdu->hdr->coap_hdr_udp_t.id; } } @@ -1360,7 +1362,7 @@ CAResult_t CAAddBlockOption(coap_pdu_t **pdu, const CAInfo_t info, OIC_LOG_V(DEBUG, TAG, "previous payload - %s", (*pdu)->data); - uint32_t code = CA_RESPONSE_CODE((*pdu)->hdr->code); + uint32_t code = CA_RESPONSE_CODE((*pdu)->hdr->coap_hdr_udp_t.code); if (CA_REQUEST_ENTITY_INCOMPLETE == code) { OIC_LOG(INFO, TAG, "don't use option"); @@ -1368,8 +1370,8 @@ CAResult_t CAAddBlockOption(coap_pdu_t **pdu, const CAInfo_t info, } CABlockDataID_t* blockDataID = CACreateBlockDatablockId( - (CAToken_t)(*pdu)->hdr->token, - (*pdu)->hdr->token_length, + (CAToken_t)(*pdu)->hdr->coap_hdr_udp_t.token, + (*pdu)->hdr->coap_hdr_udp_t.token_length, endpoint->port); if(NULL == blockDataID || NULL == blockDataID->id || blockDataID->idLength < 1) @@ -1452,8 +1454,9 @@ CAResult_t CAAddBlockOption2(coap_pdu_t **pdu, const CAInfo_t info, size_t dataL CALogBlockInfo(block2); uint8_t code = 0; - if (CA_MSG_ACKNOWLEDGE == (*pdu)->hdr->type || - (CA_MSG_NONCONFIRM == (*pdu)->hdr->type && CA_GET != (*pdu)->hdr->code)) + if (CA_MSG_ACKNOWLEDGE == (*pdu)->hdr->coap_hdr_udp_t.type || + (CA_MSG_NONCONFIRM == (*pdu)->hdr->coap_hdr_udp_t.type && + CA_GET != (*pdu)->hdr->coap_hdr_udp_t.code)) { int32_t res = coap_write_block_opt(block2, COAP_OPTION_BLOCK2, *pdu, dataLength); switch (res) @@ -1514,7 +1517,7 @@ CAResult_t CAAddBlockOption2(coap_pdu_t **pdu, const CAInfo_t info, size_t dataL } else { - if (CA_MSG_NONCONFIRM == (*pdu)->hdr->type) + if (CA_MSG_NONCONFIRM == (*pdu)->hdr->coap_hdr_udp_t.type) { OIC_LOG(DEBUG, TAG, "NON, send next block.."); // update block data @@ -1577,7 +1580,7 @@ CAResult_t CAAddBlockOption1(coap_pdu_t **pdu, const CAInfo_t info, size_t dataL CALogBlockInfo(block1); - if (CA_MSG_ACKNOWLEDGE == (*pdu)->hdr->type) + if (CA_MSG_ACKNOWLEDGE == (*pdu)->hdr->coap_hdr_udp_t.type) { OIC_LOG(DEBUG, TAG, "option1 and ACK msg.."); CAResult_t res = CAAddBlockOptionImpl(*pdu, block1, COAP_OPTION_BLOCK1); @@ -1632,7 +1635,7 @@ CAResult_t CAAddBlockOption1(coap_pdu_t **pdu, const CAInfo_t info, size_t dataL } // check the message type and if message type is NON, next block message will be sent - if (CA_MSG_NONCONFIRM == (*pdu)->hdr->type) + if (CA_MSG_NONCONFIRM == (*pdu)->hdr->coap_hdr_udp_t.type) { if (block1->m) { @@ -1679,7 +1682,7 @@ CAResult_t CAAddBlockOptionImpl(coap_pdu_t *pdu, coap_block_t *block, uint8_t bl option->length = coap_encode_var_bytes(buf, ((block->num << BLOCK_NUMBER_IDX) | (block->m << BLOCK_M_BIT_IDX) | block->szx)); - if (!coap_add_option(pdu, option->key, option->length, buf)) + if (!coap_add_option(pdu, option->key, option->length, buf, coap_udp)) { OIC_LOG(ERROR, TAG, "coap_add_option has failed"); OICFree(option); @@ -1706,7 +1709,7 @@ CAResult_t CAAddBlockSizeOption(coap_pdu_t *pdu, uint16_t sizeType, size_t dataL unsigned char value[BLOCKWISE_OPTION_BUFFER] = { 0 }; unsigned int optionLength = coap_encode_var_bytes(value, dataLength); - if (!coap_add_option(pdu, sizeType, optionLength, value)) + if (!coap_add_option(pdu, sizeType, optionLength, value, coap_udp)) { OIC_LOG(ERROR, TAG, "failed to add size option"); return CA_STATUS_FAILED; @@ -1943,14 +1946,14 @@ CAData_t* CACreateNewDataSet(const coap_pdu_t *pdu, const CAEndpoint_t *endpoint VERIFY_NON_NULL_RET(pdu->hdr, TAG, "pdu->hdr", NULL); VERIFY_NON_NULL_RET(endpoint, TAG, "endpoint", NULL); - CAInfo_t responseData = { .tokenLength = pdu->hdr->token_length }; + CAInfo_t responseData = { .tokenLength = pdu->hdr->coap_hdr_udp_t.token_length }; responseData.token = (CAToken_t) OICMalloc(responseData.tokenLength); if (NULL == responseData.token) { OIC_LOG(ERROR, TAG, "out of memory"); return NULL; } - memcpy(responseData.token, pdu->hdr->token, responseData.tokenLength); + memcpy(responseData.token, pdu->hdr->coap_hdr_udp_t.token, responseData.tokenLength); CAResponseInfo_t* responseInfo = (CAResponseInfo_t*) OICCalloc(1, sizeof(CAResponseInfo_t)); if (NULL == responseInfo) @@ -2204,7 +2207,7 @@ CAResult_t CAGetTokenFromBlockDataList(const coap_pdu_t *pdu, const CAEndpoint_t if (NULL != currData->sentData && NULL != currData->sentData->requestInfo) { - if (pdu->hdr->id == currData->sentData->requestInfo->info.messageId && + if (pdu->hdr->coap_hdr_udp_t.id == currData->sentData->requestInfo->info.messageId && endpoint->adapter == currData->sentData->remoteEndpoint->adapter) { if (NULL != currData->sentData->requestInfo->info.token) diff --git a/resource/csdk/connectivity/src/camessagehandler.c b/resource/csdk/connectivity/src/camessagehandler.c index 0742377..f746cac 100644 --- a/resource/csdk/connectivity/src/camessagehandler.c +++ b/resource/csdk/connectivity/src/camessagehandler.c @@ -156,7 +156,7 @@ static CAData_t* CAGenerateHandlerData(const CAEndpoint_t *endpoint, return NULL; } - result = CAGetResponseInfoFromPDU(data, resInfo); + result = CAGetResponseInfoFromPDU(data, resInfo, endpoint->flags); if (CA_STATUS_OK != result) { OIC_LOG(ERROR, TAG, "CAGetResponseInfoFromPDU Failed"); @@ -185,7 +185,7 @@ static CAData_t* CAGenerateHandlerData(const CAEndpoint_t *endpoint, return NULL; } - result = CAGetRequestInfoFromPDU(data, reqInfo); + result = CAGetRequestInfoFromPDU(data, reqInfo, endpoint->flags); if (CA_STATUS_OK != result) { OIC_LOG(ERROR, TAG, "CAGetRequestInfoFromPDU failed"); @@ -224,7 +224,7 @@ static CAData_t* CAGenerateHandlerData(const CAEndpoint_t *endpoint, return NULL; } - CAResult_t result = CAGetErrorInfoFromPDU(data, errorInfo); + CAResult_t result = CAGetErrorInfoFromPDU(data, errorInfo, endpoint->flags); if (CA_STATUS_OK != result) { OIC_LOG(ERROR, TAG, "CAGetErrorInfoFromPDU failed"); @@ -278,7 +278,8 @@ static void CATimeoutCallback(const CAEndpoint_t *endpoint, const void *pdu, uin resInfo->info.type = CAGetMessageTypeFromPduBinaryData(pdu, size); resInfo->info.messageId = CAGetMessageIdFromPduBinaryData(pdu, size); - CAResult_t res = CAGetTokenFromPDU((const coap_hdr_t *) pdu, &(resInfo->info)); + CAResult_t res = CAGetTokenFromPDU((const coap_hdr_t *) pdu, &(resInfo->info), + endpoint->flags); if (CA_STATUS_OK != res) { OIC_LOG(ERROR, TAG, "fail to get Token from retransmission list"); @@ -446,7 +447,11 @@ static CAResult_t CAProcessSendData(const CAData_t *data) if (NULL != pdu) { #ifdef WITH_BWT - if (CA_ADAPTER_GATT_BTLE != data->remoteEndpoint->adapter) + if (CA_ADAPTER_GATT_BTLE != data->remoteEndpoint->adapter +#ifdef CI_ADAPTER + && CA_IPV4_TCP != data->remoteEndpoint->flags +#endif + ) { // Blockwise transfer if (NULL != info) @@ -463,7 +468,7 @@ static CAResult_t CAProcessSendData(const CAData_t *data) } } #endif - CALogPDUInfo(pdu); + CALogPDUInfo(pdu, data->remoteEndpoint->flags); res = CASendUnicastData(data->remoteEndpoint, pdu->hdr, pdu->length); if (CA_STATUS_OK != res) @@ -473,15 +478,25 @@ static CAResult_t CAProcessSendData(const CAData_t *data) coap_delete_pdu(pdu); return res; } - // for retransmission - res = CARetransmissionSentData(&g_retransmissionContext, data->remoteEndpoint, pdu->hdr, - pdu->length); - if ((CA_STATUS_OK != res) && (CA_NOT_SUPPORTED != res)) + +#ifdef CI_ADAPTER + if (CA_IPV4_TCP == data->remoteEndpoint->flags) { - //when retransmission not supported this will return CA_NOT_SUPPORTED, ignore - OIC_LOG_V(INFO, TAG, "retransmission is not enabled due to error, res : %d", res); - coap_delete_pdu(pdu); - return res; + OIC_LOG(INFO, TAG, "retransmission will be not worked"); + } + else +#endif + { + // for retransmission + res = CARetransmissionSentData(&g_retransmissionContext, data->remoteEndpoint, pdu->hdr, + pdu->length); + if ((CA_STATUS_OK != res) && (CA_NOT_SUPPORTED != res)) + { + //when retransmission not supported this will return CA_NOT_SUPPORTED, ignore + OIC_LOG_V(INFO, TAG, "retransmission is not enabled due to error, res : %d", res); + coap_delete_pdu(pdu); + return res; + } } coap_delete_pdu(pdu); @@ -505,7 +520,11 @@ static CAResult_t CAProcessSendData(const CAData_t *data) if (NULL != pdu) { #ifdef WITH_BWT - if (CA_ADAPTER_GATT_BTLE != data->remoteEndpoint->adapter) + if (CA_ADAPTER_GATT_BTLE != data->remoteEndpoint->adapter +#ifdef CI_ADAPTER + && CA_IPV4_TCP != data->remoteEndpoint->flags +#endif + ) { // Blockwise transfer CAResult_t res = CAAddBlockOption(&pdu, data->requestInfo->info, @@ -519,7 +538,7 @@ static CAResult_t CAProcessSendData(const CAData_t *data) } } #endif - CALogPDUInfo(pdu); + CALogPDUInfo(pdu, data->remoteEndpoint->flags); res = CASendMulticastData(data->remoteEndpoint, pdu->hdr, pdu->length); if (CA_STATUS_OK != res) @@ -530,6 +549,9 @@ static CAResult_t CAProcessSendData(const CAData_t *data) return res; } + OIC_LOG(DEBUG, TAG, "pdu to send :"); + OIC_LOG_BUFFER(DEBUG, TAG, pdu->hdr, pdu->length); + coap_delete_pdu(pdu); } else @@ -613,10 +635,14 @@ static void CAReceivedPacketCallback(const CASecureEndpoint_t *sep, VERIFY_NON_NULL_VOID(sep, TAG, "remoteEndpoint"); VERIFY_NON_NULL_VOID(data, TAG, "data"); + OIC_LOG(DEBUG, TAG, "received pdu data :"); + OIC_LOG_BUFFER(DEBUG, TAG, data, dataLen); + uint32_t code = CA_NOT_FOUND; CAData_t *cadata = NULL; - coap_pdu_t *pdu = (coap_pdu_t *) CAParsePDU((const char *) data, dataLen, &code); + coap_pdu_t *pdu = (coap_pdu_t *) CAParsePDU((const char *) data, dataLen, &code, + sep->endpoint.flags); if (NULL == pdu) { OIC_LOG(ERROR, TAG, "Parse PDU failed"); @@ -644,28 +670,37 @@ static void CAReceivedPacketCallback(const CASecureEndpoint_t *sep, return; } - // for retransmission - void *retransmissionPdu = NULL; - CARetransmissionReceivedData(&g_retransmissionContext, cadata->remoteEndpoint, pdu->hdr, - pdu->length, &retransmissionPdu); - - // get token from saved data in retransmission list - if (retransmissionPdu && CA_EMPTY == code) +#ifdef CI_ADAPTER + if (CA_IPV4_TCP == sep->endpoint.flags) + { + OIC_LOG(INFO, TAG, "retransmission will be not worked"); + } + else +#endif { - if (cadata->responseInfo) + // for retransmission + void *retransmissionPdu = NULL; + CARetransmissionReceivedData(&g_retransmissionContext, cadata->remoteEndpoint, pdu->hdr, + pdu->length, &retransmissionPdu); + + // get token from saved data in retransmission list + if (retransmissionPdu && CA_EMPTY == code) { - CAInfo_t *info = &cadata->responseInfo->info; - CAResult_t res = CAGetTokenFromPDU((const coap_hdr_t *)retransmissionPdu, - info); - if (CA_STATUS_OK != res) + if (cadata->responseInfo) { - OIC_LOG(ERROR, TAG, "fail to get Token from retransmission list"); - OICFree(info->token); - info->tokenLength = 0; + CAInfo_t *info = &cadata->responseInfo->info; + CAResult_t res = CAGetTokenFromPDU((const coap_hdr_t *)retransmissionPdu, + info, sep->endpoint.flags); + if (CA_STATUS_OK != res) + { + OIC_LOG(ERROR, TAG, "fail to get Token from retransmission list"); + OICFree(info->token); + info->tokenLength = 0; + } } } + OICFree(retransmissionPdu); } - OICFree(retransmissionPdu); } cadata->type = SEND_TYPE_UNICAST; @@ -674,7 +709,11 @@ static void CAReceivedPacketCallback(const CASecureEndpoint_t *sep, CAProcessReceivedData(cadata); #else #ifdef WITH_BWT - if (CA_ADAPTER_GATT_BTLE != sep->endpoint.adapter) + if (CA_ADAPTER_GATT_BTLE != sep->endpoint.adapter +#ifdef CI_ADAPTER + && CA_IPV4_TCP != sep->endpoint.flags +#endif + ) { CAResult_t res = CAReceiveBlockWiseData(pdu, &(sep->endpoint), cadata, dataLen); if (CA_NOT_SUPPORTED == res) @@ -865,7 +904,11 @@ CAResult_t CADetachRequestMessage(const CAEndpoint_t *object, const CARequestInf CADestroyData(data, sizeof(CAData_t)); #else #ifdef WITH_BWT - if (CA_ADAPTER_GATT_BTLE != object->adapter) + if (CA_ADAPTER_GATT_BTLE != object->adapter +#ifdef CI_ADAPTER + && CA_IPV4_TCP != object->flags +#endif + ) { // send block data CAResult_t res = CASendBlockWiseData(data); @@ -922,7 +965,11 @@ CAResult_t CADetachResponseMessage(const CAEndpoint_t *object, CADestroyData(data, sizeof(CAData_t)); #else #ifdef WITH_BWT - if (CA_ADAPTER_GATT_BTLE != object->adapter) + if (CA_ADAPTER_GATT_BTLE != object->adapter +#ifdef CI_ADAPTER + && CA_IPV4_TCP != object->flags +#endif + ) { // send block data CAResult_t res = CASendBlockWiseData(data); @@ -1130,19 +1177,30 @@ void CATerminateMessageHandler() OIC_LOG(DEBUG, TAG, "OUT"); } -void CALogPDUInfo(coap_pdu_t *pdu) +void CALogPDUInfo(coap_pdu_t *pdu, CATransportFlags_t flags) { VERIFY_NON_NULL_VOID(pdu, TAG, "pdu"); OIC_LOG_V(DEBUG, TAG, "PDU Maker - payload : %s", pdu->data); - OIC_LOG_V(DEBUG, TAG, "PDU Maker - type : %d", pdu->hdr->type); +#ifdef CI_ADAPTER + if (CA_IPV4_TCP != flags) + { + OIC_LOG(DEBUG, TAG, "pdu headert data :"); + OIC_LOG_BUFFER(DEBUG, TAG, pdu->hdr, pdu->length); + } + else +#endif + { + OIC_LOG_V(DEBUG, TAG, "PDU Maker - type : %d", pdu->hdr->coap_hdr_udp_t.type); - OIC_LOG_V(DEBUG, TAG, "PDU Maker - code : %d", pdu->hdr->code); + OIC_LOG_V(DEBUG, TAG, "PDU Maker - code : %d", pdu->hdr->coap_hdr_udp_t.code); - OIC_LOG(DEBUG, TAG, "PDU Maker - token :"); + OIC_LOG(DEBUG, TAG, "PDU Maker - token :"); - OIC_LOG_BUFFER(DEBUG, TAG, pdu->hdr->token, pdu->hdr->token_length); + OIC_LOG_BUFFER(DEBUG, TAG, pdu->hdr->coap_hdr_udp_t.token, + pdu->hdr->coap_hdr_udp_t.token_length); + } } static void CALogPayloadInfo(CAInfo_t *info) @@ -1193,7 +1251,7 @@ void CAErrorHandler(const CAEndpoint_t *endpoint, uint32_t code = CA_NOT_FOUND; //Do not free remoteEndpoint and data. Currently they will be freed in data thread //Get PDU data - coap_pdu_t *pdu = (coap_pdu_t *)CAParsePDU((const char *)data, dataLen, &code); + coap_pdu_t *pdu = (coap_pdu_t *)CAParsePDU((const char *)data, dataLen, &code, endpoint->flags); if (NULL == pdu) { OIC_LOG(ERROR, TAG, "Parse PDU failed"); diff --git a/resource/csdk/connectivity/src/caprotocolmessage.c b/resource/csdk/connectivity/src/caprotocolmessage.c index b140264..23af19c 100644 --- a/resource/csdk/connectivity/src/caprotocolmessage.c +++ b/resource/csdk/connectivity/src/caprotocolmessage.c @@ -67,7 +67,8 @@ static const char COAP_URI_HEADER[] = "coap://[::]/"; static unsigned int SEED = 0; -CAResult_t CAGetRequestInfoFromPDU(const coap_pdu_t *pdu, CARequestInfo_t *outReqInfo) +CAResult_t CAGetRequestInfoFromPDU(const coap_pdu_t *pdu, CARequestInfo_t *outReqInfo, + CATransportFlags_t flags) { OIC_LOG(DEBUG, TAG, "IN"); @@ -78,14 +79,15 @@ CAResult_t CAGetRequestInfoFromPDU(const coap_pdu_t *pdu, CARequestInfo_t *outRe } uint32_t code = CA_NOT_FOUND; - CAResult_t ret = CAGetInfoFromPDU(pdu, &code, &(outReqInfo->info)); + CAResult_t ret = CAGetInfoFromPDU(pdu, &code, &(outReqInfo->info), flags); outReqInfo->method = code; OIC_LOG(DEBUG, TAG, "OUT"); return ret; } -CAResult_t CAGetResponseInfoFromPDU(const coap_pdu_t *pdu, CAResponseInfo_t *outResInfo) +CAResult_t CAGetResponseInfoFromPDU(const coap_pdu_t *pdu, CAResponseInfo_t *outResInfo, + CATransportFlags_t flags) { OIC_LOG(DEBUG, TAG, "IN"); @@ -96,14 +98,15 @@ CAResult_t CAGetResponseInfoFromPDU(const coap_pdu_t *pdu, CAResponseInfo_t *out } uint32_t code = CA_NOT_FOUND; - CAResult_t ret = CAGetInfoFromPDU(pdu, &code, &(outResInfo->info)); + CAResult_t ret = CAGetInfoFromPDU(pdu, &code, &(outResInfo->info), flags); outResInfo->result = code; OIC_LOG(DEBUG, TAG, "OUT"); return ret; } -CAResult_t CAGetErrorInfoFromPDU(const coap_pdu_t *pdu, CAErrorInfo_t *errorInfo) +CAResult_t CAGetErrorInfoFromPDU(const coap_pdu_t *pdu, CAErrorInfo_t *errorInfo, + CATransportFlags_t flags) { OIC_LOG(DEBUG, TAG, "IN"); @@ -114,7 +117,7 @@ CAResult_t CAGetErrorInfoFromPDU(const coap_pdu_t *pdu, CAErrorInfo_t *errorInfo } uint32_t code = 0; - CAResult_t ret = CAGetInfoFromPDU(pdu, &code, &errorInfo->info); + CAResult_t ret = CAGetInfoFromPDU(pdu, &code, &errorInfo->info, flags); OIC_LOG(DEBUG, TAG, "OUT"); return ret; } @@ -205,7 +208,8 @@ coap_pdu_t *CAGeneratePDU(uint32_t code, const CAInfo_t *info, const CAEndpoint_ return pdu; } -coap_pdu_t *CAParsePDU(const char *data, uint32_t length, uint32_t *outCode) +coap_pdu_t *CAParsePDU(const char *data, uint32_t length, uint32_t *outCode, + CATransportFlags_t flags) { OIC_LOG(DEBUG, TAG, "IN"); @@ -215,31 +219,56 @@ coap_pdu_t *CAParsePDU(const char *data, uint32_t length, uint32_t *outCode) return NULL; } - coap_pdu_t *outpdu = coap_new_pdu(); + coap_transport_type transport; +#ifdef CI_ADAPTER + if (CA_IPV4_TCP == flags) + { + transport = coap_get_tcp_header_type_from_initbyte(((unsigned char *)data)[0] >> 4); + } + else +#endif + { + transport = coap_udp; + } + + coap_pdu_t *outpdu = coap_new_pdu(transport); if (NULL == outpdu) { OIC_LOG(ERROR, TAG, "outpdu is null"); return NULL; } - if (0 >= coap_pdu_parse((unsigned char *) data, length, outpdu)) + OIC_LOG_V(DEBUG, TAG, "pdu parse-transport type : %d", transport); + + int ret = coap_pdu_parse((unsigned char *) data, length, outpdu, transport); + OIC_LOG_V(DEBUG, TAG, "pdu parse ret: %d", ret); + if (0 >= ret) { OIC_LOG(ERROR, TAG, "pdu parse failed"); coap_delete_pdu(outpdu); return NULL; } - if (outpdu->hdr->version != COAP_DEFAULT_VERSION) +#ifdef CI_ADAPTER + if (CA_IPV4_TCP == flags) { - OIC_LOG_V(ERROR, TAG, "coap version is not available : %d", - outpdu->hdr->version); - coap_delete_pdu(outpdu); - return NULL; + OIC_LOG(INFO, TAG, "there is no version info in coap header"); + } + else +#endif + { + if (outpdu->hdr->coap_hdr_udp_t.version != COAP_DEFAULT_VERSION) + { + OIC_LOG_V(ERROR, TAG, "coap version is not available : %d", + outpdu->hdr->coap_hdr_udp_t.version); + coap_delete_pdu(outpdu); + return NULL; + } } if (outCode) { - (*outCode) = (uint32_t) CA_RESPONSE_CODE(outpdu->hdr->code); + (*outCode) = (uint32_t) CA_RESPONSE_CODE(coap_get_code(outpdu, transport)); } OIC_LOG(DEBUG, TAG, "OUT"); @@ -252,7 +281,21 @@ coap_pdu_t *CAGeneratePDUImpl(code_t code, coap_list_t *options, const CAInfo_t OIC_LOG(DEBUG, TAG, "IN"); VERIFY_NON_NULL_RET(info, TAG, "info is NULL", NULL); - coap_pdu_t *pdu = coap_new_pdu(); + coap_transport_type transport; + +#ifdef CI_ADAPTER + if (CA_IPV4_TCP == endpoint->flags) + { + + transport = coap_get_tcp_header_type_from_size(info->payloadSize); + } + else +#endif + { + transport = coap_udp; + } + + coap_pdu_t *pdu = coap_new_pdu(transport); if (NULL == pdu) { @@ -260,25 +303,38 @@ coap_pdu_t *CAGeneratePDUImpl(code_t code, coap_list_t *options, const CAInfo_t return NULL; } - OIC_LOG_V(DEBUG, TAG, "msgID is %d", info->messageId); - uint16_t message_id; - if (0 == info->messageId) - { - /* initialize message id */ - prng((uint8_t * ) &message_id, sizeof(message_id)); + OIC_LOG_V(DEBUG, TAG, "transport type: %d, payload size: %d", + transport, info->payloadSize); - OIC_LOG_V(DEBUG, TAG, "gen msg id=%d", message_id); +#ifdef CI_ADAPTER + if (CA_IPV4_TCP == endpoint->flags) + { + coap_add_code(pdu, transport, code); + coap_add_length(pdu, transport, info->payloadSize); } else +#endif { - /* use saved message id */ - message_id = info->messageId; - } - pdu->hdr->id = message_id; - OIC_LOG_V(DEBUG, TAG, "messageId in pdu is %d, %d", message_id, pdu->hdr->id); + OIC_LOG_V(DEBUG, TAG, "msgID is %d", info->messageId); + uint16_t message_id; + if (0 == info->messageId) + { + /* initialize message id */ + prng((uint8_t * ) &message_id, sizeof(message_id)); - pdu->hdr->type = info->type; - pdu->hdr->code = COAP_RESPONSE_CODE(code); + OIC_LOG_V(DEBUG, TAG, "gen msg id=%d", message_id); + } + else + { + /* use saved message id */ + message_id = info->messageId; + } + pdu->hdr->coap_hdr_udp_t.id = message_id; + OIC_LOG_V(DEBUG, TAG, "messageId in pdu is %d, %d", message_id, pdu->hdr->coap_hdr_udp_t.id); + + pdu->hdr->coap_hdr_udp_t.type = info->type; + coap_add_code(pdu, transport, code); + } if (info->token && CA_EMPTY != code) { @@ -286,7 +342,7 @@ coap_pdu_t *CAGeneratePDUImpl(code_t code, coap_list_t *options, const CAInfo_t OIC_LOG_V(DEBUG, TAG, "token info token length: %d, token :", tokenLength); OIC_LOG_BUFFER(DEBUG, TAG, (const uint8_t *)info->token, tokenLength); - int32_t ret = coap_add_token(pdu, tokenLength, (unsigned char *)info->token); + int32_t ret = coap_add_token(pdu, tokenLength, (unsigned char *)info->token, transport); if (0 == ret) { OIC_LOG(ERROR, TAG, "can't add token"); @@ -299,9 +355,11 @@ coap_pdu_t *CAGeneratePDUImpl(code_t code, coap_list_t *options, const CAInfo_t { OIC_LOG_V(DEBUG, TAG, "[%s] opt will be added.", COAP_OPTION_DATA(*(coap_option *) opt->data)); + + OIC_LOG_V(DEBUG, TAG, "[%d] pdu length", pdu->length); coap_add_option(pdu, COAP_OPTION_KEY(*(coap_option *) opt->data), COAP_OPTION_LENGTH(*(coap_option *) opt->data), - COAP_OPTION_DATA(*(coap_option *) opt->data)); + COAP_OPTION_DATA(*(coap_option *) opt->data), transport); } } @@ -310,7 +368,11 @@ coap_pdu_t *CAGeneratePDUImpl(code_t code, coap_list_t *options, const CAInfo_t enabledPayload = true; #endif - if (enabledPayload || CA_ADAPTER_GATT_BTLE == endpoint->adapter) + if (enabledPayload || CA_ADAPTER_GATT_BTLE == endpoint->adapter +#ifdef CI_ADAPTER + || CA_IPV4_TCP == endpoint->flags +#endif + ) { if (NULL != info->payload && 0 < info->payloadSize) { @@ -568,7 +630,8 @@ uint32_t CAGetOptionCount(coap_opt_iterator_t opt_iter) return count; } -CAResult_t CAGetInfoFromPDU(const coap_pdu_t *pdu, uint32_t *outCode, CAInfo_t *outInfo) +CAResult_t CAGetInfoFromPDU(const coap_pdu_t *pdu, uint32_t *outCode, CAInfo_t *outInfo, + CATransportFlags_t flags) { OIC_LOG(DEBUG, TAG, "IN"); @@ -578,12 +641,24 @@ CAResult_t CAGetInfoFromPDU(const coap_pdu_t *pdu, uint32_t *outCode, CAInfo_t * return CA_STATUS_INVALID_PARAM; } + coap_transport_type transport; +#ifdef CI_ADAPTER + if (CA_IPV4_TCP == flags) + { + transport = coap_get_tcp_header_type_from_initbyte(((unsigned char *)pdu->hdr)[0] >> 4); + } + else +#endif + { + transport = coap_udp; + } + coap_opt_iterator_t opt_iter; - coap_option_iterator_init((coap_pdu_t *) pdu, &opt_iter, COAP_OPT_ALL); + coap_option_iterator_init((coap_pdu_t *) pdu, &opt_iter, COAP_OPT_ALL, transport); if (outCode) { - (*outCode) = (uint32_t) CA_RESPONSE_CODE(pdu->hdr->code); + (*outCode) = (uint32_t) CA_RESPONSE_CODE(coap_get_code(pdu, transport)); } // init HeaderOption list @@ -592,11 +667,22 @@ CAResult_t CAGetInfoFromPDU(const coap_pdu_t *pdu, uint32_t *outCode, CAInfo_t * outInfo->numOptions = count; - // set type - outInfo->type = pdu->hdr->type; +#ifdef CI_ADAPTER + if (CA_IPV4_TCP == flags) + { + // set type + outInfo->type = CA_MSG_NONCONFIRM; + } + else +#endif + { + // set type + outInfo->type = pdu->hdr->coap_hdr_udp_t.type; + + // set message id + outInfo->messageId = pdu->hdr->coap_hdr_udp_t.id; + } - // set message id - outInfo->messageId = pdu->hdr->id; if (count > 0) { @@ -722,21 +808,25 @@ CAResult_t CAGetInfoFromPDU(const coap_pdu_t *pdu, uint32_t *outCode, CAInfo_t * } } + unsigned char* token; + unsigned int token_length; + coap_get_token(pdu->hdr, transport, &token, &token_length); + // set token data - if (pdu->hdr->token_length > 0) + if (token_length > 0) { - OIC_LOG_V(DEBUG, TAG, "inside token length : %d", pdu->hdr->token_length); - outInfo->token = (char *) OICMalloc(pdu->hdr->token_length); + OIC_LOG_V(DEBUG, TAG, "inside token length : %d", token_length); + outInfo->token = (char *) OICMalloc(token_length); if (NULL == outInfo->token) { OIC_LOG(ERROR, TAG, "Out of memory"); OICFree(outInfo->options); return CA_MEMORY_ALLOC_FAILED; } - memcpy(outInfo->token, pdu->hdr->token, pdu->hdr->token_length); + memcpy(outInfo->token, token, token_length); } - outInfo->tokenLength = pdu->hdr->token_length; + outInfo->tokenLength = token_length; // set payload data size_t dataSize; @@ -778,7 +868,8 @@ exit: return CA_STATUS_FAILED; } -CAResult_t CAGetTokenFromPDU(const coap_hdr_t *pdu_hdr, CAInfo_t *outInfo) +CAResult_t CAGetTokenFromPDU(const coap_hdr_t *pdu_hdr, CAInfo_t *outInfo, + CATransportFlags_t flags) { OIC_LOG(DEBUG, TAG, "IN"); if (NULL == pdu_hdr) @@ -793,20 +884,36 @@ CAResult_t CAGetTokenFromPDU(const coap_hdr_t *pdu_hdr, CAInfo_t *outInfo) return CA_STATUS_INVALID_PARAM; } + coap_transport_type transport; +#ifdef CI_ADAPTER + if (CA_IPV4_TCP == flags) + { + transport = coap_get_tcp_header_type_from_initbyte(((unsigned char *)pdu_hdr)[0] >> 4); + } + else +#endif + { + transport = coap_udp; + } + + unsigned char* token; + unsigned int token_length; + coap_get_token(pdu_hdr, transport, &token, &token_length); + // set token data - if (pdu_hdr->token_length > 0) + if (token_length > 0) { - OIC_LOG_V(DEBUG, TAG, "token len:%d", pdu_hdr->token_length); - outInfo->token = (char *) OICMalloc(pdu_hdr->token_length); + OIC_LOG_V(DEBUG, TAG, "token len:%d", token_length); + outInfo->token = (char *) OICMalloc(token_length); if (NULL == outInfo->token) { - OIC_LOG(ERROR, TAG, "out of memory"); + OIC_LOG(ERROR, TAG, "Out of memory"); return CA_MEMORY_ALLOC_FAILED; } - memcpy(outInfo->token, pdu_hdr->token, pdu_hdr->token_length); + memcpy(outInfo->token, token, token_length); } - outInfo->tokenLength = pdu_hdr->token_length; + outInfo->tokenLength = token_length; OIC_LOG(DEBUG, TAG, "OUT"); @@ -947,7 +1054,7 @@ CAMessageType_t CAGetMessageTypeFromPduBinaryData(const void *pdu, uint32_t size coap_hdr_t *hdr = (coap_hdr_t *) pdu; - return (CAMessageType_t) hdr->type; + return (CAMessageType_t) hdr->coap_hdr_udp_t.type; } uint16_t CAGetMessageIdFromPduBinaryData(const void *pdu, uint32_t size) @@ -967,7 +1074,7 @@ uint16_t CAGetMessageIdFromPduBinaryData(const void *pdu, uint32_t size) coap_hdr_t *hdr = (coap_hdr_t *) pdu; - return hdr->id; + return hdr->coap_hdr_udp_t.id; } CAResponseResult_t CAGetCodeFromPduBinaryData(const void *pdu, uint32_t size) @@ -987,5 +1094,5 @@ CAResponseResult_t CAGetCodeFromPduBinaryData(const void *pdu, uint32_t size) coap_hdr_t *hdr = (coap_hdr_t *) pdu; - return (CAResponseResult_t) CA_RESPONSE_CODE(hdr->code); + return (CAResponseResult_t) CA_RESPONSE_CODE(hdr->coap_hdr_udp_t.code); } -- 2.7.4