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