Imported Upstream version 0.9.2
[platform/upstream/iotivity.git] / resource / csdk / connectivity / samples / linux / sample_main.c
1 /******************************************************************
2  *
3  * Copyright 2014 Samsung Electronics All Rights Reserved.
4  *
5  *
6  *
7  * Licensed under the Apache License, Version 2.0 (the "License");
8  * you may not use this file except in compliance with the License.
9  * You may obtain a copy of the License at
10  *
11  *      http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing, software
14  * distributed under the License is distributed on an "AS IS" BASIS,
15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16  * See the License for the specific language governing permissions and
17  * limitations under the License.
18  *
19  ******************************************************************/
20
21 #include <stdio.h>
22 #include <stdlib.h>
23 #include <string.h>
24 #include <sys/stat.h>
25 #include <unistd.h>
26 #include <stdbool.h>
27
28 #include "cacommon.h"
29 #include "cainterface.h"
30 #ifdef __WITH_DTLS__
31 #include "ocsecurityconfig.h"
32 #endif
33
34 #define MAX_BUF_LEN 1024
35 #define MAX_OPT_LEN 16
36
37 #define PORT_LENGTH 5
38
39 #define SECURE_DEFAULT_PORT 5684
40
41 #define RESOURCE_URI_LENGTH 14
42
43 #define SYSTEM_INVOKE_ERROR 127
44 #define SYSTEM_ERROR -1
45
46 /**
47  * @def RS_IDENTITY
48  * @brief
49  */
50 #define IDENTITY     ("1111111111111111")
51 /* @def RS_CLIENT_PSK
52  * @brief
53  */
54 #define RS_CLIENT_PSK   ("AAAAAAAAAAAAAAAA")
55
56 int g_received;
57 uint16_t g_local_secure_port = SECURE_DEFAULT_PORT;
58 CATransportAdapter_t g_selected_nw_type = CA_ADAPTER_IP;
59 const char *MESSAGE_TYPE[] = {"CON", "NON", "ACK", "RESET"};
60
61 typedef struct
62 {
63     char ipAddress[CA_IPADDR_SIZE];
64     uint16_t port;
65 } addressSet_t;
66
67 char get_menu();
68 void process();
69 CAResult_t get_network_type();
70 CAResult_t get_input_data(char *buf, int32_t length);
71
72 void start_listening_server();
73 void start_discovery_server();
74 void send_request();
75 void send_request_all();
76 void send_notification();
77 void select_network();
78 void unselect_network();
79 void handle_request_response();
80 void get_network_info();
81 void send_secure_request();
82
83 void request_handler(const CAEndpoint_t *object, const CARequestInfo_t *requestInfo);
84 void response_handler(const CAEndpoint_t *object, const CAResponseInfo_t *responseInfo);
85 void error_handler(const CAEndpoint_t *object, const CAErrorInfo_t* errorInfo);
86 void send_response(const CAEndpoint_t *endpoint, const CAInfo_t *info);
87 void get_resource_uri(char *URI, char *resourceURI, int length);
88 int get_secure_information(CAPayload_t payLoad);
89 int get_address_set(const char *pAddress, addressSet_t* outAddress);
90 void parsing_coap_uri(const char* uri, addressSet_t* address, CATransportFlags_t *flags);
91 CAHeaderOption_t* get_option_data(CAInfo_t* requestData);
92
93 static CAToken_t g_last_request_token = NULL;
94
95 static const char COAP_PREFIX[] =  "coap://";
96 static const char COAPS_PREFIX[] = "coaps://";
97 static const uint16_t COAP_PREFIX_LEN = sizeof(COAP_PREFIX) - 1;
98 static const uint16_t COAPS_PREFIX_LEN = sizeof(COAPS_PREFIX) - 1;
99
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     CATransportFlags_t flags;
415
416     printf("URI : %s\n", uri);
417     addressSet_t address = {};
418     parsing_coap_uri(uri, &address, &flags);
419
420     res = CACreateEndpoint(flags, g_selected_nw_type,
421                            (const char*)address.ipAddress, address.port, &endpoint);
422     if (CA_STATUS_OK != res || !endpoint)
423     {
424         printf("Failed to create remote endpoint, error code : %d\n", res);
425         return;
426     }
427
428     printf("\n=============================================\n");
429     printf("0:CON, 1:NON\n");
430     printf("select message type : ");
431
432     char buf[MAX_BUF_LEN] = { 0 };
433     if (CA_STATUS_OK != get_input_data(buf, MAX_BUF_LEN))
434     {
435         CADestroyEndpoint(endpoint);
436         return;
437     }
438
439     CAMessageType_t msgType = (buf[0] == '1') ? 1 : 0;
440
441     // create token
442     CAToken_t token = NULL;
443     uint8_t tokenLength = CA_MAX_TOKEN_LEN;
444
445     res = CAGenerateToken(&token, tokenLength);
446     if ((CA_STATUS_OK != res) || (!token))
447     {
448         printf("Token generate error, error code : %d\n", res);
449         CADestroyEndpoint(endpoint);
450         return;
451     }
452
453     printf("Generated token %s\n", token);
454
455     // extract relative resourceuri from give uri
456     char resourceURI[RESOURCE_URI_LENGTH + 1] = {0};
457     get_resource_uri(uri, resourceURI, RESOURCE_URI_LENGTH);
458     printf("resourceURI : %s\n", resourceURI);
459
460     // create request data
461     CAInfo_t requestData = { 0 };
462     requestData.token = token;
463     requestData.tokenLength = tokenLength;
464     requestData.resourceUri = (CAURI_t)resourceURI;
465
466     if (strcmp(secureRequest, "1") == 0)
467     {
468         size_t length = sizeof(SECURE_INFO_DATA) + strlen(resourceURI);
469         requestData.payload = (CAPayload_t) calloc(length,  sizeof(char));
470         if (NULL == requestData.payload)
471         {
472             printf("Memory allocation fail\n");
473             CADestroyEndpoint(endpoint);
474             CADestroyToken(token);
475             return;
476         }
477         snprintf((char *) requestData.payload, length, SECURE_INFO_DATA,
478                  (const char *) resourceURI, g_local_secure_port);
479         requestData.payloadSize = length;
480     }
481     else
482     {
483         size_t length = sizeof(NORMAL_INFO_DATA) + strlen(resourceURI);
484         requestData.payload = (CAPayload_t) calloc(length, sizeof(char));
485         if (NULL == requestData.payload)
486         {
487             printf("Memory allocation fail\n");
488             CADestroyEndpoint(endpoint);
489             CADestroyToken(token);
490             return;
491         }
492         snprintf((char *) requestData.payload, length, NORMAL_INFO_DATA,
493                  (const char *) resourceURI);
494         requestData.payloadSize = length;
495     }
496     requestData.type = msgType;
497     CAHeaderOption_t* headerOpt = get_option_data(&requestData);
498
499     CARequestInfo_t requestInfo = { 0 };
500     requestInfo.method = CA_GET;
501     requestInfo.info = requestData;
502     requestInfo.isMulticast = false;
503
504     // send request
505     res = CASendRequest(endpoint, &requestInfo);
506     if (CA_STATUS_OK != res)
507     {
508         printf("Could not send request : %d\n", res);
509     }
510
511     if (headerOpt)
512     {
513         free(headerOpt);
514     }
515
516     //destroy token
517     CADestroyToken(token);
518     // destroy remote endpoint
519     CADestroyEndpoint(endpoint);
520     free(requestData.payload);
521
522     printf("=============================================\n");
523 }
524
525 void send_secure_request()
526 {
527     char uri[MAX_BUF_LEN];
528     char ipv4addr[CA_IPADDR_SIZE];
529
530     printf("\n=============================================\n");
531     printf("Enter IPv4 address of the source hosting secure resource (Ex: 11.12.13.14)\n");
532
533     if (CA_STATUS_OK != get_input_data(ipv4addr, CA_IPADDR_SIZE))
534     {
535         return;
536     }
537     snprintf(uri, MAX_BUF_LEN, "%s%s:5684/a/light", COAPS_PREFIX, ipv4addr);
538
539     // create remote endpoint
540     CAEndpoint_t *endpoint = NULL;
541     CAResult_t res = CACreateEndpoint(0, CA_ADAPTER_IP, ipv4addr, SECURE_DEFAULT_PORT, &endpoint);
542     if (CA_STATUS_OK != res)
543     {
544         printf("Failed to create remote endpoint, error code: %d\n", res);
545         goto exit;
546     }
547
548     // create token
549     CAToken_t token = NULL;
550     uint8_t tokenLength = CA_MAX_TOKEN_LEN;
551
552     res = CAGenerateToken(&token, tokenLength);
553     if ((CA_STATUS_OK != res) || (!token))
554     {
555         printf("Token generate error, error code : %d\n", res);
556         goto exit;
557     }
558
559     printf("Generated token %s\n", token);
560
561     // create request data
562     CAMessageType_t msgType = CA_MSG_NONCONFIRM;
563     CAInfo_t requestData = { 0 };
564     requestData.token = token;
565     requestData.tokenLength = tokenLength;
566     requestData.type = msgType;
567
568     CARequestInfo_t requestInfo = { 0 };
569     requestInfo.method = CA_GET;
570     requestInfo.info = requestData;
571     requestInfo.isMulticast = false;
572
573     // send request
574     CASendRequest(endpoint, &requestInfo);
575
576 exit:
577     // cleanup
578     CADestroyToken(token);
579     CADestroyEndpoint(endpoint);
580     printf("=============================================\n");
581 }
582
583
584 void send_request_all()
585 {
586     CAResult_t res = get_network_type();
587     if (CA_STATUS_OK != res)
588     {
589         return;
590     }
591
592     printf("\n=============================================\n");
593     printf("ex) /a/light\n");
594     printf("resource uri : ");
595
596     char resourceURI[MAX_BUF_LEN] = { 0 };
597     if (CA_STATUS_OK != get_input_data(resourceURI, MAX_BUF_LEN))
598     {
599         return;
600     }
601
602     // create remote endpoint
603     CAEndpoint_t *endpoint = NULL;
604     res = CACreateEndpoint(0, g_selected_nw_type, NULL, 0, &endpoint);
605     if (CA_STATUS_OK != res)
606     {
607         printf("Create remote endpoint error, error code: %d\n", res);
608         return;
609     }
610
611     CAEndpoint_t *group = (CAEndpoint_t *) malloc(sizeof(CAEndpoint_t));
612     if (NULL == group)
613     {
614         printf("Memory allocation failed!\n");
615         CADestroyEndpoint(endpoint);
616         return;
617     }
618     group->adapter = endpoint->adapter;
619
620     // create token
621     CAToken_t token = NULL;
622     uint8_t tokenLength = CA_MAX_TOKEN_LEN;
623
624     res = CAGenerateToken(&token, tokenLength);
625     if ((CA_STATUS_OK != res) || (!token))
626     {
627         printf("Token generate error!!\n");
628         CADestroyEndpoint(endpoint);
629         free(group);
630         return;
631     }
632
633     printf("generated token %s\n", token);
634
635     CAInfo_t requestData = { 0 };
636     requestData.token = token;
637     requestData.tokenLength = tokenLength;
638     requestData.payload = (CAPayload_t) "TempJsonPayload";
639     requestData.payloadSize = strlen((const char *) requestData.payload);
640     requestData.type = CA_MSG_NONCONFIRM;
641     requestData.resourceUri = (CAURI_t)resourceURI;
642
643     CAHeaderOption_t* headerOpt = get_option_data(&requestData);
644
645     CARequestInfo_t requestInfo = { 0 };
646     requestInfo.method = CA_GET;
647     requestInfo.info = requestData;
648     requestInfo.isMulticast = true;
649
650     // send request
651     res = CASendRequest(group, &requestInfo);
652     if (CA_STATUS_OK != res)
653     {
654         printf("Could not send request to all\n");
655         CADestroyToken(token);
656     }
657     else
658     {
659         CADestroyToken(g_last_request_token);
660         g_last_request_token = token;
661     }
662
663     if (headerOpt)
664     {
665         free(headerOpt);
666     }
667
668     // destroy remote endpoint
669     CADestroyEndpoint(endpoint);
670     free(group);
671
672     printf("=============================================\n");
673 }
674
675 void send_notification()
676 {
677     CAResult_t res = get_network_type();
678     if (CA_STATUS_OK != res)
679     {
680         return;
681     }
682
683     printf("\n=============================================\n");
684     printf("Enter the URI like below....\n");
685     printf("coap://10.11.12.13:4545/resource_uri ( for IP )\n");
686     printf("coap://10:11:12:13:45:45/resource_uri ( for BT )\n");
687     printf("uri : ");
688
689     char uri[MAX_BUF_LEN] = { 0 };
690     if (CA_STATUS_OK != get_input_data(uri, MAX_BUF_LEN))
691     {
692         return;
693     }
694
695     printf("\n=============================================\n");
696     printf("\tselect message type\n");
697     printf("CON     : 0\n");
698     printf("NON     : 1\n");
699     printf("ACK     : 2\n");
700     printf("RESET   : 3\n");
701     printf("select : ");
702
703     char messageTypeBuf[MAX_BUF_LEN] = { 0 };
704     if (CA_STATUS_OK != get_input_data(messageTypeBuf, MAX_BUF_LEN))
705     {
706         return;
707     }
708
709     int messageType = messageTypeBuf[0] - '0';
710
711     CATransportFlags_t flags;
712     addressSet_t address = {};
713     parsing_coap_uri(uri, &address, &flags);
714
715     // create remote endpoint
716     CAEndpoint_t *endpoint = NULL;
717     res = CACreateEndpoint(flags, g_selected_nw_type, address.ipAddress, address.port, &endpoint);
718     if (CA_STATUS_OK != res)
719     {
720         printf("Create remote endpoint error, error code: %d\n", res);
721         return;
722     }
723
724     // create token
725     CAToken_t token = NULL;
726     uint8_t tokenLength = CA_MAX_TOKEN_LEN;
727
728     res = CAGenerateToken(&token, tokenLength);
729     if ((CA_STATUS_OK != res) || (!token))
730     {
731         printf("Token generate error!!\n");
732         CADestroyEndpoint(endpoint);
733         return;
734     }
735
736     printf("Generated token %s\n", token);
737
738     CAInfo_t respondData = { 0 };
739     respondData.token = token;
740     respondData.tokenLength = tokenLength;
741     respondData.payload = (CAPayload_t) "TempNotificationData";
742     respondData.payloadSize = strlen((const char *) respondData.payload);
743     respondData.type = messageType;
744     respondData.resourceUri = (CAURI_t)uri;
745
746     CAResponseInfo_t responseInfo = { 0 };
747     responseInfo.result = CA_CONTENT;
748     responseInfo.info = respondData;
749
750     // send request
751     res = CASendNotification(endpoint, &responseInfo);
752     if (CA_STATUS_OK != res)
753     {
754         printf("Send notification error, error code: %d\n", res);
755     }
756     else
757     {
758         printf("Send notification success\n");
759     }
760
761     // destroy token
762     CADestroyToken(token);
763     // destroy remote endpoint
764     CADestroyEndpoint(endpoint);
765
766     printf("\n=============================================\n");
767 }
768
769 void select_network()
770 {
771     printf("\n=============================================\n");
772     printf("\tselect network\n");
773     printf("IP     : 0\n");
774     printf("GATT   : 1\n");
775     printf("RFCOMM : 2\n");
776     printf("select : ");
777
778     char buf[MAX_BUF_LEN] = { 0 };
779     if (CA_STATUS_OK != get_input_data(buf, MAX_BUF_LEN))
780     {
781         return;
782     }
783
784     int number = buf[0] - '0';
785
786     if (number < 0 || number > 3)
787     {
788         printf("Invalid network type\n");
789         return;
790     }
791
792     CAResult_t res = CASelectNetwork(1 << number);
793     if (CA_STATUS_OK != res)
794     {
795         printf("Select network error\n");
796     }
797     else
798     {
799         printf("Select network success\n");
800     }
801
802     printf("=============================================\n");
803 }
804
805 void unselect_network()
806 {
807     printf("\n=============================================\n");
808     printf("\tunselect enabled network\n");
809     printf("IP     : 0\n");
810     printf("GATT   : 1\n");
811     printf("RFCOMM : 2\n");
812     printf("select : ");
813
814     char buf[MAX_BUF_LEN] = { 0 };
815     if (CA_STATUS_OK != get_input_data(buf, MAX_BUF_LEN))
816     {
817         return;
818     }
819
820     int number = buf[0] - '0';
821
822     if (number < 0 || number > 3)
823     {
824         printf("Invalid network type\n");
825         return;
826     }
827
828     CAResult_t res = CAUnSelectNetwork(1 << number);
829     if (CA_STATUS_OK != res)
830     {
831         printf("Unselect network error\n");
832     }
833     else
834     {
835         printf("Unselect network success\n");
836     }
837
838     printf("=============================================\n");
839 }
840
841 char get_menu()
842 {
843     printf("\n=============================================\n");
844     printf("\t\tMenu\n");
845     printf("\ts : start server\n");
846     printf("\tc : start client\n");
847     printf("\tr : send request\n");
848     printf("\tt : send request to all\n");
849     printf("\tb : send notification\n");
850     printf("\tn : select network\n");
851     printf("\tx : unselect network\n");
852     printf("\tg : get network information\n");
853     printf("\th : handle request response\n");
854     printf("\tz : run static server\n");
855     printf("\tw : send secure request\n");
856     printf("\tq : quit\n");
857     printf("=============================================\n");
858     printf("select : ");
859
860     char buf[MAX_BUF_LEN] = { 0 };
861     if (CA_STATUS_OK != get_input_data(buf, MAX_BUF_LEN))
862     {
863         printf("Failed to get input data\n");
864     }
865
866     return buf[0];
867 }
868
869 void handle_request_response()
870 {
871     printf("Handle_request_response\n");
872
873     CAResult_t res = CAHandleRequestResponse();
874     if (CA_STATUS_OK != res)
875     {
876         printf("Handle request error, error code: %d\n", res);
877     }
878     else
879     {
880         printf("Handle request success\n");
881     }
882 }
883
884 void get_network_info()
885 {
886     CAEndpoint_t *tempInfo = NULL;
887     uint32_t tempSize = 0;
888
889     CAResult_t res = CAGetNetworkInformation(&tempInfo, &tempSize);
890     if (CA_STATUS_OK != res || NULL == tempInfo || 0 >= tempSize)
891     {
892         printf("Network not connected\n");
893         free(tempInfo);
894         return;
895     }
896
897     printf("################## Network Information #######################\n");
898     printf("Network info total size is %d\n\n", tempSize);
899
900     int index;
901     for (index = 0; index < tempSize; index++)
902     {
903         printf("Type: %d\n", tempInfo[index].adapter);
904         if (CA_ADAPTER_IP == tempInfo[index].adapter)
905         {
906             printf("Address: %s\n", tempInfo[index].addr);
907             printf("Port: %d\n", tempInfo[index].port);
908         }
909         else if (CA_ADAPTER_RFCOMM_BTEDR == tempInfo[index].adapter)
910         {
911             printf("Address: %s\n", tempInfo[index].addr);
912         }
913         else if (CA_ADAPTER_GATT_BTLE == tempInfo[index].adapter)
914         {
915             printf("Address: %s\n", tempInfo[index].addr);
916         }
917         printf("Secured: %s\n\n", (tempInfo[index].flags & CA_SECURE) ? "true" : "false");
918
919         if (tempInfo[index].flags & CA_SECURE)
920         {
921             g_local_secure_port = tempInfo[index].port;
922             printf("Secured: in global %d\n\n", g_local_secure_port);
923         }
924     }
925
926     free(tempInfo);
927     printf("##############################################################");
928 }
929
930 void request_handler(const CAEndpoint_t *object, const CARequestInfo_t *requestInfo)
931 {
932     if (NULL == object || NULL == requestInfo)
933     {
934         printf("Input parameter is NULL\n");
935         return;
936     }
937
938     if ((NULL != g_last_request_token) && (NULL != requestInfo->info.token)
939         && (memcmp(g_last_request_token, requestInfo->info.token,
940                    CA_MAX_TOKEN_LEN) == 0))
941     {
942         printf("token is same. received request of it's own. skip.. \n");
943         return;
944     }
945
946     printf("##########received request from remote device #############\n");
947     if (CA_ADAPTER_IP == object->adapter)
948     {
949         printf("Remote Address: %s Port: %d secured:%d\n", object->addr,
950                object->port, object->flags & CA_SECURE);
951     }
952     else if (CA_ADAPTER_RFCOMM_BTEDR == object->adapter)
953     {
954         printf("Remote Address: %s \n", object->addr);
955     }
956     else if (CA_ADAPTER_GATT_BTLE == object->adapter)
957     {
958         printf("Remote Address: %s \n", object->addr);
959     }
960     printf("Data: %s\n", requestInfo->info.payload);
961     printf("Message type: %s\n", MESSAGE_TYPE[requestInfo->info.type]);
962
963     if (requestInfo->info.options)
964     {
965         uint32_t len = requestInfo->info.numOptions;
966         uint32_t i;
967         for (i = 0; i < len; i++)
968         {
969             printf("Option %d\n", i + 1);
970             printf("ID : %d\n", requestInfo->info.options[i].optionID);
971             printf("Data[%d]: %s\n", requestInfo->info.options[i].optionLength,
972                    requestInfo->info.options[i].optionData);
973         }
974     }
975     printf("############################################################\n");
976
977     //Check if this has secure communication information
978     if (requestInfo->info.payload &&
979             (CA_ADAPTER_IP == object->adapter))
980     {
981         int securePort = get_secure_information(requestInfo->info.payload);
982         if (0 < securePort) //Set the remote endpoint secure details and send response
983         {
984             printf("This is secure resource...\n");
985
986             CAEndpoint_t *endpoint = NULL;
987             if (CA_STATUS_OK != CACreateEndpoint(0, object->adapter, object->addr,
988                                                  object->port, &endpoint))
989             {
990                 printf("Failed to create duplicate of remote endpoint!\n");
991                 return;
992             }
993             endpoint->flags = CA_SECURE;
994             object = endpoint;
995         }
996     }
997
998     printf("Send response with URI\n");
999     send_response(object, &requestInfo->info);
1000
1001     g_received = 1;
1002 }
1003
1004 void response_handler(const CAEndpoint_t *object, const CAResponseInfo_t *responseInfo)
1005 {
1006     printf("##########Received response from remote device #############\n");
1007     if (CA_ADAPTER_IP == object->adapter)
1008     {
1009         printf("Remote Address: %s Port: %d secured:%d\n", object->addr,
1010                object->port, object->flags & CA_SECURE);
1011     }
1012     else if (CA_ADAPTER_RFCOMM_BTEDR == object->adapter)
1013     {
1014         printf("Remote Address: %s \n", object->addr);
1015     }
1016     else if (CA_ADAPTER_GATT_BTLE == object->adapter)
1017     {
1018         printf("Remote Address: %s \n", object->addr);
1019     }
1020     printf("response result : %d\n", responseInfo->result);
1021     printf("Data: %s\n", responseInfo->info.payload);
1022     printf("Message type: %s\n", MESSAGE_TYPE[responseInfo->info.type]);
1023     printf("Token: %s\n", responseInfo->info.token);
1024     if (responseInfo->info.options)
1025     {
1026         uint32_t len = responseInfo->info.numOptions;
1027         uint32_t i;
1028         for (i = 0; i < len; i++)
1029         {
1030             printf("Option %d\n", i + 1);
1031             printf("ID : %d\n", responseInfo->info.options[i].optionID);
1032             printf("Data[%d]: %s\n", responseInfo->info.options[i].optionLength,
1033                    responseInfo->info.options[i].optionData);
1034         }
1035     }
1036     printf("############################################################\n");
1037     g_received = 1;
1038
1039     //Check if this has secure communication information
1040     if (responseInfo->info.payload)
1041     {
1042         int securePort = get_secure_information(responseInfo->info.payload);
1043         if (0 < securePort) //Set the remote endpoint secure details and send response
1044         {
1045             printf("This is secure resource...\n");
1046         }
1047     }
1048 }
1049
1050 void error_handler(const CAEndpoint_t *rep, const CAErrorInfo_t* errorInfo)
1051 {
1052     printf("+++++++++++++++++++++++++++++++++++ErrorInfo+++++++++++++++++++++++++++++++++++\n");
1053
1054     if(errorInfo)
1055     {
1056         const CAInfo_t *info = &errorInfo->info;
1057         printf("Error Handler, ErrorInfo :\n");
1058         printf("Error Handler result    : %d\n", errorInfo->result);
1059         printf("Error Handler token     : %s\n", info->token);
1060         printf("Error Handler messageId : %d\n", (uint16_t) info->messageId);
1061         printf("Error Handler type      : %d\n", info->type);
1062         printf("Error Handler resourceUri : %s\n", info->resourceUri);
1063         printf("Error Handler payload   : %s\n", info->payload);
1064
1065         if(CA_ADAPTER_NOT_ENABLED == errorInfo->result)
1066         {
1067             printf("CA_ADAPTER_NOT_ENABLED, enable the adapter\n");
1068         }
1069         else if(CA_SEND_FAILED == errorInfo->result)
1070         {
1071             printf("CA_SEND_FAILED, unable to send the message, check parameters\n");
1072         }
1073         else if(CA_MEMORY_ALLOC_FAILED == errorInfo->result)
1074         {
1075             printf("CA_MEMORY_ALLOC_FAILED, insufficient memory\n");
1076         }
1077         else if(CA_SOCKET_OPERATION_FAILED == errorInfo->result)
1078         {
1079             printf("CA_SOCKET_OPERATION_FAILED, socket operation failed\n");
1080         }
1081         else if(CA_STATUS_FAILED == errorInfo->result)
1082         {
1083             printf("CA_STATUS_FAILED, message could not be delivered, internal error\n");
1084         }
1085     }
1086     printf("++++++++++++++++++++++++++++++++End of ErrorInfo++++++++++++++++++++++++++++++++\n");
1087
1088     return;
1089 }
1090
1091 void send_response(const CAEndpoint_t *endpoint, const CAInfo_t *info)
1092 {
1093     printf("entering send_response\n");
1094
1095     printf("\n=============================================\n");
1096     printf("\tselect message type\n");
1097     printf("CON     : 0\n");
1098     printf("NON     : 1\n");
1099     printf("ACK     : 2\n");
1100     printf("RESET   : 3\n");
1101     printf("select : ");
1102
1103     char buf[MAX_BUF_LEN] = { 0 };
1104     if (CA_STATUS_OK != get_input_data(buf, MAX_BUF_LEN))
1105     {
1106         return;
1107     }
1108
1109     int messageType = buf[0] - '0';
1110     if (0 > messageType || 3 < messageType)
1111     {
1112         printf("Invalid message type\n");
1113         return;
1114     }
1115
1116     int responseCode = 0 ;
1117     char responseCodeBuf[MAX_BUF_LEN] = { 0 };
1118     if (CA_MSG_RESET != messageType)
1119     {
1120         printf("\n=============================================\n");
1121         printf("\tselect response code\n");
1122         printf("EMPTY                    :   0\n");
1123         printf("SUCCESS                  : 200\n");
1124         printf("CREATED                  : 201\n");
1125         printf("DELETED                  : 202\n");
1126         printf("VALID                    : 203\n");
1127         printf("CHANGED                  : 204\n");
1128         printf("CONTENT                  : 205\n");
1129         printf("BAD_REQ                  : 400\n");
1130         printf("BAD_OPT                  : 402\n");
1131         printf("NOT_FOUND                : 404\n");
1132         printf("INTERNAL_SERVER_ERROR    : 500\n");
1133         printf("RETRANSMIT_TIMEOUT       : 504\n");
1134         printf("select : ");
1135
1136         if (CA_STATUS_OK != get_input_data(responseCodeBuf, MAX_BUF_LEN))
1137         {
1138             return;
1139         }
1140         responseCode = atoi(responseCodeBuf);
1141     }
1142     CAInfo_t responseData = { 0 };
1143     responseData.type = messageType;
1144     responseData.messageId = (info != NULL) ? info->messageId : 0;
1145     responseData.resourceUri = (info != NULL) ? info->resourceUri : 0;
1146
1147     if(CA_MSG_RESET != messageType)
1148     {
1149         responseData.token = (info != NULL) ? info->token : NULL;
1150         responseData.tokenLength = (info != NULL) ? info->tokenLength : 0;
1151
1152         if (endpoint->flags & CA_SECURE)
1153         {
1154             printf("Sending response on secure communication\n");
1155
1156             uint32_t length = sizeof(SECURE_INFO_DATA) + strlen(responseData.resourceUri);
1157             responseData.payload = (CAPayload_t) calloc(length,  sizeof(char));
1158             if (NULL == responseData.payload)
1159             {
1160                 printf("Memory allocation fail\n");
1161                 return;
1162             }
1163             snprintf((char *) responseData.payload, length, SECURE_INFO_DATA,
1164                      (const char *) responseData.resourceUri, g_local_secure_port);
1165             responseData.payloadSize = length;
1166         }
1167         else
1168         {
1169             printf("Sending response on non-secure communication\n");
1170
1171             uint32_t length = sizeof(NORMAL_INFO_DATA) + strlen(responseData.resourceUri);
1172             responseData.payload = (CAPayload_t) calloc(length, sizeof(char));
1173             if (NULL == responseData.payload)
1174             {
1175                 printf("Memory allocation fail\n");
1176                 return;
1177             }
1178             snprintf((char *) responseData.payload, length, NORMAL_INFO_DATA,
1179                      (const char *) responseData.resourceUri);
1180             responseData.payloadSize = length;
1181         }
1182     }
1183
1184     CAResponseInfo_t responseInfo = { 0 };
1185     responseInfo.result = responseCode;
1186     responseInfo.info = responseData;
1187
1188     // send response (transportType from remoteEndpoint of request Info)
1189     CAResult_t res = CASendResponse(endpoint, &responseInfo);
1190     if (CA_STATUS_OK != res)
1191     {
1192         printf("Send response error\n");
1193     }
1194     else
1195     {
1196         printf("Send response success\n");
1197     }
1198
1199     if (responseData.payload)
1200     {
1201         free(responseData.payload);
1202     }
1203
1204     printf("=============================================\n");
1205 }
1206
1207 int get_secure_information(CAPayload_t payLoad)
1208 {
1209     printf("Entering get_secure_information\n");
1210
1211     if (!payLoad)
1212     {
1213         printf("Payload is NULL\n");
1214         return -1;
1215     }
1216
1217     char *subString = NULL;
1218     if (NULL == (subString = strstr((const char *) payLoad, "\"sec\":1")))
1219     {
1220         printf("This is not secure resource\n");
1221         return -1;
1222     }
1223
1224     if (NULL == (subString = strstr((const char *) payLoad, "\"port\":")))
1225     {
1226         printf("This secure resource does not have port information\n");
1227         return -1;
1228     }
1229
1230     char *startPos = strstr(subString, ":");
1231     if (!startPos)
1232     {
1233         printf("Parsing failed !\n");
1234         return -1;
1235     }
1236
1237     char *endPos = strstr(startPos, "}");
1238     if (!endPos)
1239     {
1240         printf("Parsing failed !\n");
1241         return -1;
1242     }
1243
1244     char portStr[6] = {0};
1245     memcpy(portStr, startPos + 1, (endPos - 1) - startPos);
1246
1247     printf("secured port is: %s\n", portStr);
1248     return atoi(portStr);
1249 }
1250
1251 void get_resource_uri(char *URI, char *resourceURI, int length)
1252 {
1253     char *startPos = URI;
1254     char *temp = NULL;
1255     if (NULL != (temp = strstr(URI, "://")))
1256     {
1257         startPos = strchr(temp + 3, '/');
1258         if (!startPos)
1259         {
1260             printf("Resource URI is missing\n");
1261             return;
1262         }
1263     }
1264
1265     char *endPos = strchr(startPos, '?');
1266     if (!endPos)
1267     {
1268         endPos = URI + strlen(URI);
1269     }
1270     endPos -= 1;
1271
1272     if (endPos - startPos <= length)
1273     {
1274         memcpy(resourceURI, startPos + 1, endPos - startPos);
1275     }
1276
1277     printf("URI: %s, ResourceURI:%s\n", URI, resourceURI);
1278 }
1279
1280 CAResult_t get_network_type()
1281 {
1282     char buf[MAX_BUF_LEN] = { 0 };
1283
1284     printf("\n=============================================\n");
1285     printf("\tselect network type\n");
1286     printf("IP     : 0\n");
1287     printf("GATT   : 1\n");
1288     printf("RFCOMM : 2\n");
1289     printf("select : ");
1290
1291     if (CA_STATUS_OK != get_input_data(buf, MAX_BUF_LEN))
1292     {
1293         return CA_NOT_SUPPORTED ;
1294     }
1295
1296     int number = buf[0] - '0';
1297
1298     number = (number < 0 || number > 3) ? 0 : 1 << number;
1299
1300     if (number == 1)
1301     {
1302         g_selected_nw_type = CA_ADAPTER_IP;
1303         return CA_STATUS_OK;
1304     }
1305     if (number == 2)
1306     {
1307         g_selected_nw_type = CA_ADAPTER_GATT_BTLE;
1308         return CA_STATUS_OK;
1309     }
1310     if (number == 3)
1311     {
1312         g_selected_nw_type = CA_ADAPTER_RFCOMM_BTEDR;
1313         return CA_STATUS_OK;
1314     }
1315
1316     return CA_NOT_SUPPORTED;
1317 }
1318
1319 CAResult_t get_input_data(char *buf, int32_t length)
1320 {
1321     if (!fgets(buf, length, stdin))
1322     {
1323         printf("fgets error\n");
1324         return CA_STATUS_FAILED;
1325     }
1326
1327     char *p = NULL;
1328     if ( (p = strchr(buf, '\n')) != NULL )
1329     {
1330         *p = '\0';
1331     }
1332
1333     return CA_STATUS_OK;
1334 }
1335
1336 CAHeaderOption_t* get_option_data(CAInfo_t* requestData)
1337 {
1338     char optionNumBuf[MAX_BUF_LEN] = { 0 };
1339     char optionData[MAX_OPT_LEN] = { 0 } ;
1340
1341     printf("Option Num : ");
1342     if (CA_STATUS_OK != get_input_data(optionNumBuf, MAX_BUF_LEN))
1343     {
1344         return NULL;
1345     }
1346     int optionNum = atoi(optionNumBuf);
1347
1348     CAHeaderOption_t * headerOpt = NULL;
1349     if (0 >= optionNum)
1350     {
1351         printf("there is no headerOption!\n");
1352         return NULL;
1353     }
1354     else
1355     {
1356         headerOpt = (CAHeaderOption_t *)calloc(1, optionNum * sizeof(CAHeaderOption_t));
1357         if (NULL == headerOpt)
1358         {
1359             printf("Memory allocation failed!\n");
1360             return NULL;
1361         }
1362
1363         int i;
1364         for (i = 0; i < optionNum; i++)
1365         {
1366             char getOptionID[MAX_BUF_LEN] = { 0 } ;
1367
1368             printf("[%d] Option ID : ", i + 1);
1369             if (CA_STATUS_OK != get_input_data(getOptionID, MAX_BUF_LEN))
1370             {
1371                 free(headerOpt);
1372                 return NULL;
1373             }
1374             int optionID = atoi(getOptionID);
1375             headerOpt[i].optionID = optionID;
1376
1377             printf("[%d] Option Data : ", i + 1);
1378             if (CA_STATUS_OK != get_input_data(optionData, MAX_OPT_LEN))
1379             {
1380                 free(headerOpt);
1381                 return NULL;
1382             }
1383
1384             memcpy(headerOpt[i].optionData, optionData, strlen(optionData));
1385
1386             headerOpt[i].optionLength = (uint16_t) strlen(optionData);
1387         }
1388         requestData->numOptions = optionNum;
1389         requestData->options = headerOpt;
1390     }
1391     return headerOpt;
1392 }
1393
1394 void parsing_coap_uri(const char* uri, addressSet_t* address, CATransportFlags_t *flags)
1395 {
1396     if (NULL == uri)
1397     {
1398         printf("parameter is null\n");
1399         return;
1400     }
1401
1402     // parse uri
1403     // #1. check prefix
1404     uint8_t startIndex = 0;
1405     if (strncmp(COAPS_PREFIX, uri, COAPS_PREFIX_LEN) == 0)
1406     {
1407         printf("uri has '%s' prefix\n", COAPS_PREFIX);
1408         startIndex = COAPS_PREFIX_LEN;
1409         *flags = CA_SECURE;
1410     }
1411     else if (strncmp(COAP_PREFIX, uri, COAP_PREFIX_LEN) == 0)
1412     {
1413         printf("uri has '%s' prefix\n", COAP_PREFIX);
1414         startIndex = COAP_PREFIX_LEN;
1415         *flags = CA_DEFAULT_FLAGS;
1416     }
1417
1418     // #2. copy uri for parse
1419     int32_t len = strlen(uri) - startIndex;
1420
1421     if (len <= 0)
1422     {
1423         printf("uri length is 0!\n");
1424         return;
1425     }
1426
1427     char *cloneUri = (char *) calloc(len + 1, sizeof(char));
1428     if (NULL == cloneUri)
1429     {
1430         printf("Out of memory\n");
1431         return;
1432     }
1433
1434     memcpy(cloneUri, &uri[startIndex], sizeof(char) * len);
1435     cloneUri[len] = '\0';
1436
1437     char *pAddress = cloneUri;
1438     printf("pAddress : %s\n", pAddress);
1439
1440     int res = get_address_set(pAddress, address);
1441     if (res == -1)
1442     {
1443         printf("address parse error\n");
1444
1445         free(cloneUri);
1446         return;
1447     }
1448     free(cloneUri);
1449     return;
1450 }
1451
1452 int get_address_set(const char *pAddress, addressSet_t* outAddress)
1453 {
1454     if (NULL == pAddress)
1455     {
1456         printf("parameter is null !\n");
1457         return -1;
1458     }
1459
1460     int32_t len = strlen(pAddress);
1461     int32_t isIp = 0;
1462     int32_t ipLen = 0;
1463
1464     for (int i = 0; i < len; i++)
1465     {
1466         if (pAddress[i] == '.')
1467         {
1468             isIp = 1;
1469         }
1470
1471         // found port number start index
1472         if (isIp && pAddress[i] == ':')
1473         {
1474             ipLen = i;
1475             break;
1476         }
1477     }
1478
1479     if (isIp)
1480     {
1481         if(ipLen && ipLen < sizeof(outAddress->ipAddress))
1482         {
1483             strncpy(outAddress->ipAddress, pAddress, ipLen);
1484             outAddress->ipAddress[ipLen] = '\0';
1485         }
1486         else if (!ipLen && len < sizeof(outAddress->ipAddress))
1487         {
1488             strncpy(outAddress->ipAddress, pAddress, len);
1489             outAddress->ipAddress[len] = '\0';
1490         }
1491         else
1492         {
1493             printf("IP Address too long: %d\n", ipLen==0 ? len : ipLen);
1494             return -1;
1495         }
1496
1497         if (ipLen > 0)
1498         {
1499             outAddress->port = atoi(pAddress + ipLen + 1);
1500         }
1501     }
1502
1503     return isIp;
1504 }