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