netutils/libcoap : bug fixes for CoAP over TCP
authorJin-Seong Kim <jseong82.kim@samsung.com>
Tue, 8 Aug 2017 08:29:58 +0000 (17:29 +0900)
committerEunBong Song <eunb.song@samsung.com>
Wed, 30 Aug 2017 04:16:44 +0000 (21:16 -0700)
This commit is patch for bug fixes for CoAP over TCP
1. patch for memory leakage issue
 - some pdus are not freed when coap_send returns COAP_INVALID_TID
2. add waiting routine on libcoap-server
 - waiting until g_operating_status is SERVER_STOPPED state
 - duplicated libcoap-server process can cause abort during long-run test
3. add debug logs for further tracing

Change-Id: Ib1173a6f24691eebae5860727227d85c09972ef3
Signed-off-by: Jin-Seong Kim <jseong82.kim@samsung.com>
apps/examples/libcoap_client/libcoap-client.c
apps/examples/libcoap_server/libcoap-server.c
apps/netutils/libcoap/net.c
apps/netutils/libcoap/resource.c

index 117898e..90b4fe3 100644 (file)
@@ -431,6 +431,7 @@ void message_handler(struct coap_context_t *ctx, const coap_address_t *remote, c
                                }
                        } else if (ctx->protocol == COAP_PROTO_TCP || ctx->protocol == COAP_PROTO_TLS) {
                                /* TODO: do nothing? */
+                               debug("message_handler : do nothing\n");
                        } else {
                                /* should not enter here */
                        }
@@ -455,12 +456,12 @@ void message_handler(struct coap_context_t *ctx, const coap_address_t *remote, c
 
        code = (unsigned short)coap_get_code(received, transport);
 
+       debug("message_handler : code %d, sent %p\n", code, sent);
+
        /* output the received data, if any */
        if (code == COAP_RESPONSE_CODE(205)) {
 
                /* set obs timer if we have successfully subscribed a resource */
-               info("message_handler : code %d, sent %p\n", code, sent);
-
                if (sent && coap_check_option2(received, COAP_OPTION_SUBSCRIPTION, &opt_iter, transport)) {
                        printf("message_handler : observation relationship established, set timeout to %d\n", obs_seconds);
                        set_timeout(&obs_wait, obs_seconds);
@@ -544,6 +545,7 @@ void message_handler(struct coap_context_t *ctx, const coap_address_t *remote, c
                }
        } else {                                        /* no 2.05 */
 
+               debug("message_handler : response class %d\n", COAP_RESPONSE_CLASS(code));
                /* check if an error was signaled and output payload if so */
                if (COAP_RESPONSE_CLASS(code) >= 4) {
                        fprintf(stderr, "%d.%02d", (code >> 5), code & 0x1F);
@@ -559,8 +561,12 @@ void message_handler(struct coap_context_t *ctx, const coap_address_t *remote, c
        }
 
        /* finally send new request, if needed */
-       if (pdu && coap_send(ctx, remote, pdu) == COAP_INVALID_TID) {
-               debug("message_handler: error sending response");
+       if (pdu != NULL) {
+               if (coap_send(ctx, remote, pdu) == COAP_INVALID_TID) {
+                       debug("message_handler: error sending response");
+               }
+       } else {
+               debug("message_handler: pdu is NULL\n");
        }
        coap_delete_pdu(pdu);
 
@@ -1323,10 +1329,7 @@ int main(int argc, char **argv)
        case COAP_PROTO_TCP:
        case COAP_PROTO_TLS:
                tid = coap_send(ctx, &dst, pdu);
-
-               if (tid == COAP_INVALID_TID) {
-                       coap_delete_pdu(pdu);
-               }
+               coap_delete_pdu(pdu);
                break;
        default :
                /* should not enter here */
index 5858923..d5f4bfc 100644 (file)
@@ -513,12 +513,17 @@ int main(int argc, char **argv)
        if (g_operating_status == SERVER_RUNNING) {
                if (quit) {
                        printf("coap-server : set quit flag %d\n", quit);
-                       /* To prevent memory leakage */
-                       if (addr_str != NULL)
+                       while (g_operating_status != SERVER_STOPPED) {
+                               usleep(100000);
+                       }
+                       printf("coap-server : server process has been stopped\n");
+                       if (addr_str) {
                                free(addr_str);
+                       }
                } else {
                        printf("coap-server : another libcoap-server is running\n");
                }
+
                return 0;
        }
 
index 467bf68..2669fc0 100644 (file)
@@ -777,14 +777,29 @@ coap_tid_t coap_send_message_type(coap_context_t *context, const coap_address_t
        coap_pdu_t *response;
        coap_tid_t result = COAP_INVALID_TID;
 
-       if (request) {
-               /* TODO : Considering TCP Case */
-               response = coap_pdu_init(type, 0, request->transport_hdr->udp.id, sizeof(coap_pdu_t));
-               if (response) {
-                       result = coap_send(context, dst, response);
-                       coap_delete_pdu(response);
+       coap_transport_t transport;
+
+       switch (context->protocol) {
+       case COAP_PROTO_UDP:
+       case COAP_PROTO_DTLS:
+               transport = COAP_UDP;
+               if (request) {
+                       response = coap_pdu_init(type, 0, request->transport_hdr->udp.id, sizeof(coap_pdu_t));
+                       if (response) {
+                               result = coap_send(context, dst, response);
+                               coap_delete_pdu(response);
+                       }
                }
+               break;
+       case COAP_PROTO_TCP:
+       case COAP_PROTO_TLS:
+               transport = coap_get_tcp_header_type_from_initbyte(((unsigned char *)request)[0] >> 4);
+               result = COAP_TCP_TID;
+               break;
+       default:
+               break;
        }
+
        return result;
 }
 
@@ -1294,7 +1309,6 @@ coap_pdu_t *coap_new_error_response2(coap_pdu_t *request, unsigned char code, co
        }
 
        /* Now create the response and fill with options and payload data. */
-       /* TODO : Considering TCP Case */
        if (protocol == COAP_PROTO_UDP || protocol == COAP_PROTO_DTLS) {
                response = coap_pdu_init(type, code, request->transport_hdr->udp.id, COAP_MAX_PDU_SIZE);
        } else if (protocol == COAP_PROTO_TCP || protocol == COAP_PROTO_TLS) {
@@ -1694,7 +1708,12 @@ static inline void handle_response(coap_context_t *context, coap_queue_t *sent,
                context->response_handler(context, &rcvd->remote, sent ? sent->pdu : NULL, rcvd->pdu, rcvd->id);
        } else {
                /* send ACK if rcvd is confirmable (i.e. a separate response) */
-               coap_send_ack(context, &rcvd->remote, rcvd->pdu);
+               if (context->protocol == COAP_PROTO_UDP || context->protocol == COAP_PROTO_DTLS) {
+                       coap_send_ack(context, &rcvd->remote, rcvd->pdu);
+               } else {
+                       debug("handle_response : do nothing\n");
+                       /* TODO: CoAP over TCP doesn't have ACK message */
+               }
        }
 }
 
index 70cfd28..332fd3e 100644 (file)
@@ -765,9 +765,10 @@ static void coap_notify_observers(coap_context_t *context, coap_resource_t *r)
                                        warn("coap_check_notify : failed to create TCP response\n");
                                } else {
                                        tid = coap_send(context, &obs->subscriber, tcp_resp);
-                                       if (COAP_INVALID_TID == tid) {
-                                               coap_delete_pdu(tcp_resp);
+                                       if (tid == COAP_INVALID_TID) {
+                                               debug("coap_check_notify: coap_send failed\n");
                                        }
+                                       coap_delete_pdu(tcp_resp);
                                }
                                break;
                        default: