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