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