Add CI Adapter to support CoAP over TCP
[platform/upstream/iotivity.git] / resource / csdk / connectivity / samples / linux / sample_main.c
1 /* ****************************************************************
2  *
3  * Copyright 2014 Samsung Electronics All Rights Reserved.
4  *
5  *
6  *
7  * Licensed under the Apache License, Version 2.0 (the "License");
8  * you may not use this file except in compliance with the License.
9  * You may obtain a copy of the License at
10  *
11  *      http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing, software
14  * distributed under the License is distributed on an "AS IS" BASIS,
15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16  * See the License for the specific language governing permissions and
17  * limitations under the License.
18  *
19  ******************************************************************/
20
21 #include <stdio.h>
22 #include <stdlib.h>
23 #include <string.h>
24 #include <sys/stat.h>
25 #include <unistd.h>
26 #include <stdbool.h>
27
28 #include "cacommon.h"
29 #include "cainterface.h"
30 #include "oic_string.h"
31 #ifdef __WITH_DTLS__
32 #include "ocsecurityconfig.h"
33 #endif
34
35 #define MAX_BUF_LEN 1024
36 #define MAX_OPT_LEN 16
37
38 #define PORT_LENGTH 5
39
40 #define SECURE_DEFAULT_PORT 5684
41
42 #define RESOURCE_URI_LENGTH 14
43
44 #define SYSTEM_INVOKE_ERROR 127
45 #define SYSTEM_ERROR -1
46
47 #ifdef WITH_BWT
48 #define BLOCK_SIZE(arg) (1 << ((arg) + 4))
49 #endif
50
51 /**
52  * @def RS_IDENTITY
53  * @brief
54  */
55 #define IDENTITY     ("1111111111111111")
56 /* @def RS_CLIENT_PSK
57  * @brief
58  */
59 #define RS_CLIENT_PSK   ("AAAAAAAAAAAAAAAA")
60
61 int g_received;
62 uint16_t g_local_secure_port = SECURE_DEFAULT_PORT;
63 CATransportAdapter_t g_selected_nw_type = CA_ADAPTER_IP;
64 const char *MESSAGE_TYPE[] = {"CON", "NON", "ACK", "RESET"};
65
66 typedef struct
67 {
68     char ipAddress[CA_IPADDR_SIZE];
69     uint16_t port;
70 } addressSet_t;
71
72 char get_menu();
73 void process();
74 CAResult_t get_network_type();
75 CAResult_t get_input_data(char *buf, int32_t length);
76
77 bool select_payload_type();
78 CAPayload_t get_binary_payload(size_t *payloadLength);
79 bool read_file(const char* name, CAPayload_t* bytes, size_t* length);
80 void create_file(CAPayload_t bytes, size_t length);
81
82 void start_listening_server();
83 void start_discovery_server();
84 void send_request();
85 void send_request_all();
86 void send_notification();
87 void select_network();
88 void unselect_network();
89 void handle_request_response();
90 void get_network_info();
91 void send_secure_request();
92 #ifdef CI_ADAPTER
93 void create_tcp_connection();
94 #endif
95
96 void request_handler(const CAEndpoint_t *object, const CARequestInfo_t *requestInfo);
97 void response_handler(const CAEndpoint_t *object, const CAResponseInfo_t *responseInfo);
98 void error_handler(const CAEndpoint_t *object, const CAErrorInfo_t* errorInfo);
99 void send_response(const CAEndpoint_t *endpoint, const CAInfo_t *info);
100 void get_resource_uri(char *URI, char *resourceURI, int length);
101 int get_secure_information(CAPayload_t payLoad);
102 bool get_address_set(const char *pAddress, addressSet_t* outAddress);
103 void parsing_coap_uri(const char* uri, addressSet_t* address, CATransportFlags_t *flags);
104 CAHeaderOption_t* get_option_data(CAInfo_t* requestData);
105
106 static CAToken_t g_last_request_token = NULL;
107
108 static const char COAP_PREFIX[] =  "coap://";
109 static const char COAPS_PREFIX[] = "coaps://";
110 static const char COAP_TCP_PREFIX[] =  "coap+tcp://";
111
112 static const uint16_t COAP_PREFIX_LEN = sizeof(COAP_PREFIX) - 1;
113 static const uint16_t COAPS_PREFIX_LEN = sizeof(COAPS_PREFIX) - 1;
114 static const uint16_t COAP_TCP_PREFIX_LEN = sizeof(COAP_TCP_PREFIX) - 1;
115
116 static const char SECURE_INFO_DATA[] =
117                                     "{\"oc\":[{\"href\":\"%s\",\"prop\":{\"rt\":[\"core.led\"],"
118                                      "\"if\":[\"oic.if.baseline\"],\"obs\":1,\"sec\":1,\"port\":"
119                                      "%d}}]}";
120 static const char NORMAL_INFO_DATA[] =
121                                     "{\"oc\":[{\"href\":\"%s\",\"prop\":{\"rt\":[\"core.led\"],"
122                                      "\"if\":[\"oic.if.baseline\"],\"obs\":1}}]}";
123
124 #ifdef __WITH_DTLS__
125 static CADtlsPskCredsBlob_t *pskCredsBlob = NULL;
126
127 void clearDtlsCredentialInfo()
128 {
129     printf("clearDtlsCredentialInfo IN\n");
130     if (pskCredsBlob)
131     {
132         // Initialize sensitive data to zeroes before freeing.
133         if (pskCredsBlob->creds)
134         {
135             memset(pskCredsBlob->creds, 0, sizeof(OCDtlsPskCreds) * (pskCredsBlob->num));
136             free(pskCredsBlob->creds);
137         }
138
139         memset(pskCredsBlob, 0, sizeof(CADtlsPskCredsBlob_t));
140         free(pskCredsBlob);
141         pskCredsBlob = NULL;
142     }
143     printf("clearDtlsCredentialInfo OUT\n");
144 }
145
146 // Internal API. Invoked by CA stack to retrieve credentials from this module
147 void CAGetDtlsPskCredentials(CADtlsPskCredsBlob_t **credInfo)
148 {
149     printf("CAGetDtlsPskCredentials IN\n");
150     if(!credInfo)
151     {
152         printf("Invalid credential container");
153         return;
154     }
155
156     *credInfo = (CADtlsPskCredsBlob_t *)malloc(sizeof(CADtlsPskCredsBlob_t));
157     if (NULL == *credInfo)
158     {
159         printf("Failed to allocate credential blob.");
160         return;
161     }
162
163     size_t credLen = sizeof(OCDtlsPskCreds) * (pskCredsBlob->num);
164     (*credInfo)->creds = (OCDtlsPskCreds *)malloc(credLen);
165     if (NULL == (*credInfo)->creds)
166     {
167         printf("Failed to allocate credentials.");
168         free(*credInfo);
169         *credInfo = NULL;
170         return;
171     }
172
173     memcpy((*credInfo)->identity, pskCredsBlob->identity, DTLS_PSK_ID_LEN);
174     (*credInfo)->num = pskCredsBlob->num;
175     memcpy((*credInfo)->creds, pskCredsBlob->creds, credLen);
176
177     printf("CAGetDtlsPskCredentials OUT\n");
178 }
179
180
181 CAResult_t SetCredentials()
182 {
183     printf("SetCredentials IN\n");
184     pskCredsBlob = (CADtlsPskCredsBlob_t *)calloc(1, sizeof(CADtlsPskCredsBlob_t));
185     if (NULL == pskCredsBlob)
186     {
187         printf("Memory allocation failed!\n");
188         return CA_MEMORY_ALLOC_FAILED;
189      }
190     memcpy(pskCredsBlob->identity, IDENTITY, DTLS_PSK_ID_LEN);
191
192
193     pskCredsBlob->num = 1;
194
195     pskCredsBlob->creds = (OCDtlsPskCreds *)malloc(sizeof(OCDtlsPskCreds) * (pskCredsBlob->num));
196     if (NULL == pskCredsBlob->creds)
197     {
198         printf("Memory allocation failed!\n");
199         free(pskCredsBlob);
200         return CA_MEMORY_ALLOC_FAILED;
201     }
202
203     memcpy(pskCredsBlob->creds[0].id, IDENTITY, DTLS_PSK_ID_LEN);
204     memcpy(pskCredsBlob->creds[0].psk, RS_CLIENT_PSK, DTLS_PSK_PSK_LEN);
205
206     printf("SetCredentials OUT\n");
207     return CA_STATUS_OK;
208 }
209 #endif
210
211 int main()
212 {
213     int ret = system("clear");
214     // shell invoke error: 127, others: -1
215     if (SYSTEM_INVOKE_ERROR == ret || SYSTEM_ERROR == ret)
216     {
217         printf("Terminal Clear Error: %d\n", ret);
218         return -1;
219     }
220
221     printf("=============================================\n");
222     printf("\t\tsample main\n");
223     printf("=============================================\n");
224
225     CAResult_t res = CAInitialize();
226     if (CA_STATUS_OK != res)
227     {
228         printf("CAInitialize fail\n");
229         return -1;
230     }
231
232     /*
233     * Read DTLS PSK credentials from persistent storage and
234     * set in the OC stack.
235     */
236 #ifdef __WITH_DTLS__
237     res = SetCredentials();
238     if (CA_STATUS_OK != res)
239     {
240         printf("SetCredentials failed\n");
241         return -1;
242     }
243
244     res = CARegisterDTLSCredentialsHandler(CAGetDtlsPskCredentials);
245     if (CA_STATUS_OK != res)
246     {
247         printf("Set credential handler fail\n");
248         return -1;
249     }
250 #endif
251
252     // set handler.
253     CARegisterHandler(request_handler, response_handler, error_handler);
254
255     process();
256
257     CADestroyToken(g_last_request_token);
258
259     g_last_request_token = NULL;
260
261     CATerminate();
262 #ifdef __WITH_DTLS__
263     clearDtlsCredentialInfo();
264 #endif
265     return 0;
266 }
267
268 void process()
269 {
270     while (1)
271     {
272         char menu = get_menu();
273
274         switch (menu)
275         {
276             case 'm': // menu
277             case 'M':
278                 break;
279
280             case 'q': // quit
281             case 'Q':
282                 printf("quit..!!\n");
283                 return;
284
285             case 's': // start server
286             case 'S':
287                 start_listening_server();
288                 break;
289
290             case 't': // send request
291             case 'T':
292                 send_request_all();
293                 break;
294
295             case 'c': // start client
296             case 'C':
297                 start_discovery_server();
298                 break;
299
300             case 'r': // send request
301             case 'R':
302                 send_request();
303                 break;
304
305             case 'b': // send notification
306             case 'B':
307                 send_notification();
308                 break;
309
310             case 'n': // select network
311             case 'N':
312                 select_network();
313                 break;
314
315             case 'x': // unselect network
316             case 'X':
317                 unselect_network();
318                 break;
319
320             case 'h': // handle request response
321             case 'H':
322                 handle_request_response();
323                 break;
324
325             case 'w':
326             case 'W':
327                 g_received = 0;
328                 start_discovery_server();
329                 send_secure_request();
330                 while (g_received == 0)
331                 {
332                     sleep(1);
333                     handle_request_response();
334                 }
335                 break;
336
337             case 'z':
338             case 'Z':
339                 start_listening_server();
340                 while (1)
341                 {
342                     sleep(1);
343                     handle_request_response();
344                 }
345                 break;
346
347             case 'g': // get network information
348             case 'G':
349                 get_network_info();
350                 break;
351
352 #ifdef CI_ADAPTER
353             case 'p': // create tcp connection
354             case 'P':
355                 create_tcp_connection();
356                 break;
357 #endif
358
359             default:
360                 printf("not supported menu!!\n");
361                 break;
362         }
363     }
364 }
365
366 void start_listening_server()
367 {
368     printf("start listening server!!\n");
369
370     CAResult_t res = CAStartListeningServer();
371     if (CA_STATUS_OK != res)
372     {
373         printf("start listening server fail, error code : %d\n", res);
374     }
375     else
376     {
377         printf("start listening server success\n");
378     }
379 }
380
381 void start_discovery_server()
382 {
383     printf("start discovery client!!\n");
384
385     CAResult_t res = CAStartDiscoveryServer();
386     if (CA_STATUS_OK != res)
387     {
388         printf("start discovery client fail, error code : %d\n", res);
389     }
390     else
391     {
392         printf("start discovery client success\n");
393     }
394 }
395
396 bool select_payload_type()
397 {
398     char buf[MAX_BUF_LEN]={0};
399     printf("\n=============================================\n");
400     printf("Normal Payload  : 0\nBig Payload   : 1\n");
401     printf("select Payload type : ");
402
403     CAResult_t res = get_input_data(buf, sizeof(buf));
404     if (CA_STATUS_OK != res)
405     {
406         printf("Payload type selection error\n");
407         printf("Default: Using normal Payload\n");
408         return false;
409     }
410
411     return (buf[0] == '1') ? true : false;
412 }
413
414 CAPayload_t get_binary_payload(size_t *payloadLength)
415 {
416     CAPayload_t binaryPayload = NULL;
417     bool result = read_file("sample_input.txt", &binaryPayload, payloadLength);
418     if (false == result)
419     {
420         return NULL;
421     }
422
423     return binaryPayload;
424 }
425
426 void send_request()
427 {
428     CAResult_t res = get_network_type();
429     if (CA_STATUS_OK != res)
430     {
431         return;
432     }
433
434     printf("Do you want to send secure request ?.... enter (0/1): ");
435
436     char secureRequest[MAX_BUF_LEN] = {0};
437     if (CA_STATUS_OK != get_input_data(secureRequest, MAX_BUF_LEN))
438     {
439         return;
440     }
441
442     if (strcmp(secureRequest, "1") == 0)
443     {
444         printf("Enter the URI like below....\n");
445         printf("coaps://10.11.12.13:4545/resource_uri ( for IP secure)\n");
446     }
447     else if (strcmp(secureRequest, "0") == 0)
448     {
449         printf("Enter the URI like below....\n");
450         printf("coap://10.11.12.13:4545/resource_uri ( for IP )\n");
451         printf("coap://10:11:12:13:45:45/resource_uri ( for BT )\n");
452 #ifdef CI_ADAPTER
453         printf("coap+tcp://10:11:12:13:45:45/resource_uri ( for CI )\n");
454 #endif
455     }
456     else
457     {
458         printf("Input data is wrong value\n");
459         return;
460     }
461
462     char uri[MAX_BUF_LEN] = {'\0'};
463     if (CA_STATUS_OK != get_input_data(uri, MAX_BUF_LEN))
464     {
465         return;
466     }
467
468     // create remote endpoint
469     CAEndpoint_t *endpoint = NULL;
470     CATransportFlags_t flags;
471
472     printf("URI : %s\n", uri);
473     addressSet_t address = {{}, 0};
474     parsing_coap_uri(uri, &address, &flags);
475
476     res = CACreateEndpoint(flags, g_selected_nw_type,
477                            (const char*)address.ipAddress, address.port, &endpoint);
478     if (CA_STATUS_OK != res || !endpoint)
479     {
480         printf("Failed to create remote endpoint, error code : %d\n", res);
481         return;
482     }
483
484     printf("\n=============================================\n");
485     printf("0:CON, 1:NON\n");
486     printf("select message type : ");
487
488     char buf[MAX_BUF_LEN] = { 0 };
489     if (CA_STATUS_OK != get_input_data(buf, MAX_BUF_LEN))
490     {
491         CADestroyEndpoint(endpoint);
492         return;
493     }
494
495     CAMessageType_t msgType = (buf[0] == '1') ? 1 : 0;
496
497     // create token
498     CAToken_t token = NULL;
499     uint8_t tokenLength = CA_MAX_TOKEN_LEN;
500
501     res = CAGenerateToken(&token, tokenLength);
502     if ((CA_STATUS_OK != res) || (!token))
503     {
504         printf("Token generate error, error code : %d\n", res);
505         CADestroyEndpoint(endpoint);
506         return;
507     }
508
509     printf("Generated token %s\n", token);
510
511     // extract relative resourceuri from give uri
512     char resourceURI[RESOURCE_URI_LENGTH + 1] = {0};
513     get_resource_uri(uri, resourceURI, RESOURCE_URI_LENGTH);
514     printf("resourceURI : %s\n", resourceURI);
515
516     // create request data
517     CAInfo_t requestData = { .type = msgType,
518                              .messageId = 0,
519                              .token = token,
520                              .tokenLength = tokenLength,
521                              .options = NULL,
522                              .numOptions = 0,
523                              .payload = NULL,
524                              .payloadSize = 0,
525                              .resourceUri = (CAURI_t)resourceURI };
526
527     if (strcmp(secureRequest, "1") == 0)
528     {
529         size_t length = sizeof(SECURE_INFO_DATA) + strlen(resourceURI);
530         requestData.payload = (CAPayload_t) calloc(length,  sizeof(char));
531         if (NULL == requestData.payload)
532         {
533             printf("Memory allocation fail\n");
534             CADestroyEndpoint(endpoint);
535             CADestroyToken(token);
536             return;
537         }
538         snprintf((char *) requestData.payload, length, SECURE_INFO_DATA,
539                  (const char *) resourceURI, g_local_secure_port);
540         requestData.payloadSize = length;
541     }
542     else
543     {
544         bool useBigPayload = select_payload_type();
545         if (useBigPayload)
546         {
547             size_t payloadLength = 0;
548             CAPayload_t binaryPayload = get_binary_payload(&payloadLength);
549             if (!binaryPayload)
550             {
551                 free(binaryPayload);
552                 CADestroyToken(token);
553                 CADestroyEndpoint(endpoint);
554                 return;
555             }
556
557             requestData.payload = (CAPayload_t) malloc(payloadLength);
558             if (NULL == requestData.payload)
559             {
560                 printf("Memory allocation failed!");
561                 free(binaryPayload);
562                 CADestroyToken(token);
563                 CADestroyEndpoint(endpoint);
564                 return;
565             }
566             memcpy(requestData.payload, binaryPayload, payloadLength);
567             requestData.payloadSize = payloadLength;
568
569             // memory free
570             free(binaryPayload);
571         }
572         else
573         {
574             size_t length = sizeof(NORMAL_INFO_DATA) + strlen(resourceURI);
575             requestData.payload = (CAPayload_t) calloc(length, sizeof(char));
576             if (NULL == requestData.payload)
577             {
578                 printf("Memory allocation fail\n");
579                 CADestroyEndpoint(endpoint);
580                 CADestroyToken(token);
581                 return;
582             }
583             snprintf((char *) requestData.payload, length, NORMAL_INFO_DATA,
584                      (const char *) resourceURI);
585             requestData.payloadSize = length;
586         }
587     }
588
589     CAHeaderOption_t* headerOpt = get_option_data(&requestData);
590
591     CARequestInfo_t requestInfo = { .method = CA_GET,
592                                     .info = requestData,
593                                     .isMulticast = false };
594
595     // send request
596     res = CASendRequest(endpoint, &requestInfo);
597     if (CA_STATUS_OK != res)
598     {
599         printf("Could not send request : %d\n", res);
600     }
601
602     if (headerOpt)
603     {
604         free(headerOpt);
605     }
606
607     //destroy token
608     CADestroyToken(token);
609     // destroy remote endpoint
610     CADestroyEndpoint(endpoint);
611     free(requestData.payload);
612
613     printf("=============================================\n");
614 }
615
616 void send_secure_request()
617 {
618     char uri[MAX_BUF_LEN];
619     char ipv4addr[CA_IPADDR_SIZE];
620
621     printf("\n=============================================\n");
622     printf("Enter IPv4 address of the source hosting secure resource (Ex: 11.12.13.14)\n");
623
624     if (CA_STATUS_OK != get_input_data(ipv4addr, CA_IPADDR_SIZE))
625     {
626         return;
627     }
628     snprintf(uri, MAX_BUF_LEN, "%s%s:5684/a/light", COAPS_PREFIX, ipv4addr);
629
630     // create remote endpoint
631     CAEndpoint_t *endpoint = NULL;
632     CAResult_t res = CACreateEndpoint(0, CA_ADAPTER_IP, ipv4addr, SECURE_DEFAULT_PORT, &endpoint);
633     if (CA_STATUS_OK != res)
634     {
635         printf("Failed to create remote endpoint, error code: %d\n", res);
636         goto exit;
637     }
638
639     // create token
640     CAToken_t token = NULL;
641     uint8_t tokenLength = CA_MAX_TOKEN_LEN;
642
643     res = CAGenerateToken(&token, tokenLength);
644     if (CA_STATUS_OK != res)
645     {
646         printf("Token generate error, error code : %d\n", res);
647         goto exit;
648     }
649
650     printf("Generated token %s\n", token);
651
652     // create request data
653     CAInfo_t requestData = { .type = CA_MSG_NONCONFIRM,
654                              .messageId = 0,
655                              .token = token,
656                              .tokenLength = tokenLength,
657                              .options = NULL,
658                              .numOptions = 0,
659                              .payload = NULL,
660                              .payloadSize = 0,
661                              .resourceUri = NULL };
662
663     CARequestInfo_t requestInfo = { .method = CA_GET,
664                                     .info = requestData,
665                                     .isMulticast = false };
666
667     // send request
668     CASendRequest(endpoint, &requestInfo);
669
670 exit:
671     // cleanup
672     CADestroyToken(token);
673     CADestroyEndpoint(endpoint);
674     printf("=============================================\n");
675 }
676
677
678 void send_request_all()
679 {
680     CAResult_t res = get_network_type();
681     if (CA_STATUS_OK != res)
682     {
683         return;
684     }
685
686     printf("\n=============================================\n");
687     printf("ex) /a/light\n");
688     printf("resource uri : ");
689
690     char resourceURI[MAX_BUF_LEN] = { 0 };
691     if (CA_STATUS_OK != get_input_data(resourceURI, MAX_BUF_LEN))
692     {
693         return;
694     }
695
696     // create remote endpoint
697     CAEndpoint_t *group = NULL;
698     res = CACreateEndpoint(CA_IPV4, g_selected_nw_type, NULL, 0, &group);
699     if (CA_STATUS_OK != res)
700     {
701         printf("Create remote endpoint error, error code: %d\n", res);
702         return;
703     }
704
705     // create token
706     CAToken_t token = NULL;
707     uint8_t tokenLength = CA_MAX_TOKEN_LEN;
708
709     res = CAGenerateToken(&token, tokenLength);
710     if ((CA_STATUS_OK != res) || (!token))
711     {
712         printf("Token generate error!!\n");
713         CADestroyEndpoint(group);
714         return;
715     }
716
717     printf("generated token %s\n", token);
718
719     // create request data
720     CAPayload_t payload = (CAPayload_t) "TempJsonPayload";
721     size_t payloadSize = strlen((const char *) payload);
722
723     CAInfo_t requestData = { .type = CA_MSG_NONCONFIRM,
724                              .messageId = 0,
725                              .token = token,
726                              .tokenLength = tokenLength,
727                              .options = NULL,
728                              .numOptions = 0,
729                              .payload = payload,
730                              .payloadSize = payloadSize,
731                              .resourceUri = (CAURI_t) resourceURI };
732
733     CARequestInfo_t requestInfo = { .method = CA_GET,
734                                     .info = requestData,
735                                     .isMulticast = true };
736
737     CAHeaderOption_t* headerOpt = get_option_data(&requestData);
738
739     // send request
740     res = CASendRequest(group, &requestInfo);
741     if (CA_STATUS_OK != res)
742     {
743         printf("Could not send request to all\n");
744         CADestroyToken(token);
745     }
746     else
747     {
748         CADestroyToken(g_last_request_token);
749         g_last_request_token = token;
750     }
751
752     if (headerOpt)
753     {
754         free(headerOpt);
755     }
756
757     // destroy remote endpoint
758     CADestroyEndpoint(group);
759
760     printf("=============================================\n");
761 }
762
763 void send_notification()
764 {
765     CAResult_t res = get_network_type();
766     if (CA_STATUS_OK != res)
767     {
768         return;
769     }
770
771     printf("\n=============================================\n");
772     printf("Enter the URI like below....\n");
773     printf("coap://10.11.12.13:4545/resource_uri ( for IP )\n");
774     printf("coap://10:11:12:13:45:45/resource_uri ( for BT )\n");
775 #ifdef CI_ADAPTER
776     printf("coap+tcp://10:11:12:13:45:45/resource_uri ( for CI )\n");
777 #endif
778     printf("uri : ");
779
780     char uri[MAX_BUF_LEN] = { 0 };
781     if (CA_STATUS_OK != get_input_data(uri, MAX_BUF_LEN))
782     {
783         return;
784     }
785
786     printf("\n=============================================\n");
787     printf("\tselect message type\n");
788     printf("CON     : 0\n");
789     printf("NON     : 1\n");
790     printf("ACK     : 2\n");
791     printf("RESET   : 3\n");
792     printf("select : ");
793
794     char messageTypeBuf[MAX_BUF_LEN] = { 0 };
795     if (CA_STATUS_OK != get_input_data(messageTypeBuf, MAX_BUF_LEN))
796     {
797         return;
798     }
799
800     int messageType = messageTypeBuf[0] - '0';
801
802     CATransportFlags_t flags;
803     addressSet_t address = {{}, 0};
804     parsing_coap_uri(uri, &address, &flags);
805
806     // create remote endpoint
807     CAEndpoint_t *endpoint = NULL;
808     res = CACreateEndpoint(flags, g_selected_nw_type, address.ipAddress, address.port, &endpoint);
809     if (CA_STATUS_OK != res)
810     {
811         printf("Create remote endpoint error, error code: %d\n", res);
812         return;
813     }
814
815     // create token
816     CAToken_t token = NULL;
817     uint8_t tokenLength = CA_MAX_TOKEN_LEN;
818
819     res = CAGenerateToken(&token, tokenLength);
820     if ((CA_STATUS_OK != res) || (!token))
821     {
822         printf("Token generate error!!\n");
823         CADestroyEndpoint(endpoint);
824         return;
825     }
826
827     printf("Generated token %s\n", token);
828
829     // create response data
830     CAPayload_t payload = (CAPayload_t) "TempNotificationData";
831     size_t payloadSize = strlen((const char *) payload);
832
833     CAInfo_t respondData = { .type = messageType,
834                              .messageId = 0,
835                              .token = token,
836                              .tokenLength = tokenLength,
837                              .options = NULL,
838                              .numOptions = 0,
839                              .payload = payload,
840                              .payloadSize = payloadSize,
841                              .resourceUri = (CAURI_t)uri };
842
843     CAResponseInfo_t responseInfo = { .result = CA_CONTENT,
844                                       .info = respondData };
845
846     // send request
847     res = CASendNotification(endpoint, &responseInfo);
848     if (CA_STATUS_OK != res)
849     {
850         printf("Send notification error, error code: %d\n", res);
851     }
852     else
853     {
854         printf("Send notification success\n");
855     }
856
857     // destroy token
858     CADestroyToken(token);
859     // destroy remote endpoint
860     CADestroyEndpoint(endpoint);
861
862     printf("\n=============================================\n");
863 }
864
865 void select_network()
866 {
867     printf("\n=============================================\n");
868     printf("\tselect network\n");
869     printf("IP     : 0\n");
870     printf("GATT   : 1\n");
871     printf("RFCOMM : 2\n");
872 #ifdef CI_ADAPTER
873     printf("CI     : 5\n");
874 #endif
875     printf("select : ");
876
877     char buf[MAX_BUF_LEN] = { 0 };
878     if (CA_STATUS_OK != get_input_data(buf, MAX_BUF_LEN))
879     {
880         return;
881     }
882
883     int number = buf[0] - '0';
884
885     if (number < 0 || number > 5)
886     {
887         printf("Invalid network type\n");
888         return;
889     }
890
891     CAResult_t res = CASelectNetwork(1 << number);
892     if (CA_STATUS_OK != res)
893     {
894         printf("Select network error\n");
895     }
896     else
897     {
898         printf("Select network success\n");
899     }
900
901     printf("=============================================\n");
902 }
903
904 void unselect_network()
905 {
906     printf("\n=============================================\n");
907     printf("\tunselect enabled network\n");
908     printf("IP     : 0\n");
909     printf("GATT   : 1\n");
910     printf("RFCOMM : 2\n");
911 #ifdef CI_ADAPTER
912     printf("CI     : 5\n");
913 #endif
914     printf("select : ");
915
916     char buf[MAX_BUF_LEN] = { 0 };
917     if (CA_STATUS_OK != get_input_data(buf, MAX_BUF_LEN))
918     {
919         return;
920     }
921
922     int number = buf[0] - '0';
923
924     if (number < 0 || number > 5)
925     {
926         printf("Invalid network type\n");
927         return;
928     }
929
930     CAResult_t res = CAUnSelectNetwork(1 << number);
931     if (CA_STATUS_OK != res)
932     {
933         printf("Unselect network error\n");
934     }
935     else
936     {
937         printf("Unselect network success\n");
938     }
939
940     printf("=============================================\n");
941 }
942
943 char get_menu()
944 {
945     printf("\n=============================================\n");
946     printf("\t\tMenu\n");
947     printf("\ts : start server\n");
948     printf("\tc : start client\n");
949     printf("\tr : send request\n");
950     printf("\tt : send request to all\n");
951     printf("\tb : send notification\n");
952     printf("\tn : select network\n");
953     printf("\tx : unselect network\n");
954     printf("\tg : get network information\n");
955     printf("\th : handle request response\n");
956     printf("\tz : run static server\n");
957     printf("\tw : send secure request\n");
958 #ifdef CI_ADAPTER
959     printf("\tp : create tcp connection\n");
960 #endif
961     printf("\tq : quit\n");
962     printf("=============================================\n");
963     printf("select : ");
964
965     char buf[MAX_BUF_LEN] = { 0 };
966     if (CA_STATUS_OK != get_input_data(buf, MAX_BUF_LEN))
967     {
968         printf("Failed to get input data\n");
969     }
970
971     return buf[0];
972 }
973
974 void handle_request_response()
975 {
976     printf("Handle_request_response\n");
977
978     CAResult_t res = CAHandleRequestResponse();
979     if (CA_STATUS_OK != res)
980     {
981         printf("Handle request error, error code: %d\n", res);
982     }
983     else
984     {
985         printf("Handle request success\n");
986     }
987 }
988
989 void get_network_info()
990 {
991     CAEndpoint_t *tempInfo = NULL;
992     uint32_t tempSize = 0;
993
994     CAResult_t res = CAGetNetworkInformation(&tempInfo, &tempSize);
995     if (CA_STATUS_OK != res || NULL == tempInfo || 0 >= tempSize)
996     {
997         printf("Network not connected\n");
998         free(tempInfo);
999         return;
1000     }
1001
1002     printf("################## Network Information #######################\n");
1003     printf("Network info total size is %d\n\n", tempSize);
1004
1005     for (uint32_t index = 0; index  < tempSize; index++)
1006     {
1007         printf("Type: %d\n", tempInfo[index].adapter);
1008         printf("Address: %s\n", tempInfo[index].addr);
1009         if (CA_ADAPTER_IP == tempInfo[index].adapter)
1010         {
1011             printf("Port: %d\n", tempInfo[index].port);
1012         }
1013         printf("Secured: %s\n\n", (tempInfo[index].flags & CA_SECURE) ? "true" : "false");
1014
1015         if (tempInfo[index].flags & CA_SECURE)
1016         {
1017             g_local_secure_port = tempInfo[index].port;
1018             printf("Secured: in global %d\n\n", g_local_secure_port);
1019         }
1020     }
1021
1022     free(tempInfo);
1023     printf("##############################################################");
1024 }
1025
1026 void request_handler(const CAEndpoint_t *object, const CARequestInfo_t *requestInfo)
1027 {
1028     if (NULL == object || NULL == requestInfo)
1029     {
1030         printf("Input parameter is NULL\n");
1031         return;
1032     }
1033
1034     if ((NULL != g_last_request_token) && (NULL != requestInfo->info.token)
1035         && (memcmp(g_last_request_token, requestInfo->info.token,
1036                    CA_MAX_TOKEN_LEN) == 0))
1037     {
1038         printf("token is same. received request of it's own. skip.. \n");
1039         return;
1040     }
1041
1042     printf("##########received request from remote device #############\n");
1043     if (CA_ADAPTER_IP == object->adapter)
1044     {
1045         printf("Remote Address: %s Port: %d secured:%d\n", object->addr,
1046                object->port, object->flags & CA_SECURE);
1047     }
1048     else
1049     {
1050         printf("Remote Address: %s \n", object->addr);
1051     }
1052     printf("Data: %s\n", requestInfo->info.payload);
1053     printf("Message type: %s\n", MESSAGE_TYPE[requestInfo->info.type]);
1054
1055     if (requestInfo->info.options)
1056     {
1057         uint32_t len = requestInfo->info.numOptions;
1058         uint32_t i;
1059         for (i = 0; i < len; i++)
1060         {
1061             printf("Option %d\n", i + 1);
1062             printf("ID : %d\n", requestInfo->info.options[i].optionID);
1063             printf("Data[%d]: %s\n", requestInfo->info.options[i].optionLength,
1064                    requestInfo->info.options[i].optionData);
1065         }
1066     }
1067     printf("############################################################\n");
1068
1069     //Check if this has secure communication information
1070     if (requestInfo->info.payload &&
1071             (CA_ADAPTER_IP == object->adapter))
1072     {
1073         int securePort = get_secure_information(requestInfo->info.payload);
1074         if (0 < securePort) //Set the remote endpoint secure details and send response
1075         {
1076             printf("This is secure resource...\n");
1077
1078             CAEndpoint_t *endpoint = NULL;
1079             if (CA_STATUS_OK != CACreateEndpoint(0, object->adapter, object->addr,
1080                                                  object->port, &endpoint))
1081             {
1082                 printf("Failed to create duplicate of remote endpoint!\n");
1083                 return;
1084             }
1085             endpoint->flags = CA_SECURE;
1086             object = endpoint;
1087         }
1088     }
1089
1090 #ifdef WITH_BWT
1091     // if received message is bulk data, create output file
1092     if ((requestInfo->info.payload) &&
1093             (requestInfo->info.payloadSize > BLOCK_SIZE(CA_DEFAULT_BLOCK_SIZE)))
1094     {
1095         create_file(requestInfo->info.payload, requestInfo->info.payloadSize);
1096     }
1097 #endif
1098
1099     printf("Send response with URI\n");
1100     send_response(object, &requestInfo->info);
1101
1102     g_received = 1;
1103 }
1104
1105 void response_handler(const CAEndpoint_t *object, const CAResponseInfo_t *responseInfo)
1106 {
1107     printf("##########Received response from remote device #############\n");
1108     if (CA_ADAPTER_IP == object->adapter)
1109     {
1110         printf("Remote Address: %s Port: %d secured:%d\n", object->addr,
1111                object->port, object->flags & CA_SECURE);
1112     }
1113     else
1114     {
1115         printf("Remote Address: %s \n", object->addr);
1116     }
1117     printf("response result : %d\n", responseInfo->result);
1118     printf("Data: %s\n", responseInfo->info.payload);
1119     printf("Message type: %s\n", MESSAGE_TYPE[responseInfo->info.type]);
1120     printf("Token: %s\n", responseInfo->info.token);
1121     if (responseInfo->info.options)
1122     {
1123         uint32_t len = responseInfo->info.numOptions;
1124         uint32_t i;
1125         for (i = 0; i < len; i++)
1126         {
1127             printf("Option %d\n", i + 1);
1128             printf("ID : %d\n", responseInfo->info.options[i].optionID);
1129             printf("Data[%d]: %s\n", responseInfo->info.options[i].optionLength,
1130                    responseInfo->info.options[i].optionData);
1131         }
1132     }
1133     printf("############################################################\n");
1134     g_received = 1;
1135
1136     //Check if this has secure communication information
1137     if (responseInfo->info.payload)
1138     {
1139         int securePort = get_secure_information(responseInfo->info.payload);
1140         if (0 < securePort) //Set the remote endpoint secure details and send response
1141         {
1142             printf("This is secure resource...\n");
1143         }
1144     }
1145
1146 #ifdef WITH_BWT
1147     // if received message is bulk data, create output file
1148     if ((responseInfo->info.payload) &&
1149             (responseInfo->info.payloadSize > BLOCK_SIZE(CA_DEFAULT_BLOCK_SIZE)))
1150     {
1151         create_file(responseInfo->info.payload, responseInfo->info.payloadSize);
1152     }
1153 #endif
1154 }
1155
1156 void error_handler(const CAEndpoint_t *rep, const CAErrorInfo_t* errorInfo)
1157 {
1158     (void)rep;
1159     printf("+++++++++++++++++++++++++++++++++++ErrorInfo+++++++++++++++++++++++++++++++++++\n");
1160
1161     if(errorInfo)
1162     {
1163         const CAInfo_t *info = &errorInfo->info;
1164         printf("Error Handler, ErrorInfo :\n");
1165         printf("Error Handler result    : %d\n", errorInfo->result);
1166         printf("Error Handler token     : %s\n", info->token);
1167         printf("Error Handler messageId : %d\n", (uint16_t) info->messageId);
1168         printf("Error Handler type      : %d\n", info->type);
1169         printf("Error Handler resourceUri : %s\n", info->resourceUri);
1170         printf("Error Handler payload   : %s\n", info->payload);
1171
1172         if(CA_ADAPTER_NOT_ENABLED == errorInfo->result)
1173         {
1174             printf("CA_ADAPTER_NOT_ENABLED, enable the adapter\n");
1175         }
1176         else if(CA_SEND_FAILED == errorInfo->result)
1177         {
1178             printf("CA_SEND_FAILED, unable to send the message, check parameters\n");
1179         }
1180         else if(CA_MEMORY_ALLOC_FAILED == errorInfo->result)
1181         {
1182             printf("CA_MEMORY_ALLOC_FAILED, insufficient memory\n");
1183         }
1184         else if(CA_SOCKET_OPERATION_FAILED == errorInfo->result)
1185         {
1186             printf("CA_SOCKET_OPERATION_FAILED, socket operation failed\n");
1187         }
1188         else if(CA_STATUS_FAILED == errorInfo->result)
1189         {
1190             printf("CA_STATUS_FAILED, message could not be delivered, internal error\n");
1191         }
1192     }
1193     printf("++++++++++++++++++++++++++++++++End of ErrorInfo++++++++++++++++++++++++++++++++\n");
1194
1195     return;
1196 }
1197
1198 void send_response(const CAEndpoint_t *endpoint, const CAInfo_t *info)
1199 {
1200     printf("entering send_response\n");
1201
1202     printf("\n=============================================\n");
1203     printf("\tselect message type\n");
1204     printf("CON     : 0\n");
1205     printf("NON     : 1\n");
1206     printf("ACK     : 2\n");
1207     printf("RESET   : 3\n");
1208     printf("select : ");
1209
1210     char buf[MAX_BUF_LEN] = { 0 };
1211     if (CA_STATUS_OK != get_input_data(buf, MAX_BUF_LEN))
1212     {
1213         return;
1214     }
1215
1216     int messageType = buf[0] - '0';
1217     if (0 > messageType || 3 < messageType)
1218     {
1219         printf("Invalid message type\n");
1220         return;
1221     }
1222
1223     int responseCode = 0 ;
1224     char responseCodeBuf[MAX_BUF_LEN] = { 0 };
1225     if (CA_MSG_RESET != messageType)
1226     {
1227         printf("\n=============================================\n");
1228         printf("\tselect response code\n");
1229         printf("EMPTY                    :   0\n");
1230         printf("SUCCESS                  : 200\n");
1231         printf("CREATED                  : 201\n");
1232         printf("DELETED                  : 202\n");
1233         printf("VALID                    : 203\n");
1234         printf("CHANGED                  : 204\n");
1235         printf("CONTENT                  : 205\n");
1236         printf("BAD_REQ                  : 400\n");
1237         printf("BAD_OPT                  : 402\n");
1238         printf("NOT_FOUND                : 404\n");
1239         printf("INTERNAL_SERVER_ERROR    : 500\n");
1240         printf("RETRANSMIT_TIMEOUT       : 504\n");
1241         printf("select : ");
1242
1243         if (CA_STATUS_OK != get_input_data(responseCodeBuf, MAX_BUF_LEN))
1244         {
1245             return;
1246         }
1247         responseCode = atoi(responseCodeBuf);
1248     }
1249
1250     // create response data
1251     uint16_t messageId = (info != NULL) ? info->messageId : 0;
1252     CAURI_t resourceUri = (info != NULL) ? info->resourceUri : 0;
1253
1254     CAInfo_t responseData = { .type = messageType,
1255                               .messageId = messageId,
1256                               .token = NULL,
1257                               .tokenLength = 0,
1258                               .options = NULL,
1259                               .numOptions = 0,
1260                               .payload = NULL,
1261                               .payloadSize = 0,
1262                               .resourceUri = resourceUri };
1263
1264     if(CA_MSG_RESET != messageType)
1265     {
1266         responseData.token = (info != NULL) ? info->token : NULL;
1267         responseData.tokenLength = (info != NULL) ? info->tokenLength : 0;
1268
1269         if (endpoint->flags & CA_SECURE)
1270         {
1271             if(!responseData.resourceUri)
1272             {
1273                printf("resourceUri not available in SECURE\n");
1274                return;
1275             }
1276             printf("Sending response on secure communication\n");
1277
1278             uint32_t length = sizeof(SECURE_INFO_DATA) + strlen(responseData.resourceUri);
1279             responseData.payload = (CAPayload_t) calloc(length,  sizeof(char));
1280             if (NULL == responseData.payload)
1281             {
1282                 printf("Memory allocation fail\n");
1283                 return;
1284             }
1285             snprintf((char *) responseData.payload, length, SECURE_INFO_DATA,
1286                      (const char *) responseData.resourceUri, g_local_secure_port);
1287             responseData.payloadSize = length;
1288         }
1289         else
1290         {
1291             printf("Sending response on non-secure communication\n");
1292
1293             bool useBigPayload = select_payload_type();
1294             if (useBigPayload)
1295             {
1296                 size_t payloadLength = 0;
1297                 CAPayload_t binaryPayload = get_binary_payload(&payloadLength);
1298                 if (NULL == binaryPayload)
1299                 {
1300                     free(binaryPayload);
1301                     return;
1302                 }
1303
1304                 responseData.payload = (CAPayload_t) malloc(payloadLength);
1305                 if (NULL == responseData.payload)
1306                 {
1307                     printf("Memory allocation failed!");
1308                     free(binaryPayload);
1309                     return;
1310                 }
1311                 memcpy(responseData.payload, binaryPayload, payloadLength);
1312                 responseData.payloadSize = payloadLength;
1313
1314                 // memory free
1315                 free(binaryPayload);
1316             }
1317             else
1318             {
1319                 if(!responseData.resourceUri)
1320                 {
1321                    printf("resourceUri not available in NON-SECURE\n");
1322                    return;
1323                 }
1324                 uint32_t length = sizeof(NORMAL_INFO_DATA) + strlen(responseData.resourceUri);
1325                 responseData.payload = (CAPayload_t) calloc(length, sizeof(char));
1326                 if (NULL == responseData.payload)
1327                 {
1328                     printf("Memory allocation fail\n");
1329                     return;
1330                 }
1331                 snprintf((char *) responseData.payload, length, NORMAL_INFO_DATA,
1332                          (const char *) responseData.resourceUri);
1333                 responseData.payloadSize = length;
1334             }
1335         }
1336     }
1337
1338     CAResponseInfo_t responseInfo = { .result = responseCode,
1339                                       .info = responseData };
1340
1341     // send response (transportType from remoteEndpoint of request Info)
1342     CAResult_t res = CASendResponse(endpoint, &responseInfo);
1343     if (CA_STATUS_OK != res)
1344     {
1345         printf("Send response error\n");
1346     }
1347     else
1348     {
1349         printf("Send response success\n");
1350     }
1351
1352     if (responseData.payload)
1353     {
1354         free(responseData.payload);
1355     }
1356
1357     printf("=============================================\n");
1358 }
1359
1360 int get_secure_information(CAPayload_t payLoad)
1361 {
1362     printf("Entering get_secure_information\n");
1363
1364     if (!payLoad)
1365     {
1366         printf("Payload is NULL\n");
1367         return -1;
1368     }
1369
1370     char *subString = NULL;
1371     if (NULL == (subString = strstr((const char *) payLoad, "\"sec\":1")))
1372     {
1373         printf("This is not secure resource\n");
1374         return -1;
1375     }
1376
1377     if (NULL == (subString = strstr((const char *) payLoad, "\"port\":")))
1378     {
1379         printf("This secure resource does not have port information\n");
1380         return -1;
1381     }
1382
1383     char *startPos = strstr(subString, ":");
1384     if (!startPos)
1385     {
1386         printf("Parsing failed !\n");
1387         return -1;
1388     }
1389
1390     char *endPos = strstr(startPos, "}");
1391     if (!endPos)
1392     {
1393         printf("Parsing failed !\n");
1394         return -1;
1395     }
1396
1397     char portStr[6] = {0};
1398     OICStrcpyPartial(portStr, sizeof(portStr), startPos + 1, (endPos - 1) - startPos);
1399     printf("secured port is: %s\n", portStr);
1400     return atoi(portStr);
1401 }
1402
1403 void get_resource_uri(char *URI, char *resourceURI, int length)
1404 {
1405     char *startPos = URI;
1406     char *temp = NULL;
1407     if (NULL != (temp = strstr(URI, "://")))
1408     {
1409         startPos = strchr(temp + 3, '/');
1410         if (!startPos)
1411         {
1412             printf("Resource URI is missing\n");
1413             return;
1414         }
1415     }
1416
1417     char *endPos = strchr(startPos, '?');
1418     if (!endPos)
1419     {
1420         endPos = URI + strlen(URI);
1421     }
1422     endPos -= 1;
1423
1424     if (endPos - startPos <= length)
1425     {
1426         OICStrcpyPartial(resourceURI, length, startPos + 1, endPos - startPos);
1427     }
1428
1429     printf("URI: %s, ResourceURI:%s\n", URI, resourceURI);
1430 }
1431
1432 CAResult_t get_network_type()
1433 {
1434     char buf[MAX_BUF_LEN] = { 0 };
1435
1436     printf("\n=============================================\n");
1437     printf("\tselect network type\n");
1438     printf("IP     : 0\n");
1439     printf("GATT   : 1\n");
1440     printf("RFCOMM : 2\n");
1441 #ifdef CI_ADAPTER
1442     printf("CI     : 5\n");
1443 #endif
1444     printf("select : ");
1445
1446     if (CA_STATUS_OK != get_input_data(buf, MAX_BUF_LEN))
1447     {
1448         return CA_NOT_SUPPORTED ;
1449     }
1450
1451     int number = buf[0] - '0';
1452
1453     number = (number < 0 || number > 5) ? 0 : 1 << number;
1454
1455     switch (number)
1456     {
1457         case CA_ADAPTER_IP:
1458         case CA_ADAPTER_GATT_BTLE:
1459         case CA_ADAPTER_RFCOMM_BTEDR:
1460 #ifdef CI_ADAPTER
1461         case CA_ADAPTER_CLOUD_INTERFACE:
1462 #endif
1463             g_selected_nw_type = number;
1464             return CA_STATUS_OK;
1465         default:
1466             return CA_NOT_SUPPORTED;
1467     }
1468 }
1469
1470 CAResult_t get_input_data(char *buf, int32_t length)
1471 {
1472     if (!fgets(buf, length, stdin))
1473     {
1474         printf("fgets error\n");
1475         return CA_STATUS_FAILED;
1476     }
1477
1478     char *p = NULL;
1479     if ( (p = strchr(buf, '\n')) != NULL )
1480     {
1481         *p = '\0';
1482     }
1483
1484     return CA_STATUS_OK;
1485 }
1486
1487 CAHeaderOption_t* get_option_data(CAInfo_t* requestData)
1488 {
1489     char optionNumBuf[MAX_BUF_LEN] = { 0 };
1490     char optionData[MAX_OPT_LEN] = { 0 } ;
1491
1492     printf("Option Num : ");
1493     if (CA_STATUS_OK != get_input_data(optionNumBuf, MAX_BUF_LEN))
1494     {
1495         return NULL;
1496     }
1497     int optionNum = atoi(optionNumBuf);
1498
1499     CAHeaderOption_t * headerOpt = NULL;
1500     if (0 >= optionNum)
1501     {
1502         printf("there is no headerOption!\n");
1503         return NULL;
1504     }
1505     else if (optionNum > MAX_OPT_LEN)
1506     {
1507         printf("Too many header options!\n");
1508         return NULL;
1509     }
1510     else
1511     {
1512         headerOpt = (CAHeaderOption_t *)calloc(optionNum, sizeof(CAHeaderOption_t));
1513         if (NULL == headerOpt)
1514         {
1515             printf("Memory allocation failed!\n");
1516             return NULL;
1517         }
1518
1519         int i;
1520         for (i = 0; i < optionNum; i++)
1521         {
1522             char getOptionID[MAX_BUF_LEN] = { 0 } ;
1523
1524             printf("[%d] Option ID : ", i + 1);
1525             if (CA_STATUS_OK != get_input_data(getOptionID, MAX_BUF_LEN))
1526             {
1527                 free(headerOpt);
1528                 return NULL;
1529             }
1530             int optionID = atoi(getOptionID);
1531             headerOpt[i].optionID = optionID;
1532
1533             printf("[%d] Option Data : ", i + 1);
1534             if (CA_STATUS_OK != get_input_data(optionData, MAX_OPT_LEN))
1535             {
1536                 free(headerOpt);
1537                 return NULL;
1538             }
1539
1540             OICStrcpy(headerOpt[i].optionData, sizeof(headerOpt[i].optionData), optionData);
1541
1542             headerOpt[i].optionLength = (uint16_t) strlen(optionData);
1543         }
1544         requestData->numOptions = optionNum;
1545         requestData->options = headerOpt;
1546     }
1547     return headerOpt;
1548 }
1549
1550 void parsing_coap_uri(const char* uri, addressSet_t* address, CATransportFlags_t *flags)
1551 {
1552     if (NULL == uri)
1553     {
1554         printf("parameter is null\n");
1555         return;
1556     }
1557
1558     // parse uri
1559     // #1. check prefix
1560     uint8_t startIndex = 0;
1561     if (strncmp(COAPS_PREFIX, uri, COAPS_PREFIX_LEN) == 0)
1562     {
1563         printf("uri has '%s' prefix\n", COAPS_PREFIX);
1564         startIndex = COAPS_PREFIX_LEN;
1565         *flags = CA_SECURE;
1566     }
1567     else if (strncmp(COAP_PREFIX, uri, COAP_PREFIX_LEN) == 0)
1568     {
1569         printf("uri has '%s' prefix\n", COAP_PREFIX);
1570         startIndex = COAP_PREFIX_LEN;
1571         *flags = CA_IPV4;
1572     }
1573 #ifdef CI_ADAPTER
1574     else if (strncmp(COAP_TCP_PREFIX, uri, COAP_TCP_PREFIX_LEN) == 0)
1575     {
1576         printf("uri has '%s' prefix\n", COAP_TCP_PREFIX);
1577         startIndex = COAP_TCP_PREFIX_LEN;
1578         *flags = CA_IPV4_TCP;
1579     }
1580 #endif
1581
1582     // #2. copy uri for parse
1583     int32_t len = strlen(uri) - startIndex;
1584
1585     if (len <= 0)
1586     {
1587         printf("uri length is 0!\n");
1588         return;
1589     }
1590
1591     char *cloneUri = (char *) calloc(len + 1, sizeof(char));
1592     if (NULL == cloneUri)
1593     {
1594         printf("Out of memory\n");
1595         return;
1596     }
1597
1598     memcpy(cloneUri, &uri[startIndex], sizeof(char) * len);
1599     cloneUri[len] = '\0';
1600
1601     char *pAddress = cloneUri;
1602     printf("pAddress : %s\n", pAddress);
1603
1604     if (!get_address_set(pAddress, address))
1605     {
1606         printf("address parse error\n");
1607
1608         free(cloneUri);
1609         return;
1610     }
1611     free(cloneUri);
1612     return;
1613 }
1614
1615 bool get_address_set(const char *pAddress, addressSet_t* outAddress)
1616 {
1617     if (NULL == pAddress)
1618     {
1619         printf("parameter is null !\n");
1620         return false;
1621     }
1622
1623     size_t len = strlen(pAddress);
1624     bool isIp = false;
1625     size_t ipLen = 0;
1626
1627     for (size_t i = 0; i < len; i++)
1628     {
1629         if (pAddress[i] == '.')
1630         {
1631             isIp = true;
1632         }
1633
1634         // found port number start index
1635         if (isIp && pAddress[i] == ':')
1636         {
1637             ipLen = i;
1638             break;
1639         }
1640     }
1641
1642     if (isIp)
1643     {
1644         if(ipLen && ipLen < sizeof(outAddress->ipAddress))
1645         {
1646             OICStrcpyPartial(outAddress->ipAddress, sizeof(outAddress->ipAddress),
1647                              pAddress, ipLen);
1648         }
1649         else if (!ipLen && len < sizeof(outAddress->ipAddress))
1650         {
1651             OICStrcpyPartial(outAddress->ipAddress, sizeof(outAddress->ipAddress),
1652                              pAddress, len);
1653         }
1654         else
1655         {
1656             printf("IP Address too long: %zu\n", (ipLen == 0) ? len : ipLen);
1657             return false;
1658         }
1659
1660         if (ipLen > 0)
1661         {
1662             outAddress->port = atoi(pAddress + ipLen + 1);
1663         }
1664         return true;
1665     }
1666     else
1667     {
1668         return false;
1669     }
1670 }
1671
1672 void create_file(CAPayload_t bytes, size_t length)
1673 {
1674     FILE *fp = fopen("sample_output.txt", "wb");
1675     if (fp)
1676     {
1677         fwrite(bytes, 1, length, fp);
1678         fclose(fp);
1679     }
1680 }
1681
1682 bool read_file(const char* name, CAPayload_t* bytes, size_t* length)
1683 {
1684     if (NULL == name)
1685     {
1686         printf("parameter is null\n");
1687         return false;
1688     }
1689
1690     FILE* file = NULL;
1691     CAPayload_t buffer = NULL;
1692     unsigned long fileLen = 0;
1693
1694     // Open file
1695     file = fopen(name, "rb");
1696     if (!file)
1697     {
1698         fprintf(stderr, "Unable to open file, %s\n", name);
1699         return false;
1700     }
1701
1702     // Get file length
1703     fseek(file, 0, SEEK_END);
1704     fileLen = ftell(file);
1705     fseek(file, 0, SEEK_SET);
1706
1707     // Allocate memory
1708     buffer = calloc(1, sizeof(uint8_t) * fileLen + 1);
1709     if (!buffer)
1710     {
1711         fprintf(stderr, "Memory error\n");
1712         fclose(file);
1713         return false;
1714     }
1715
1716     // Read file contents into buffer
1717     size_t ret = fread(buffer, fileLen, 1, file);
1718     if (ret != 1)
1719     {
1720         printf("Failed to read data from file, %s\n", name);
1721         fclose(file);
1722         free(buffer);
1723         return false;
1724     }
1725
1726     fclose(file);
1727
1728     *bytes = buffer;
1729     *length = fileLen;
1730
1731     return true;
1732 }
1733
1734 #ifdef CI_ADAPTER
1735 void create_tcp_connection()
1736 {
1737     printf("Enter the CI Server information....\n");
1738     printf("IP: ");
1739     char address[MAX_BUF_LEN] = {'\0'};
1740     if (CA_STATUS_OK != get_input_data(address, MAX_BUF_LEN))
1741     {
1742         return;
1743     }
1744     printf("Port: ");
1745     char port[MAX_BUF_LEN] = {'\0'};
1746     if (CA_STATUS_OK != get_input_data(port, MAX_BUF_LEN))
1747     {
1748         return;
1749     }
1750
1751     int portNum = atoi(port);
1752     CACIServerInfo_t serverInfo = { .u4tcp.port = portNum };
1753     strncpy(serverInfo.addr, address, strlen(address));
1754
1755     CAResult_t res = CACreateTCPConnection(&serverInfo);
1756     if (CA_STATUS_OK != res)
1757     {
1758         printf("Failed to create TCP Connection");
1759     }
1760 }
1761 #endif