0a40dab75a86efd5bada54c479f18a50c23691ab
[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
93 void request_handler(const CAEndpoint_t *object, const CARequestInfo_t *requestInfo);
94 void response_handler(const CAEndpoint_t *object, const CAResponseInfo_t *responseInfo);
95 void error_handler(const CAEndpoint_t *object, const CAErrorInfo_t* errorInfo);
96 void send_response(const CAEndpoint_t *endpoint, const CAInfo_t *info);
97 void get_resource_uri(char *URI, char *resourceURI, int length);
98 int get_secure_information(CAPayload_t payLoad);
99 bool get_address_set(const char *pAddress, addressSet_t* outAddress);
100 void parsing_coap_uri(const char* uri, addressSet_t* address, CATransportFlags_t *flags);
101 CAHeaderOption_t* get_option_data(CAInfo_t* requestData);
102
103 static CAToken_t g_last_request_token = NULL;
104
105 static const char COAP_PREFIX[] =  "coap://";
106 static const char COAPS_PREFIX[] = "coaps://";
107 static const char COAP_TCP_PREFIX[] =  "coap+tcp://";
108
109 static const uint16_t COAP_PREFIX_LEN = sizeof(COAP_PREFIX) - 1;
110 static const uint16_t COAPS_PREFIX_LEN = sizeof(COAPS_PREFIX) - 1;
111 static const uint16_t COAP_TCP_PREFIX_LEN = sizeof(COAP_TCP_PREFIX) - 1;
112
113 static const char SECURE_INFO_DATA[] =
114                                     "{\"oc\":[{\"href\":\"%s\",\"prop\":{\"rt\":[\"core.led\"],"
115                                      "\"if\":[\"oic.if.baseline\"],\"obs\":1,\"sec\":1,\"port\":"
116                                      "%d}}]}";
117 static const char NORMAL_INFO_DATA[] =
118                                     "{\"oc\":[{\"href\":\"%s\",\"prop\":{\"rt\":[\"core.led\"],"
119                                      "\"if\":[\"oic.if.baseline\"],\"obs\":1}}]}";
120
121 #ifdef __WITH_DTLS__
122 static CADtlsPskCredsBlob_t *pskCredsBlob = NULL;
123
124 void clearDtlsCredentialInfo()
125 {
126     printf("clearDtlsCredentialInfo IN\n");
127     if (pskCredsBlob)
128     {
129         // Initialize sensitive data to zeroes before freeing.
130         if (pskCredsBlob->creds)
131         {
132             memset(pskCredsBlob->creds, 0, sizeof(OCDtlsPskCreds) * (pskCredsBlob->num));
133             free(pskCredsBlob->creds);
134         }
135
136         memset(pskCredsBlob, 0, sizeof(CADtlsPskCredsBlob_t));
137         free(pskCredsBlob);
138         pskCredsBlob = NULL;
139     }
140     printf("clearDtlsCredentialInfo OUT\n");
141 }
142
143 #ifdef __WITH_X509__
144 int GetDtlsX509Credentials(CADtlsX509Creds_t *credInfo)
145 {
146     (void) credInfo;
147     return -1;
148 }
149 int * GetCRLResource()
150 {
151     return (int*) NULL;
152 }
153 #endif
154
155 // Internal API. Invoked by CA stack to retrieve credentials from this module
156 void CAGetDtlsPskCredentials(CADtlsPskCredsBlob_t **credInfo)
157 {
158     printf("CAGetDtlsPskCredentials IN\n");
159     if(!credInfo)
160     {
161         printf("Invalid credential container");
162         return;
163     }
164
165     *credInfo = (CADtlsPskCredsBlob_t *)malloc(sizeof(CADtlsPskCredsBlob_t));
166     if (NULL == *credInfo)
167     {
168         printf("Failed to allocate credential blob.");
169         return;
170     }
171
172     size_t credLen = sizeof(OCDtlsPskCreds) * (pskCredsBlob->num);
173     (*credInfo)->creds = (OCDtlsPskCreds *)malloc(credLen);
174     if (NULL == (*credInfo)->creds)
175     {
176         printf("Failed to allocate credentials.");
177         free(*credInfo);
178         *credInfo = NULL;
179         return;
180     }
181
182     memcpy((*credInfo)->identity, pskCredsBlob->identity, DTLS_PSK_ID_LEN);
183     (*credInfo)->num = pskCredsBlob->num;
184     memcpy((*credInfo)->creds, pskCredsBlob->creds, credLen);
185
186     printf("CAGetDtlsPskCredentials OUT\n");
187 }
188
189
190 CAResult_t SetCredentials()
191 {
192     printf("SetCredentials IN\n");
193     pskCredsBlob = (CADtlsPskCredsBlob_t *)calloc(1, sizeof(CADtlsPskCredsBlob_t));
194     if (NULL == pskCredsBlob)
195     {
196         printf("Memory allocation failed!\n");
197         return CA_MEMORY_ALLOC_FAILED;
198      }
199     memcpy(pskCredsBlob->identity, IDENTITY, DTLS_PSK_ID_LEN);
200
201
202     pskCredsBlob->num = 1;
203
204     pskCredsBlob->creds = (OCDtlsPskCreds *)malloc(sizeof(OCDtlsPskCreds) * (pskCredsBlob->num));
205     if (NULL == pskCredsBlob->creds)
206     {
207         printf("Memory allocation failed!\n");
208         free(pskCredsBlob);
209         return CA_MEMORY_ALLOC_FAILED;
210     }
211
212     memcpy(pskCredsBlob->creds[0].id, IDENTITY, DTLS_PSK_ID_LEN);
213     memcpy(pskCredsBlob->creds[0].psk, RS_CLIENT_PSK, DTLS_PSK_PSK_LEN);
214
215     printf("SetCredentials OUT\n");
216     return CA_STATUS_OK;
217 }
218 #endif
219
220 int main()
221 {
222     int ret = system("clear");
223     // shell invoke error: 127, others: -1
224     if (SYSTEM_INVOKE_ERROR == ret || SYSTEM_ERROR == ret)
225     {
226         printf("Terminal Clear Error: %d\n", ret);
227         return -1;
228     }
229
230     printf("=============================================\n");
231     printf("\t\tsample main\n");
232     printf("=============================================\n");
233
234     CAResult_t res = CAInitialize();
235     if (CA_STATUS_OK != res)
236     {
237         printf("CAInitialize fail\n");
238         return -1;
239     }
240
241     /*
242     * Read DTLS PSK credentials from persistent storage and
243     * set in the OC stack.
244     */
245 #ifdef __WITH_DTLS__
246     res = SetCredentials();
247     if (CA_STATUS_OK != res)
248     {
249         printf("SetCredentials failed\n");
250         return -1;
251     }
252
253     res = CARegisterDTLSCredentialsHandler(CAGetDtlsPskCredentials);
254     if (CA_STATUS_OK != res)
255     {
256         printf("Set credential handler fail\n");
257         return -1;
258     }
259 #endif
260
261     // set handler.
262     CARegisterHandler(request_handler, response_handler, error_handler);
263
264     process();
265
266     CADestroyToken(g_last_request_token);
267
268     g_last_request_token = NULL;
269
270     CATerminate();
271 #ifdef __WITH_DTLS__
272     clearDtlsCredentialInfo();
273 #endif
274     return 0;
275 }
276
277 void process()
278 {
279     while (1)
280     {
281         char menu = get_menu();
282
283         switch (menu)
284         {
285             case 'm': // menu
286             case 'M':
287                 break;
288
289             case 'q': // quit
290             case 'Q':
291                 printf("quit..!!\n");
292                 return;
293
294             case 's': // start server
295             case 'S':
296                 start_listening_server();
297                 break;
298
299             case 't': // send request
300             case 'T':
301                 send_request_all();
302                 break;
303
304             case 'c': // start client
305             case 'C':
306                 start_discovery_server();
307                 break;
308
309             case 'r': // send request
310             case 'R':
311                 send_request();
312                 break;
313
314             case 'b': // send notification
315             case 'B':
316                 send_notification();
317                 break;
318
319             case 'n': // select network
320             case 'N':
321                 select_network();
322                 break;
323
324             case 'x': // unselect network
325             case 'X':
326                 unselect_network();
327                 break;
328
329             case 'h': // handle request response
330             case 'H':
331                 handle_request_response();
332                 break;
333
334             case 'w':
335             case 'W':
336                 g_received = 0;
337                 start_discovery_server();
338                 send_secure_request();
339                 while (g_received == 0)
340                 {
341                     sleep(1);
342                     handle_request_response();
343                 }
344                 break;
345
346             case 'z':
347             case 'Z':
348                 start_listening_server();
349                 while (1)
350                 {
351                     sleep(1);
352                     handle_request_response();
353                 }
354                 break;
355
356             case 'g': // get network information
357             case 'G':
358                 get_network_info();
359                 break;
360
361             default:
362                 printf("not supported menu!!\n");
363                 break;
364         }
365     }
366 }
367
368 void start_listening_server()
369 {
370     printf("start listening server!!\n");
371
372     CAResult_t res = CAStartListeningServer();
373     if (CA_STATUS_OK != res)
374     {
375         printf("start listening server fail, error code : %d\n", res);
376     }
377     else
378     {
379         printf("start listening server success\n");
380     }
381 }
382
383 void start_discovery_server()
384 {
385     printf("start discovery client!!\n");
386
387     CAResult_t res = CAStartDiscoveryServer();
388     if (CA_STATUS_OK != res)
389     {
390         printf("start discovery client fail, error code : %d\n", res);
391     }
392     else
393     {
394         printf("start discovery client success\n");
395     }
396 }
397
398 bool select_payload_type()
399 {
400     char buf[MAX_BUF_LEN]={0};
401     printf("\n=============================================\n");
402     printf("Normal Payload  : 0\nBig Payload   : 1\n");
403     printf("select Payload type : ");
404
405     CAResult_t res = get_input_data(buf, sizeof(buf));
406     if (CA_STATUS_OK != res)
407     {
408         printf("Payload type selection error\n");
409         printf("Default: Using normal Payload\n");
410         return false;
411     }
412
413     return (buf[0] == '1') ? true : false;
414 }
415
416 CAPayload_t get_binary_payload(size_t *payloadLength)
417 {
418     CAPayload_t binaryPayload = NULL;
419     bool result = read_file("sample_input.txt", &binaryPayload, payloadLength);
420     if (false == result)
421     {
422         return NULL;
423     }
424
425     return binaryPayload;
426 }
427
428 void send_request()
429 {
430     CAResult_t res = get_network_type();
431     if (CA_STATUS_OK != res)
432     {
433         return;
434     }
435
436     printf("Do you want to send secure request ?.... enter (0/1): ");
437
438     char secureRequest[MAX_BUF_LEN] = {0};
439     if (CA_STATUS_OK != get_input_data(secureRequest, MAX_BUF_LEN))
440     {
441         return;
442     }
443
444     if (strcmp(secureRequest, "1") == 0)
445     {
446         printf("Enter the URI like below....\n");
447         printf("coaps://10.11.12.13:4545/resource_uri ( for IP secure)\n");
448     }
449     else if (strcmp(secureRequest, "0") == 0)
450     {
451         printf("Enter the URI like below....\n");
452         printf("coap://10.11.12.13:4545/resource_uri ( for IP )\n");
453         printf("coap://10:11:12:13:45:45/resource_uri ( for BT )\n");
454         printf("coap+tcp://10:11:12:13:45:45/resource_uri ( for TCP )\n");
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     printf("coap+tcp://10:11:12:13:45:45/resource_uri ( for TCP )\n");
776     printf("uri : ");
777
778     char uri[MAX_BUF_LEN] = { 0 };
779     if (CA_STATUS_OK != get_input_data(uri, MAX_BUF_LEN))
780     {
781         return;
782     }
783
784     printf("\n=============================================\n");
785     printf("\tselect message type\n");
786     printf("CON     : 0\n");
787     printf("NON     : 1\n");
788     printf("ACK     : 2\n");
789     printf("RESET   : 3\n");
790     printf("select : ");
791
792     char messageTypeBuf[MAX_BUF_LEN] = { 0 };
793     if (CA_STATUS_OK != get_input_data(messageTypeBuf, MAX_BUF_LEN))
794     {
795         return;
796     }
797
798     int messageType = messageTypeBuf[0] - '0';
799
800     CATransportFlags_t flags;
801     addressSet_t address = {{}, 0};
802     parsing_coap_uri(uri, &address, &flags);
803
804     // create remote endpoint
805     CAEndpoint_t *endpoint = NULL;
806     res = CACreateEndpoint(flags, g_selected_nw_type, address.ipAddress, address.port, &endpoint);
807     if (CA_STATUS_OK != res)
808     {
809         printf("Create remote endpoint error, error code: %d\n", res);
810         return;
811     }
812
813     // create token
814     CAToken_t token = NULL;
815     uint8_t tokenLength = CA_MAX_TOKEN_LEN;
816
817     res = CAGenerateToken(&token, tokenLength);
818     if ((CA_STATUS_OK != res) || (!token))
819     {
820         printf("Token generate error!!\n");
821         CADestroyEndpoint(endpoint);
822         return;
823     }
824
825     printf("Generated token %s\n", token);
826
827     // create response data
828     CAPayload_t payload = (CAPayload_t) "TempNotificationData";
829     size_t payloadSize = strlen((const char *) payload);
830
831     CAInfo_t respondData = { .type = messageType,
832                              .messageId = 0,
833                              .token = token,
834                              .tokenLength = tokenLength,
835                              .options = NULL,
836                              .numOptions = 0,
837                              .payload = payload,
838                              .payloadSize = payloadSize,
839                              .resourceUri = (CAURI_t)uri };
840
841     CAResponseInfo_t responseInfo = { .result = CA_CONTENT,
842                                       .info = respondData };
843
844     // send request
845     res = CASendNotification(endpoint, &responseInfo);
846     if (CA_STATUS_OK != res)
847     {
848         printf("Send notification error, error code: %d\n", res);
849     }
850     else
851     {
852         printf("Send notification success\n");
853     }
854
855     // destroy token
856     CADestroyToken(token);
857     // destroy remote endpoint
858     CADestroyEndpoint(endpoint);
859
860     printf("\n=============================================\n");
861 }
862
863 void select_network()
864 {
865     printf("\n=============================================\n");
866     printf("\tselect network\n");
867     printf("IP     : 0\n");
868     printf("GATT   : 1\n");
869     printf("RFCOMM : 2\n");
870     printf("TCP    : 4\n");
871     printf("select : ");
872
873     char buf[MAX_BUF_LEN] = { 0 };
874     if (CA_STATUS_OK != get_input_data(buf, MAX_BUF_LEN))
875     {
876         return;
877     }
878
879     int number = buf[0] - '0';
880
881     if (number < 0 || number > 4)
882     {
883         printf("Invalid network type\n");
884         return;
885     }
886
887     CAResult_t res = CASelectNetwork(1 << number);
888     if (CA_STATUS_OK != res)
889     {
890         printf("Select network error\n");
891     }
892     else
893     {
894         printf("Select network success\n");
895     }
896
897     printf("=============================================\n");
898 }
899
900 void unselect_network()
901 {
902     printf("\n=============================================\n");
903     printf("\tunselect enabled network\n");
904     printf("IP     : 0\n");
905     printf("GATT   : 1\n");
906     printf("RFCOMM : 2\n");
907     printf("TCP    : 4\n");
908     printf("select : ");
909
910     char buf[MAX_BUF_LEN] = { 0 };
911     if (CA_STATUS_OK != get_input_data(buf, MAX_BUF_LEN))
912     {
913         return;
914     }
915
916     int number = buf[0] - '0';
917
918     if (number < 0 || number > 4)
919     {
920         printf("Invalid network type\n");
921         return;
922     }
923
924     CAResult_t res = CAUnSelectNetwork(1 << number);
925     if (CA_STATUS_OK != res)
926     {
927         printf("Unselect network error\n");
928     }
929     else
930     {
931         printf("Unselect network success\n");
932     }
933
934     printf("=============================================\n");
935 }
936
937 char get_menu()
938 {
939     printf("\n=============================================\n");
940     printf("\t\tMenu\n");
941     printf("\ts : start server\n");
942     printf("\tc : start client\n");
943     printf("\tr : send request\n");
944     printf("\tt : send request to all\n");
945     printf("\tb : send notification\n");
946     printf("\tn : select network\n");
947     printf("\tx : unselect network\n");
948     printf("\tg : get network information\n");
949     printf("\th : handle request response\n");
950     printf("\tz : run static server\n");
951     printf("\tw : send secure request\n");
952     printf("\tq : quit\n");
953     printf("=============================================\n");
954     printf("select : ");
955
956     char buf[MAX_BUF_LEN] = { 0 };
957     if (CA_STATUS_OK != get_input_data(buf, MAX_BUF_LEN))
958     {
959         printf("Failed to get input data\n");
960     }
961
962     return buf[0];
963 }
964
965 void handle_request_response()
966 {
967     printf("Handle_request_response\n");
968
969     CAResult_t res = CAHandleRequestResponse();
970     if (CA_STATUS_OK != res)
971     {
972         printf("Handle request error, error code: %d\n", res);
973     }
974     else
975     {
976         printf("Handle request success\n");
977     }
978 }
979
980 void get_network_info()
981 {
982     CAEndpoint_t *tempInfo = NULL;
983     uint32_t tempSize = 0;
984
985     CAResult_t res = CAGetNetworkInformation(&tempInfo, &tempSize);
986     if (CA_STATUS_OK != res || NULL == tempInfo || 0 >= tempSize)
987     {
988         printf("Network not connected\n");
989         free(tempInfo);
990         return;
991     }
992
993     printf("################## Network Information #######################\n");
994     printf("Network info total size is %d\n\n", tempSize);
995
996     for (uint32_t index = 0; index  < tempSize; index++)
997     {
998         printf("Type: %d\n", tempInfo[index].adapter);
999         printf("Address: %s\n", tempInfo[index].addr);
1000         if (CA_ADAPTER_IP == tempInfo[index].adapter)
1001         {
1002             printf("Port: %d\n", tempInfo[index].port);
1003             printf("Secured: %s flag : %x\n\n", (tempInfo[index].flags & CA_SECURE) ? "true" :
1004                    "false", tempInfo[index].flags);
1005
1006             if (tempInfo[index].flags & CA_SECURE)
1007             {
1008                 g_local_secure_port = tempInfo[index].port;
1009                 printf("Secured: in global %d\n\n", g_local_secure_port);
1010             }
1011         }
1012     }
1013
1014     free(tempInfo);
1015     printf("##############################################################");
1016 }
1017
1018 void request_handler(const CAEndpoint_t *object, const CARequestInfo_t *requestInfo)
1019 {
1020     if (NULL == object || NULL == requestInfo)
1021     {
1022         printf("Input parameter is NULL\n");
1023         return;
1024     }
1025
1026     if ((NULL != g_last_request_token) && (NULL != requestInfo->info.token)
1027         && (memcmp(g_last_request_token, requestInfo->info.token,
1028                    CA_MAX_TOKEN_LEN) == 0))
1029     {
1030         printf("token is same. received request of it's own. skip.. \n");
1031         return;
1032     }
1033
1034     printf("##########received request from remote device #############\n");
1035     if (CA_ADAPTER_IP == object->adapter)
1036     {
1037         printf("Remote Address: %s Port: %d secured:%d\n", object->addr,
1038                object->port, object->flags & CA_SECURE);
1039     }
1040     else
1041     {
1042         printf("Remote Address: %s \n", object->addr);
1043     }
1044     printf("Data: %s\n", requestInfo->info.payload);
1045     printf("Message type: %s\n", MESSAGE_TYPE[requestInfo->info.type]);
1046
1047     if (requestInfo->info.options)
1048     {
1049         uint32_t len = requestInfo->info.numOptions;
1050         uint32_t i;
1051         for (i = 0; i < len; i++)
1052         {
1053             printf("Option %d\n", i + 1);
1054             printf("ID : %d\n", requestInfo->info.options[i].optionID);
1055             printf("Data[%d]: %s\n", requestInfo->info.options[i].optionLength,
1056                    requestInfo->info.options[i].optionData);
1057         }
1058     }
1059     printf("############################################################\n");
1060
1061     //Check if this has secure communication information
1062     if (requestInfo->info.payload &&
1063             (CA_ADAPTER_IP == object->adapter))
1064     {
1065         int securePort = get_secure_information(requestInfo->info.payload);
1066         if (0 < securePort) //Set the remote endpoint secure details and send response
1067         {
1068             printf("This is secure resource...\n");
1069
1070             CAEndpoint_t *endpoint = NULL;
1071             if (CA_STATUS_OK != CACreateEndpoint(0, object->adapter, object->addr,
1072                                                  object->port, &endpoint))
1073             {
1074                 printf("Failed to create duplicate of remote endpoint!\n");
1075                 return;
1076             }
1077             endpoint->flags = CA_SECURE;
1078             object = endpoint;
1079         }
1080     }
1081
1082 #ifdef WITH_BWT
1083     // if received message is bulk data, create output file
1084     if ((requestInfo->info.payload) &&
1085             (requestInfo->info.payloadSize > BLOCK_SIZE(CA_DEFAULT_BLOCK_SIZE)))
1086     {
1087         create_file(requestInfo->info.payload, requestInfo->info.payloadSize);
1088     }
1089 #endif
1090
1091     printf("Send response with URI\n");
1092     send_response(object, &requestInfo->info);
1093
1094     g_received = 1;
1095 }
1096
1097 void response_handler(const CAEndpoint_t *object, const CAResponseInfo_t *responseInfo)
1098 {
1099     printf("##########Received response from remote device #############\n");
1100     if (CA_ADAPTER_IP == object->adapter)
1101     {
1102         printf("Remote Address: %s Port: %d secured:%d\n", object->addr,
1103                object->port, object->flags & CA_SECURE);
1104     }
1105     else
1106     {
1107         printf("Remote Address: %s \n", object->addr);
1108     }
1109     printf("response result : %d\n", responseInfo->result);
1110     printf("Data: %s\n", responseInfo->info.payload);
1111     printf("Message type: %s\n", MESSAGE_TYPE[responseInfo->info.type]);
1112     printf("Token: %s\n", responseInfo->info.token);
1113     if (responseInfo->info.options)
1114     {
1115         uint32_t len = responseInfo->info.numOptions;
1116         uint32_t i;
1117         for (i = 0; i < len; i++)
1118         {
1119             printf("Option %d\n", i + 1);
1120             printf("ID : %d\n", responseInfo->info.options[i].optionID);
1121             printf("Data[%d]: %s\n", responseInfo->info.options[i].optionLength,
1122                    responseInfo->info.options[i].optionData);
1123         }
1124     }
1125     printf("############################################################\n");
1126     g_received = 1;
1127
1128     //Check if this has secure communication information
1129     if (responseInfo->info.payload)
1130     {
1131         int securePort = get_secure_information(responseInfo->info.payload);
1132         if (0 < securePort) //Set the remote endpoint secure details and send response
1133         {
1134             printf("This is secure resource...\n");
1135         }
1136     }
1137
1138 #ifdef WITH_BWT
1139     // if received message is bulk data, create output file
1140     if ((responseInfo->info.payload) &&
1141             (responseInfo->info.payloadSize > BLOCK_SIZE(CA_DEFAULT_BLOCK_SIZE)))
1142     {
1143         create_file(responseInfo->info.payload, responseInfo->info.payloadSize);
1144     }
1145 #endif
1146 }
1147
1148 void error_handler(const CAEndpoint_t *rep, const CAErrorInfo_t* errorInfo)
1149 {
1150     (void)rep;
1151     printf("+++++++++++++++++++++++++++++++++++ErrorInfo+++++++++++++++++++++++++++++++++++\n");
1152
1153     if(errorInfo)
1154     {
1155         const CAInfo_t *info = &errorInfo->info;
1156         printf("Error Handler, ErrorInfo :\n");
1157         printf("Error Handler result    : %d\n", errorInfo->result);
1158         printf("Error Handler token     : %s\n", info->token);
1159         printf("Error Handler messageId : %d\n", (uint16_t) info->messageId);
1160         printf("Error Handler type      : %d\n", info->type);
1161         printf("Error Handler resourceUri : %s\n", info->resourceUri);
1162         printf("Error Handler payload   : %s\n", info->payload);
1163
1164         if(CA_ADAPTER_NOT_ENABLED == errorInfo->result)
1165         {
1166             printf("CA_ADAPTER_NOT_ENABLED, enable the adapter\n");
1167         }
1168         else if(CA_SEND_FAILED == errorInfo->result)
1169         {
1170             printf("CA_SEND_FAILED, unable to send the message, check parameters\n");
1171         }
1172         else if(CA_MEMORY_ALLOC_FAILED == errorInfo->result)
1173         {
1174             printf("CA_MEMORY_ALLOC_FAILED, insufficient memory\n");
1175         }
1176         else if(CA_SOCKET_OPERATION_FAILED == errorInfo->result)
1177         {
1178             printf("CA_SOCKET_OPERATION_FAILED, socket operation failed\n");
1179         }
1180         else if(CA_STATUS_FAILED == errorInfo->result)
1181         {
1182             printf("CA_STATUS_FAILED, message could not be delivered, internal error\n");
1183         }
1184     }
1185     printf("++++++++++++++++++++++++++++++++End of ErrorInfo++++++++++++++++++++++++++++++++\n");
1186
1187     return;
1188 }
1189
1190 void send_response(const CAEndpoint_t *endpoint, const CAInfo_t *info)
1191 {
1192     printf("entering send_response\n");
1193
1194     printf("\n=============================================\n");
1195     printf("\tselect message type\n");
1196     printf("CON     : 0\n");
1197     printf("NON     : 1\n");
1198     printf("ACK     : 2\n");
1199     printf("RESET   : 3\n");
1200     printf("select : ");
1201
1202     char buf[MAX_BUF_LEN] = { 0 };
1203     if (CA_STATUS_OK != get_input_data(buf, MAX_BUF_LEN))
1204     {
1205         return;
1206     }
1207
1208     int messageType = buf[0] - '0';
1209     if (0 > messageType || 3 < messageType)
1210     {
1211         printf("Invalid message type\n");
1212         return;
1213     }
1214
1215     int responseCode = 0 ;
1216     char responseCodeBuf[MAX_BUF_LEN] = { 0 };
1217     if (CA_MSG_RESET != messageType)
1218     {
1219         printf("\n=============================================\n");
1220         printf("\tselect response code\n");
1221         printf("EMPTY                    :   0\n");
1222         printf("CREATED                  : 201\n");
1223         printf("DELETED                  : 202\n");
1224         printf("VALID                    : 203\n");
1225         printf("CHANGED                  : 204\n");
1226         printf("CONTENT                  : 205\n");
1227         printf("BAD_REQ                  : 400\n");
1228         printf("BAD_OPT                  : 402\n");
1229         printf("NOT_FOUND                : 404\n");
1230         printf("INTERNAL_SERVER_ERROR    : 500\n");
1231         printf("RETRANSMIT_TIMEOUT       : 504\n");
1232         printf("select : ");
1233
1234         if (CA_STATUS_OK != get_input_data(responseCodeBuf, MAX_BUF_LEN))
1235         {
1236             return;
1237         }
1238         responseCode = atoi(responseCodeBuf);
1239     }
1240
1241     // create response data
1242     uint16_t messageId = (info != NULL) ? info->messageId : 0;
1243     CAURI_t resourceUri = (info != NULL) ? info->resourceUri : 0;
1244
1245     CAInfo_t responseData = { .type = messageType,
1246                               .messageId = messageId,
1247                               .token = NULL,
1248                               .tokenLength = 0,
1249                               .options = NULL,
1250                               .numOptions = 0,
1251                               .payload = NULL,
1252                               .payloadSize = 0,
1253                               .resourceUri = resourceUri };
1254
1255     if(CA_MSG_RESET != messageType)
1256     {
1257         responseData.token = (info != NULL) ? info->token : NULL;
1258         responseData.tokenLength = (info != NULL) ? info->tokenLength : 0;
1259
1260         if (endpoint->flags & CA_SECURE)
1261         {
1262             if(!responseData.resourceUri)
1263             {
1264                printf("resourceUri not available in SECURE\n");
1265                return;
1266             }
1267             printf("Sending response on secure communication\n");
1268
1269             uint32_t length = sizeof(SECURE_INFO_DATA) + strlen(responseData.resourceUri);
1270             responseData.payload = (CAPayload_t) calloc(length,  sizeof(char));
1271             if (NULL == responseData.payload)
1272             {
1273                 printf("Memory allocation fail\n");
1274                 return;
1275             }
1276             snprintf((char *) responseData.payload, length, SECURE_INFO_DATA,
1277                      (const char *) responseData.resourceUri, g_local_secure_port);
1278             responseData.payloadSize = length;
1279         }
1280         else
1281         {
1282             printf("Sending response on non-secure communication\n");
1283
1284             bool useBigPayload = select_payload_type();
1285             if (useBigPayload)
1286             {
1287                 size_t payloadLength = 0;
1288                 CAPayload_t binaryPayload = get_binary_payload(&payloadLength);
1289                 if (NULL == binaryPayload)
1290                 {
1291                     free(binaryPayload);
1292                     return;
1293                 }
1294
1295                 responseData.payload = (CAPayload_t) malloc(payloadLength);
1296                 if (NULL == responseData.payload)
1297                 {
1298                     printf("Memory allocation failed!");
1299                     free(binaryPayload);
1300                     return;
1301                 }
1302                 memcpy(responseData.payload, binaryPayload, payloadLength);
1303                 responseData.payloadSize = payloadLength;
1304
1305                 // memory free
1306                 free(binaryPayload);
1307             }
1308             else
1309             {
1310                 if(!responseData.resourceUri)
1311                 {
1312                    printf("resourceUri not available in NON-SECURE\n");
1313                    return;
1314                 }
1315                 uint32_t length = sizeof(NORMAL_INFO_DATA) + strlen(responseData.resourceUri);
1316                 responseData.payload = (CAPayload_t) calloc(length, sizeof(char));
1317                 if (NULL == responseData.payload)
1318                 {
1319                     printf("Memory allocation fail\n");
1320                     return;
1321                 }
1322                 snprintf((char *) responseData.payload, length, NORMAL_INFO_DATA,
1323                          (const char *) responseData.resourceUri);
1324                 responseData.payloadSize = length;
1325             }
1326         }
1327     }
1328
1329     CAResponseInfo_t responseInfo = { .result = responseCode,
1330                                       .info = responseData };
1331
1332     // send response (transportType from remoteEndpoint of request Info)
1333     CAResult_t res = CASendResponse(endpoint, &responseInfo);
1334     if (CA_STATUS_OK != res)
1335     {
1336         printf("Send response error\n");
1337     }
1338     else
1339     {
1340         printf("Send response success\n");
1341     }
1342
1343     if (responseData.payload)
1344     {
1345         free(responseData.payload);
1346     }
1347
1348     printf("=============================================\n");
1349 }
1350
1351 int get_secure_information(CAPayload_t payLoad)
1352 {
1353     printf("Entering get_secure_information\n");
1354
1355     if (!payLoad)
1356     {
1357         printf("Payload is NULL\n");
1358         return -1;
1359     }
1360
1361     char *subString = NULL;
1362     if (NULL == (subString = strstr((const char *) payLoad, "\"sec\":1")))
1363     {
1364         printf("This is not secure resource\n");
1365         return -1;
1366     }
1367
1368     if (NULL == (subString = strstr((const char *) payLoad, "\"port\":")))
1369     {
1370         printf("This secure resource does not have port information\n");
1371         return -1;
1372     }
1373
1374     char *startPos = strstr(subString, ":");
1375     if (!startPos)
1376     {
1377         printf("Parsing failed !\n");
1378         return -1;
1379     }
1380
1381     char *endPos = strstr(startPos, "}");
1382     if (!endPos)
1383     {
1384         printf("Parsing failed !\n");
1385         return -1;
1386     }
1387
1388     char portStr[6] = {0};
1389     OICStrcpyPartial(portStr, sizeof(portStr), startPos + 1, (endPos - 1) - startPos);
1390     printf("secured port is: %s\n", portStr);
1391     return atoi(portStr);
1392 }
1393
1394 void get_resource_uri(char *URI, char *resourceURI, int length)
1395 {
1396     char *startPos = URI;
1397     char *temp = NULL;
1398     if (NULL != (temp = strstr(URI, "://")))
1399     {
1400         startPos = strchr(temp + 3, '/');
1401         if (!startPos)
1402         {
1403             printf("Resource URI is missing\n");
1404             return;
1405         }
1406     }
1407
1408     char *endPos = strchr(startPos, '?');
1409     if (!endPos)
1410     {
1411         endPos = URI + strlen(URI);
1412     }
1413     endPos -= 1;
1414
1415     if (endPos - startPos <= length)
1416     {
1417         OICStrcpyPartial(resourceURI, length, startPos + 1, endPos - startPos);
1418     }
1419
1420     printf("URI: %s, ResourceURI:%s\n", URI, resourceURI);
1421 }
1422
1423 CAResult_t get_network_type()
1424 {
1425     char buf[MAX_BUF_LEN] = { 0 };
1426
1427     printf("\n=============================================\n");
1428     printf("\tselect network type\n");
1429     printf("IP     : 0\n");
1430     printf("GATT   : 1\n");
1431     printf("RFCOMM : 2\n");
1432     printf("TCP    : 4\n");
1433     printf("select : ");
1434
1435     if (CA_STATUS_OK != get_input_data(buf, MAX_BUF_LEN))
1436     {
1437         return CA_NOT_SUPPORTED ;
1438     }
1439
1440     int number = buf[0] - '0';
1441
1442     number = (number < 0 || number > 4) ? 0 : 1 << number;
1443
1444     switch (number)
1445     {
1446         case CA_ADAPTER_IP:
1447         case CA_ADAPTER_GATT_BTLE:
1448         case CA_ADAPTER_RFCOMM_BTEDR:
1449         case CA_ADAPTER_TCP:
1450             g_selected_nw_type = number;
1451             return CA_STATUS_OK;
1452         default:
1453             return CA_NOT_SUPPORTED;
1454     }
1455 }
1456
1457 CAResult_t get_input_data(char *buf, int32_t length)
1458 {
1459     if (!fgets(buf, length, stdin))
1460     {
1461         printf("fgets error\n");
1462         return CA_STATUS_FAILED;
1463     }
1464
1465     char *p = NULL;
1466     if ( (p = strchr(buf, '\n')) != NULL )
1467     {
1468         *p = '\0';
1469     }
1470
1471     return CA_STATUS_OK;
1472 }
1473
1474 CAHeaderOption_t* get_option_data(CAInfo_t* requestData)
1475 {
1476     char optionNumBuf[MAX_BUF_LEN] = { 0 };
1477     char optionData[MAX_OPT_LEN] = { 0 } ;
1478
1479     printf("Option Num : ");
1480     if (CA_STATUS_OK != get_input_data(optionNumBuf, MAX_BUF_LEN))
1481     {
1482         return NULL;
1483     }
1484     int optionNum = atoi(optionNumBuf);
1485
1486     CAHeaderOption_t * headerOpt = NULL;
1487     if (0 >= optionNum)
1488     {
1489         printf("there is no headerOption!\n");
1490         return NULL;
1491     }
1492     else if (optionNum > MAX_OPT_LEN)
1493     {
1494         printf("Too many header options!\n");
1495         return NULL;
1496     }
1497     else
1498     {
1499         headerOpt = (CAHeaderOption_t *)calloc(optionNum, sizeof(CAHeaderOption_t));
1500         if (NULL == headerOpt)
1501         {
1502             printf("Memory allocation failed!\n");
1503             return NULL;
1504         }
1505
1506         int i;
1507         for (i = 0; i < optionNum; i++)
1508         {
1509             char getOptionID[MAX_BUF_LEN] = { 0 } ;
1510
1511             printf("[%d] Option ID : ", i + 1);
1512             if (CA_STATUS_OK != get_input_data(getOptionID, MAX_BUF_LEN))
1513             {
1514                 free(headerOpt);
1515                 return NULL;
1516             }
1517             int optionID = atoi(getOptionID);
1518             headerOpt[i].optionID = optionID;
1519
1520             printf("[%d] Option Data : ", i + 1);
1521             if (CA_STATUS_OK != get_input_data(optionData, MAX_OPT_LEN))
1522             {
1523                 free(headerOpt);
1524                 return NULL;
1525             }
1526
1527             OICStrcpy(headerOpt[i].optionData, sizeof(headerOpt[i].optionData), optionData);
1528
1529             headerOpt[i].optionLength = (uint16_t) strlen(optionData);
1530         }
1531         requestData->numOptions = optionNum;
1532         requestData->options = headerOpt;
1533     }
1534     return headerOpt;
1535 }
1536
1537 void parsing_coap_uri(const char* uri, addressSet_t* address, CATransportFlags_t *flags)
1538 {
1539     if (NULL == uri)
1540     {
1541         printf("parameter is null\n");
1542         return;
1543     }
1544
1545     // parse uri
1546     // #1. check prefix
1547     uint8_t startIndex = 0;
1548     if (strncmp(COAPS_PREFIX, uri, COAPS_PREFIX_LEN) == 0)
1549     {
1550         printf("uri has '%s' prefix\n", COAPS_PREFIX);
1551         startIndex = COAPS_PREFIX_LEN;
1552         *flags = CA_SECURE;
1553     }
1554     else if (strncmp(COAP_PREFIX, uri, COAP_PREFIX_LEN) == 0)
1555     {
1556         printf("uri has '%s' prefix\n", COAP_PREFIX);
1557         startIndex = COAP_PREFIX_LEN;
1558         *flags = CA_IPV4;
1559     }
1560     else if (strncmp(COAP_TCP_PREFIX, uri, COAP_TCP_PREFIX_LEN) == 0)
1561     {
1562         printf("uri has '%s' prefix\n", COAP_TCP_PREFIX);
1563         startIndex = COAP_TCP_PREFIX_LEN;
1564         *flags = CA_IPV4;
1565     }
1566
1567     // #2. copy uri for parse
1568     int32_t len = strlen(uri) - startIndex;
1569
1570     if (len <= 0)
1571     {
1572         printf("uri length is 0!\n");
1573         return;
1574     }
1575
1576     char *cloneUri = (char *) calloc(len + 1, sizeof(char));
1577     if (NULL == cloneUri)
1578     {
1579         printf("Out of memory\n");
1580         return;
1581     }
1582
1583     memcpy(cloneUri, &uri[startIndex], sizeof(char) * len);
1584     cloneUri[len] = '\0';
1585
1586     char *pAddress = cloneUri;
1587     printf("pAddress : %s\n", pAddress);
1588
1589     if (!get_address_set(pAddress, address))
1590     {
1591         printf("address parse error\n");
1592
1593         free(cloneUri);
1594         return;
1595     }
1596     free(cloneUri);
1597     return;
1598 }
1599
1600 bool get_address_set(const char *pAddress, addressSet_t* outAddress)
1601 {
1602     if (NULL == pAddress)
1603     {
1604         printf("parameter is null !\n");
1605         return false;
1606     }
1607
1608     size_t len = strlen(pAddress);
1609     bool isIp = false;
1610     size_t ipLen = 0;
1611
1612     for (size_t i = 0; i < len; i++)
1613     {
1614         if (pAddress[i] == '.')
1615         {
1616             isIp = true;
1617         }
1618
1619         // found port number start index
1620         if (isIp && pAddress[i] == ':')
1621         {
1622             ipLen = i;
1623             break;
1624         }
1625     }
1626
1627     if (isIp)
1628     {
1629         if(ipLen && ipLen < sizeof(outAddress->ipAddress))
1630         {
1631             OICStrcpyPartial(outAddress->ipAddress, sizeof(outAddress->ipAddress),
1632                              pAddress, ipLen);
1633         }
1634         else if (!ipLen && len < sizeof(outAddress->ipAddress))
1635         {
1636             OICStrcpyPartial(outAddress->ipAddress, sizeof(outAddress->ipAddress),
1637                              pAddress, len);
1638         }
1639         else
1640         {
1641             printf("IP Address too long: %zu\n", (ipLen == 0) ? len : ipLen);
1642             return false;
1643         }
1644
1645         if (ipLen > 0)
1646         {
1647             outAddress->port = atoi(pAddress + ipLen + 1);
1648         }
1649         return true;
1650     }
1651     else
1652     {
1653         return false;
1654     }
1655 }
1656
1657 void create_file(CAPayload_t bytes, size_t length)
1658 {
1659     FILE *fp = fopen("sample_output.txt", "wb");
1660     if (fp)
1661     {
1662         fwrite(bytes, 1, length, fp);
1663         fclose(fp);
1664     }
1665 }
1666
1667 bool read_file(const char* name, CAPayload_t* bytes, size_t* length)
1668 {
1669     if (NULL == name)
1670     {
1671         printf("parameter is null\n");
1672         return false;
1673     }
1674
1675     FILE* file = NULL;
1676     CAPayload_t buffer = NULL;
1677     unsigned long fileLen = 0;
1678
1679     // Open file
1680     file = fopen(name, "rb");
1681     if (!file)
1682     {
1683         fprintf(stderr, "Unable to open file, %s\n", name);
1684         return false;
1685     }
1686
1687     // Get file length
1688     fseek(file, 0, SEEK_END);
1689     fileLen = ftell(file);
1690     fseek(file, 0, SEEK_SET);
1691
1692     // Allocate memory
1693     buffer = calloc(1, sizeof(uint8_t) * fileLen + 1);
1694     if (!buffer)
1695     {
1696         fprintf(stderr, "Memory error\n");
1697         fclose(file);
1698         return false;
1699     }
1700
1701     // Read file contents into buffer
1702     size_t ret = fread(buffer, fileLen, 1, file);
1703     if (ret != 1)
1704     {
1705         printf("Failed to read data from file, %s\n", name);
1706         fclose(file);
1707         free(buffer);
1708         return false;
1709     }
1710
1711     fclose(file);
1712
1713     *bytes = buffer;
1714     *length = fileLen;
1715
1716     return true;
1717 }