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