Integrated CA layer and RI layer for DTLS security
[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 "cacommon.h"
27 #include "cainterface.h"
28 #include "ocsecurityconfig.h"
29
30
31 #define MAX_BUF_LEN 1024
32 #define MAX_OPT_LEN 16
33 #define TRUE 1
34 #define FALSE 0
35
36 /**
37  * @def RS_IDENTITY
38  * @brief
39  */
40 #define IDENTITY     ("1111111111111111")
41 /* @def RS_CLIENT_PSK
42  * @brief
43  */
44 #define RS_CLIENT_PSK   ("AAAAAAAAAAAAAAAA")
45
46
47 int gReceived;
48 CABool_t gLocalUnicastPort;
49 CABool_t gLocalSecurePort;
50 CAConnectivityType_t gSelectedNwType = CA_ETHERNET;
51
52 char get_menu();
53 void process();
54 CAResult_t get_network_type();
55
56 void start_listening_server();
57 void start_discovery_server();
58 void find_resource();
59 void send_request();
60 void send_request_all();
61 void send_response();
62 void advertise_resource();
63 void send_notification();
64 void select_network();
65 void unselect_network();
66 void handle_request_response();
67 void find_fixed_resource();
68 void get_network_info();
69 void send_secure_request();
70
71 void request_handler(const CARemoteEndpoint_t *object, const CARequestInfo_t *requestInfo);
72 void response_handler(const CARemoteEndpoint_t *object, const CAResponseInfo_t *responseInfo);
73 void send_request_tmp(CARemoteEndpoint_t *endpoint, CAToken_t token);
74 void get_resource_uri(char *URI, char *resourceURI, int length);
75 int get_secure_information(CAPayload_t payLoad);
76
77 static CAToken_t gLastRequestToken = NULL;
78 static const char *gSecureInfoData = "{\"oc\":[{\"href\":\"%s\",\"prop\":{\"rt\":[\"core.led\"],"
79                                      "\"if\":[\"oc.mi.def\"],\"obs\":1,\"sec\":1,\"port\":%d}}]}";
80 static const char *gNormalInfoData = "{\"oc\":[{\"href\":\"%s\",\"prop\":{\"rt\":[\"core.led\"],"
81                                      "\"if\":[\"oc.mi.def\"],\"obs\":1}}]}";
82
83 static OCDtlsPskCredsBlob *pskCredsBlob = NULL;
84
85 void clearDtlsCredentialInfo()
86 {
87     printf("clearDtlsCredentialInfo IN\n");
88     if (pskCredsBlob)
89     {
90         // Zero out sensitive data before freeing.
91         if (pskCredsBlob->num)
92         {
93             memset(pskCredsBlob->creds, 0,
94                     sizeof(OCDtlsPskCredsBlob) + (sizeof(OCDtlsPskCreds)*(pskCredsBlob->num - 1)));
95         }
96         free(pskCredsBlob->creds);
97         pskCredsBlob = NULL;
98     }
99     printf("clearDtlsCredentialInfo OUT\n");
100 }
101
102 // Internal API. Invoked by OC stack to retrieve credentials from this module
103 void OCGetDtlsPskCredentials(OCDtlsPskCredsBlob **credInfo)
104 {
105     printf("OCGetDtlsPskCredentials IN\n");
106
107     *credInfo = pskCredsBlob;
108
109     printf("OCGetDtlsPskCredentials OUT\n");
110 }
111
112 int32_t SetCredentials()
113 {
114     int32_t ret = 0;
115     printf("SetCredentials IN\n");
116     pskCredsBlob = (OCDtlsPskCredsBlob *)malloc(sizeof(OCDtlsPskCredsBlob));
117
118     if (pskCredsBlob)
119     {
120         memset(pskCredsBlob, 0x0, sizeof(OCDtlsPskCredsBlob));
121         pskCredsBlob->num = DtlsPskCredsBlobVer_CurrentVersion;
122         memcpy(pskCredsBlob->identity, IDENTITY, DTLS_PSK_ID_LEN);
123
124         pskCredsBlob->num = 1;
125
126         memcpy(pskCredsBlob->creds[0].id, IDENTITY, DTLS_PSK_ID_LEN);
127         memcpy(pskCredsBlob->creds[0].psk, RS_CLIENT_PSK, DTLS_PSK_PSK_LEN);
128
129         ret = 1;
130     }
131
132     printf("SetCredentials OUT\n");
133     return ret;
134 }
135
136 int main()
137 {
138     system("clear");
139
140     printf("=============================================\n");
141     printf("\t\tsample main\n");
142     printf("=============================================\n");
143
144     /*
145     * Read DTLS PSK credentials from persistent storage and
146     * set in the OC stack.
147     */
148     if (SetCredentials() == 0)
149     {
150         printf("SetCredentials failed\n");
151         return 0;
152     }
153
154     CAResult_t res = CAInitialize();
155     if (res != CA_STATUS_OK)
156     {
157         printf("CAInitialize fail\n");
158         return 0;
159     }
160
161 #if 0
162     // network enable
163     // default
164     printf("select default network(WIFI)\n");
165     res = CASelectNetwork(CA_WIFI);
166     if (res != CA_STATUS_OK)
167     {
168         printf("CASelectNetwork fail\n");
169         return 0;
170     }
171 #endif
172
173     // set handler.
174     res = CARegisterHandler(request_handler, response_handler);
175     if (res != CA_STATUS_OK)
176     {
177         printf("CARegisterHandler fail\n");
178         return 0;
179     }
180
181     process();
182
183     CATerminate();
184     clearDtlsCredentialInfo();
185
186     return 0;
187 }
188
189 void process()
190 {
191     while (1)
192     {
193         char menu = get_menu();
194
195         switch (menu)
196         {
197             case 'm': // menu
198             case 'M':
199                 continue;
200
201             case 'q': // quit
202             case 'Q':
203                 printf("quit..!!\n");
204                 return;
205
206             case 's': // start server
207             case 'S':
208                 start_listening_server();
209                 break;
210
211             case 't': // send request
212             case 'T':
213                 send_request_all();
214                 break;
215
216             case 'c': // start client
217             case 'D':
218                 start_discovery_server();
219                 break;
220
221             case 'f': // find resource
222             case 'F':
223                 find_resource();
224                 break;
225
226             case 'r': // send request
227             case 'R':
228                 send_request();
229                 break;
230
231             case 'a': // advertise resource
232             case 'A':
233                 advertise_resource();
234                 break;
235
236             case 'b': // send notification
237             case 'B':
238                 send_notification();
239                 break;
240
241             case 'n': // select network
242             case 'N':
243                 select_network();
244                 break;
245
246             case 'x': // unselect network
247             case 'X':
248                 unselect_network();
249                 break;
250
251             case 'h': // handle request response
252             case 'H':
253                 handle_request_response();
254                 break;
255             case 'y':
256             case 'Y':
257                 while (1)
258                 {
259                     gReceived = 0;
260                     find_fixed_resource();
261                     while (gReceived == 0)
262                     {
263                         sleep(1);
264                         handle_request_response();
265
266                     }
267                 }
268                 break;
269
270             case 'w':
271             case 'W':
272                 gReceived = 0;
273                 start_discovery_server();
274                 send_secure_request();
275                 while (gReceived == 0)
276                 {
277                     sleep(1);
278                     handle_request_response();
279                 }
280
281                 break;
282
283             case 'z':
284             case 'Z':
285                 start_listening_server();
286                 while (1)
287                 {
288                     sleep(1);
289                     handle_request_response();
290                 }
291                 break;
292
293             case 'g': // get network information
294             case 'G':
295                 get_network_info();
296                 break;
297
298             default:
299                 printf("not supported menu!!\n");
300                 break;
301         }
302     }
303
304 }
305
306
307
308 void start_listening_server()
309 {
310     printf("start listening server!!\n");
311
312     CAResult_t res = CAStartListeningServer();
313     if (res != CA_STATUS_OK)
314     {
315         printf("start listening server fail\n");
316     }
317     else
318     {
319         printf("start listening server success\n");
320     }
321 }
322
323 void start_discovery_server()
324 {
325     printf("start discovery client!!\n");
326
327     CAResult_t res = CAStartDiscoveryServer();
328     if (res != CA_STATUS_OK)
329     {
330         printf("start discovery client fail\n");
331     }
332     else
333     {
334         printf("start discovery client success\n");
335     }
336 }
337
338 void find_fixed_resource()
339 {
340     char buf[MAX_BUF_LEN] =
341     { 0, };
342     strcpy(buf, "/a/light");
343
344     // create token
345     CAToken_t token = NULL;
346     CAResult_t res = CAGenerateToken(&token);
347     if (res != CA_STATUS_OK)
348     {
349         printf("token generate error!!");
350         token = NULL;
351     }
352
353     printf("generated token %s\n", (token != NULL) ? token : "");
354
355     res = CAFindResource(buf, token);
356     if (res != CA_STATUS_OK)
357     {
358         printf("find resource error!!\n");
359     }
360     else
361     {
362         printf("find resource to %s URI\n", buf);
363     }
364
365     // delete token
366     /*
367      if (token != NULL)
368      {
369      CADestroyToken(token);
370      }
371      */
372
373     printf("=============================================\n");
374 }
375
376 void find_resource()
377 {
378     char buf[MAX_BUF_LEN];
379
380     memset(buf, 0, sizeof(char) * MAX_BUF_LEN);
381
382     printf("\n=============================================\n");
383     printf("ex) /a/light\n");
384     printf("reference uri : ");
385
386     gets(buf);
387
388     // create token
389     CAToken_t token = NULL;
390     CAResult_t res = CAGenerateToken(&token);
391     if (res != CA_STATUS_OK)
392     {
393         printf("token generate error!!\n");
394         token = NULL;
395     }
396
397     printf("generated token %s\n", (token != NULL) ? token : "");
398
399     res = CAFindResource(buf, token);
400     if (res != CA_STATUS_OK)
401     {
402         printf("find resource error!!\n");
403     }
404     else
405     {
406         printf("find resource to %s URI\n", buf);
407
408         gLastRequestToken = token;
409     }
410
411     // delete token
412     /*
413      if (token != NULL)
414      {
415      CADestroyToken(token);
416      }
417      */
418
419     printf("=============================================\n");
420 }
421
422 void send_request()
423 {
424     char secureRequest[2] = {0};
425     CAResult_t res;
426
427     res = get_network_type();
428     if (res != CA_STATUS_OK)
429     {
430         return;
431     }
432
433     printf("Do you want to send secure request ?.... enter (0/1): ");
434     gets(secureRequest);
435     if ('1' == secureRequest[0])
436     {
437         printf("Enter the URI like below....\n");
438         printf("coaps://10.11.12.13:4545/resource_uri ( for IP secure)\n");
439     }
440     else
441     {
442         printf("Enter the URI like below....\n");
443         printf("coap://10.11.12.13:4545/resource_uri ( for IP )\n");
444         printf("coap://10:11:12:13:45:45/resource_uri ( for BT )\n");
445     }
446
447     char uri[MAX_BUF_LEN] = {'\0'};
448     gets(uri);
449
450     // create remote endpoint
451     CARemoteEndpoint_t *endpoint = NULL;
452     if (CA_STATUS_OK != CACreateRemoteEndpoint(uri, gSelectedNwType, &endpoint)
453         || !endpoint)
454     {
455         printf("Failed to create remote endpoint!\n");
456         CADestroyRemoteEndpoint(endpoint);
457         return;
458     }
459
460     //endpoint->connectivityType = gSelectedNwType;
461
462     char buf[MAX_BUF_LEN];
463     memset(buf, 0, sizeof(char) * MAX_BUF_LEN);
464
465     printf("\n=============================================\n");
466     printf("0:CON, 1:NON\n");
467     printf("select message type : ");
468
469     gets(buf);
470
471     CAMessageType_t msgType = (buf[0] == '0' || buf[0] == '1') ? buf[0] - '0' : 0;
472
473     // create token
474     CAToken_t token = NULL;
475     if (CA_STATUS_OK != CAGenerateToken(&token))
476     {
477         printf("token generate error!!\n");
478         token = NULL;
479     }
480
481     printf("generated token %s\n", (token != NULL) ? token : "");
482
483     // extract relative resourceuri from give uri
484     char resourceURI[15] = {0};
485
486     printf("URI : %s\n", uri);
487     get_resource_uri(uri, resourceURI, 14);
488
489     // create request data
490     CAInfo_t requestData;
491     memset(&requestData, 0, sizeof(CAInfo_t));
492     requestData.token = token;
493     if ('1' == secureRequest[0])
494     {
495         int length = strlen(resourceURI) + 1;
496         requestData.payload = (CAPayload_t) malloc(length);
497         sprintf(requestData.payload, gSecureInfoData, resourceURI, gLocalSecurePort);
498     }
499     else
500     {
501         int length = strlen(gNormalInfoData) + strlen(resourceURI) + 1;
502         requestData.payload = (CAPayload_t) malloc(length);
503         sprintf(requestData.payload, gNormalInfoData, resourceURI);
504     }
505     requestData.type = msgType;
506
507     CARequestInfo_t requestInfo;
508     memset(&requestInfo, 0, sizeof(CARequestInfo_t));
509     requestInfo.method = CA_GET;
510     requestInfo.info = requestData;
511
512     // send request
513     CASendRequest(endpoint, &requestInfo);
514
515     if (token != NULL)
516     {
517         CADestroyToken(token);
518     }
519
520     // destroy remote endpoint
521     CADestroyRemoteEndpoint(endpoint);
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("Enter IPv4 address of the source hosting secure resource (Ex: 11.12.13.14)\n");
531
532     fgets(ipv4addr, CA_IPADDR_SIZE, stdin);
533     snprintf(uri, MAX_BUF_LEN, "coaps://%s:5684/a/light", ipv4addr);
534
535     printf("\n=============================================\n");
536     // create remote endpoint
537     CARemoteEndpoint_t *endpoint = NULL;
538     if (CA_STATUS_OK != CACreateRemoteEndpoint(uri, CA_ETHERNET, &endpoint))
539     {
540         printf("Failed to create remote endpoint!\n");
541         goto exit;
542     }
543
544     // create token
545     CAToken_t token = NULL;
546     if (CA_STATUS_OK != CAGenerateToken(&token))
547     {
548         printf("Failed to generate token !\n");
549         goto exit;
550     }
551
552     // create request data
553     CAMessageType_t msgType = CA_MSG_NONCONFIRM;
554     CAInfo_t requestData;
555     memset(&requestData, 0, sizeof(CAInfo_t));
556     requestData.token = token;
557     requestData.type = msgType;
558
559     CARequestInfo_t requestInfo;
560     memset(&requestInfo, 0, sizeof(CARequestInfo_t));
561     requestInfo.method = CA_GET;
562     requestInfo.info = requestData;
563
564     // send request
565     CASendRequest(endpoint, &requestInfo);
566
567 exit:
568     // cleanup
569     CADestroyToken(token);
570     CADestroyRemoteEndpoint(endpoint);
571     printf("=============================================\n");
572 }
573
574
575 void send_request_all()
576 {
577     char buf[MAX_BUF_LEN];
578     memset(buf, 0, sizeof(char) * MAX_BUF_LEN);
579
580     CAResult_t res;
581
582     res = get_network_type();
583     if (res != CA_STATUS_OK)
584     {
585         return;
586     }
587
588     printf("\n=============================================\n");
589     printf("10.11.12.13:4545/resource_uri ( for IP )\n");
590     printf("10:11:12:13:45:45/resource_uri ( for BT )\n");
591     printf("uri : ");
592
593     gets(buf);
594
595     // create remote endpoint
596     CARemoteEndpoint_t *endpoint = NULL;
597     res = CACreateRemoteEndpoint(buf, gSelectedNwType, &endpoint);
598
599     if (res != CA_STATUS_OK)
600     {
601         printf("create remote endpoint error!!\n");
602         CADestroyRemoteEndpoint(endpoint);
603         return;
604     }
605
606
607     CAGroupEndpoint_t *group = NULL;
608     group = (CAGroupEndpoint_t *)malloc(sizeof(CAGroupEndpoint_t));
609     group->connectivityType = endpoint->connectivityType;
610     group->resourceUri = endpoint->resourceUri;
611
612
613     // create token
614     CAToken_t token = NULL;
615     res = CAGenerateToken(&token);
616
617     if (res != CA_STATUS_OK)
618     {
619         printf("token generate error!!\n");
620         token = NULL;
621     }
622
623     printf("generated token %s\n", (token != NULL) ? token : "");
624
625     CAInfo_t requestData;
626     memset(&requestData, 0, sizeof(CAInfo_t));
627     requestData.token = token;
628     requestData.payload = "Temp Json Payload";
629
630     CARequestInfo_t requestInfo;
631     memset(&requestInfo, 0, sizeof(CARequestInfo_t));
632     requestInfo.method = CA_GET;
633     requestInfo.info = requestData;
634
635     // send request
636     // CASendRequest(endpoint, &requestInfo);
637     CASendRequestToAll(group, &requestInfo);
638
639     if (token != NULL)
640     {
641         CADestroyToken(token);
642     }
643
644     // destroy remote endpoint
645     if (endpoint != NULL)
646     {
647         CADestroyRemoteEndpoint(endpoint);
648     }
649
650     free(group);
651
652     printf("=============================================\n");
653 }
654
655 void advertise_resource()
656 {
657     char buf[MAX_BUF_LEN];
658
659     memset(buf, 0, sizeof(char) * MAX_BUF_LEN);
660
661     printf("\n=============================================\n");
662     printf("uri : ");
663
664     scanf("%s", buf);
665
666     int optionNum = 0;
667     char optionData[MAX_OPT_LEN];
668
669     printf("Option Num : ");
670     scanf("%d", &optionNum);
671     CAHeaderOption_t *headerOpt;
672     headerOpt = (CAHeaderOption_t *) malloc(sizeof(CAHeaderOption_t) * optionNum);
673     if (NULL == headerOpt)
674     {
675         printf("Memory allocation failed!\n");
676         return;
677     }
678     memset(headerOpt, 0, sizeof(CAHeaderOption_t) * optionNum);
679
680     int i;
681     for (i = 0; i < optionNum; i++)
682     {
683         int optionID = 0;
684         printf("[%d] Option ID : ", i + 1);
685         scanf("%d", &optionID);
686         headerOpt[i].optionID = optionID;
687
688         memset(optionData, 0, sizeof(char) * MAX_OPT_LEN);
689         printf("[%d] Option Data : ", i + 1);
690         scanf("%s", optionData);
691         memcpy(headerOpt[i].optionData, optionData, strlen(optionData));
692         printf("[%d] inputed option : ID : %d, data : %s\n", i + 1, optionID, optionData);
693
694         headerOpt[i].optionLength = (uint16_t) strlen(optionData);
695     }
696     printf("\n=============================================\n");
697
698     // create token
699     CAToken_t token = NULL;
700     CAResult_t res = CAGenerateToken(&token);
701     if (res != CA_STATUS_OK)
702     {
703         printf("token generate error!!\n");
704         token = NULL;
705     }
706
707     printf("generated token %s\n", (token != NULL) ? token : "");
708
709     CAAdvertiseResource(buf, token, headerOpt, (uint8_t) optionNum);
710
711     // delete token
712     /*
713      if (token != NULL)
714      {
715      CADestroyToken(token);
716      }
717      */
718
719     free(headerOpt);
720
721 }
722
723 void send_notification()
724 {
725     char buf[MAX_BUF_LEN];
726     memset(buf, 0, sizeof(char) * MAX_BUF_LEN);
727
728     CAResult_t res;
729
730     res = get_network_type();
731     if (res != CA_STATUS_OK)
732     {
733         return;
734     }
735
736     printf("\n=============================================\n");
737     printf("10.11.12.13:4545/resource_uri ( for IP )\n");
738     printf("10:11:12:13:45:45/resource_uri ( for BT )\n");
739     printf("uri : ");
740
741     gets(buf);
742
743     // create remote endpoint
744     CARemoteEndpoint_t *endpoint = NULL;
745     res = CACreateRemoteEndpoint(buf, gSelectedNwType, &endpoint);
746
747     if (res != CA_STATUS_OK)
748     {
749         printf("create remote endpoint error!!\n");
750         CADestroyRemoteEndpoint(endpoint);
751         return;
752     }
753
754     CAInfo_t respondeData;
755     memset(&respondeData, 0, sizeof(CAInfo_t));
756     respondeData.token = "client token";
757     respondeData.payload = "Temp Notification Data";
758
759     CAResponseInfo_t responseInfo;
760     memset(&responseInfo, 0, sizeof(CAResponseInfo_t));
761     responseInfo.result = CA_SUCCESS;
762     responseInfo.info = respondeData;
763
764     // send request
765     res = CASendNotification(endpoint, &responseInfo);
766     if (res != CA_STATUS_OK)
767     {
768         printf("send notification error\n");
769     }
770     else
771     {
772         printf("send notification success\n");
773     }
774
775     // destroy remote endpoint
776     if (endpoint != NULL)
777     {
778         CADestroyRemoteEndpoint(endpoint);
779     }
780
781     printf("\n=============================================\n");
782 }
783
784 void select_network()
785 {
786     char buf[MAX_BUF_LEN];
787
788     printf("\n=============================================\n");
789     printf("\tselect network\n");
790     printf("ETHERNET : 0\n");
791     printf("WIFI : 1\n");
792     printf("EDR : 2\n");
793     printf("LE : 3\n");
794     printf("select : ");
795
796     memset(buf, 0, sizeof(char) * MAX_BUF_LEN);
797     gets(buf);
798
799     int number = buf[0] - '0';
800
801     number = (number < 0 || number > 3) ? 0 : number;
802
803     CAResult_t res = CASelectNetwork(1 << number);
804     if (res != CA_STATUS_OK)
805     {
806         printf("select network error\n");
807         gSelectedNwType = 1 << number;
808     }
809     else
810     {
811         printf("select network success\n");
812     }
813
814     printf("=============================================\n");
815 }
816
817 void unselect_network()
818 {
819     char buf[MAX_BUF_LEN];
820
821     printf("\n=============================================\n");
822     printf("\tunselect enabled network\n");
823     printf("ETHERNET : 0\n");
824     printf("WIFI : 1\n");
825     printf("EDR : 2\n");
826     printf("LE : 3\n");
827     printf("select : ");
828
829     memset(buf, 0, sizeof(char) * MAX_BUF_LEN);
830     gets(buf);
831
832     int number = buf[0] - '0';
833
834     number = (number < 0 || number > 3) ? 1 : number;
835
836     CAResult_t res = CAUnSelectNetwork(1 << number);
837     if (res != CA_STATUS_OK)
838     {
839         printf("unselect network error\n");
840     }
841     else
842     {
843         printf("unselect network success\n");
844     }
845
846     printf("=============================================\n");
847 }
848
849 char get_menu()
850 {
851     char buf[MAX_BUF_LEN];
852
853     printf("\n=============================================\n");
854     printf("\t\tMenu\n");
855     printf("\ts : start server\n");
856     printf("\tc : start client\n");
857     printf("\tf : find resource\n");
858     printf("\tr : send request\n");
859     printf("\tt : send request to all\n");
860     printf("\ta : advertise resource\n");
861     printf("\tb : send notification\n");
862     printf("\tn : select network\n");
863     printf("\tx : unselect network\n");
864     printf("\tg : get network information\n");
865     printf("\th : handle request response\n");
866     printf("\ty : run static client\n");
867     printf("\tz : run static server\n");
868     printf("\tw : send secure request\n");
869     printf("\tq : quit\n");
870     printf("=============================================\n");
871     printf("select : ");
872
873     memset(buf, 0, sizeof(char) * MAX_BUF_LEN);
874
875     gets(buf);
876
877     return buf[0];
878 }
879
880 void handle_request_response()
881 {
882     printf("handle_request_response\n");
883
884     CAResult_t res = CAHandleRequestResponse();
885     if (res != CA_STATUS_OK)
886     {
887         printf("handle request error\n");
888     }
889     else
890     {
891         printf("handle request success\n");
892     }
893 }
894
895 void get_network_info()
896 {
897     int index;
898
899     CALocalConnectivity_t *tempInfo = NULL;
900     uint32_t tempSize = 0;
901
902     if((CAGetNetworkInformation(&tempInfo, &tempSize) != CA_STATUS_OK) ||
903         !tempInfo || !tempSize)
904     {
905         printf("network not connected\n");
906         return;
907     }
908
909     printf("################## Network Information #######################\n");
910     printf("network info total size is %d\n\n", tempSize);
911     for (index = 0; index < tempSize; index++)
912     {
913         printf("Type: %d\n", tempInfo[index].type);
914         printf("Address: %s\n", tempInfo[index].addressInfo.IP.ipAddress);
915         printf("Port: %d\n", tempInfo[index].addressInfo.IP.port);
916         printf("Secured: %d\n\n", tempInfo[index].isSecured);
917
918         if (CA_TRUE == tempInfo[index].isSecured)
919         {
920             gLocalSecurePort = tempInfo[index].addressInfo.IP.port;
921         }
922         else
923         {
924             gLocalUnicastPort = tempInfo[index].addressInfo.IP.port;
925         }
926     }
927
928     free(tempInfo);
929     printf("##############################################################");
930 }
931
932 void request_handler(const CARemoteEndpoint_t *object, const CARequestInfo_t *requestInfo)
933 {
934     if (!object)
935     {
936         printf("Remote endpoint is NULL!");
937         return;
938     }
939
940     if (!requestInfo)
941     {
942         printf("Request info is NULL!");
943         return;
944     }
945
946     printf("##########received request from remote device #############\n");
947     printf("Uri: %s\n", object->resourceUri);
948     printf("Remote Address: %s Port: %d secured:%d\n", object->addressInfo.IP.ipAddress,
949            object->addressInfo.IP.port, object->isSecured);
950
951     printf("Data: %s\n", requestInfo->info.payload);
952
953     if (gLastRequestToken != NULL && requestInfo->info.token != NULL
954         && (strcmp((char *)gLastRequestToken, requestInfo->info.token) == 0))
955     {
956         printf("token is same. received request of it's own. skip.. \n");
957         return;
958     }
959
960     if (requestInfo->info.options)
961     {
962         uint32_t len = requestInfo->info.numOptions;
963         uint32_t i;
964         for (i = 0; i < len; i++)
965         {
966             printf("Option %d\n", i + 1);
967             printf("ID : %d\n", requestInfo->info.options[i].optionID);
968             printf("Data[%d]: %s\n", requestInfo->info.options[i].optionLength,
969                    requestInfo->info.options[i].optionData);
970         }
971     }
972     printf("############################################################\n");
973
974     //Check if this has secure communication information
975     if (requestInfo->info.payload)
976     {
977         int securePort = get_secure_information(requestInfo->info.payload);
978         if (0 < securePort) //Set the remote endpoint secure details and send response
979         {
980             printf("This is secure resource...\n");
981             char *uri = NULL;
982             int length = 0;
983
984             length = 8; //length of "coaps://"
985             length += strlen(object->addressInfo.IP.ipAddress) + 5; // length of "ipaddress:port"
986             length += strlen(object->resourceUri) + 1;
987
988             uri = calloc(1, sizeof(char) * length);
989             if (!uri)
990             {
991                 printf("Failed to create new uri\n");
992                 return;
993             }
994             sprintf(uri, "coaps://%s:%d/%s", object->addressInfo.IP.ipAddress,
995                     securePort, object->resourceUri);
996
997             CARemoteEndpoint_t *endpoint = NULL;
998             if (CA_STATUS_OK != CACreateRemoteEndpoint(uri, object->connectivityType, &endpoint))
999             {
1000                 printf("Failed to create duplicate of remote endpoint!\n");
1001                 return;
1002             }
1003             //endpoint->connectivityType = object->connectivityType;
1004             endpoint->isSecured = CA_TRUE;
1005             object = endpoint;
1006         }
1007     }
1008
1009     printf("send response with URI\n");
1010     send_response(object, (requestInfo != NULL) ? &requestInfo->info : NULL);
1011
1012     gReceived = 1;
1013 }
1014
1015 void response_handler(const CARemoteEndpoint_t *object, const CAResponseInfo_t *responseInfo)
1016 {
1017     printf("##########Received response from remote device #############\n");
1018     printf("Uri: %s\n", object->resourceUri);
1019     printf("Remote Address: %s Port: %d secured:%d\n", object->addressInfo.IP.ipAddress,
1020            object->addressInfo.IP.port, object->isSecured);
1021     printf("response result : %d\n", responseInfo->result);
1022     printf("Data: %s\n", responseInfo->info.payload);
1023
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     gReceived = 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 send_response(CARemoteEndpoint_t *endpoint, CAInfo_t *info)
1051 {
1052     printf("entering send_response\n");
1053
1054     CAInfo_t responseData;
1055     memset(&responseData, 0, sizeof(CAInfo_t));
1056     responseData.type =
1057         (info != NULL) ?
1058         ((info->type == CA_MSG_CONFIRM) ? CA_MSG_ACKNOWLEDGE : CA_MSG_NONCONFIRM) :
1059             CA_MSG_NONCONFIRM;
1060     responseData.messageId = (info != NULL) ? info->messageId : 0;
1061     responseData.token = (info != NULL) ? info->token : "";
1062     responseData.payload = "response payload";
1063
1064     CAResponseInfo_t responseInfo;
1065     memset(&responseInfo, 0, sizeof(CAResponseInfo_t));
1066     responseInfo.result = 203;
1067     responseInfo.info = responseData;
1068
1069     if (CA_TRUE == endpoint->isSecured)
1070         printf("Sending response on secure communication\n");
1071     else
1072         printf("Sending response on non-secure communication\n");
1073
1074     // send request (connectivityType from remoteEndpoint of request Info)
1075     CAResult_t res = CASendResponse(endpoint, &responseInfo);
1076     if (res != CA_STATUS_OK)
1077 {
1078         printf("send response error\n");
1079     }
1080     else
1081     {
1082         printf("send response success\n");
1083     }
1084
1085     printf("=============================================\n");
1086 }
1087
1088 void send_request_tmp(CARemoteEndpoint_t *endpoint, CAToken_t token)
1089 {
1090
1091     printf("\n=============================================\n");
1092
1093     CAInfo_t requestData;
1094     memset(&requestData, 0, sizeof(CAInfo_t));
1095     requestData.token = token;
1096     requestData.payload = "Temp Json Payload";
1097
1098     CARequestInfo_t requestInfo;
1099     memset(&requestInfo, 0, sizeof(CARequestInfo_t));
1100     requestInfo.method = CA_GET;
1101     requestInfo.info = requestData;
1102
1103     // send request
1104     endpoint->connectivityType = CA_WIFI;
1105
1106     CAResult_t res = CASendRequest(endpoint, &requestInfo);
1107     if (res != CA_STATUS_OK)
1108     {
1109         printf("send request error\n");
1110     }
1111     else
1112     {
1113         printf("send request success\n");
1114     }
1115
1116     printf("=============================================\n");
1117
1118 }
1119
1120 int get_secure_information(CAPayload_t payLoad)
1121 {
1122     printf("entering get_secure_information\n");
1123
1124     if (!payLoad)
1125     {
1126         printf("Payload is NULL\n");
1127         return -1;
1128     }
1129
1130     char *subString = NULL;
1131     if (NULL == (subString = strstr(payLoad, "\"sec\":1")))
1132     {
1133         printf("This is not secure resource\n");
1134         return -1;
1135     }
1136
1137     if (NULL == (subString = strstr(payLoad, "\"port\":")))
1138     {
1139         printf("This secure resource does not have port information\n");
1140         return -1;
1141     }
1142
1143     char *startPos = strstr(subString, ":");
1144     if (!startPos)
1145     {
1146         printf("Parsing failed !\n");
1147         return -1;
1148     }
1149
1150     char *endPos = strstr(startPos, "}");
1151     if (!endPos)
1152     {
1153         printf("Parsing failed !\n");
1154         return -1;
1155     }
1156
1157     char portStr[4] = {0};
1158     memcpy(portStr, startPos + 1, (endPos - 1) - startPos);
1159
1160     printf("secured port is: %s\n", portStr);
1161     return atoi(portStr);
1162 }
1163
1164 void get_resource_uri(char *URI, char *resourceURI, int length)
1165 {
1166     char *startPos = URI;
1167     char *temp = NULL;
1168     if (NULL != (temp = strstr(URI, "://")))
1169     {
1170         startPos = strchr(temp + 3, '/');
1171         if (!startPos)
1172         {
1173             printf("Resource URI is missing\n");
1174             return;
1175         }
1176     }
1177
1178     char *endPos = strchr(startPos, '?');
1179     if (!endPos)
1180     {
1181         endPos = URI + strlen(URI);
1182     }
1183     endPos -= 1;
1184
1185     if (endPos - startPos <= length)
1186         memcpy(resourceURI, startPos + 1, endPos - startPos);
1187
1188     printf("URI: %s, ResourceURI:%s\n", URI, resourceURI);
1189 }
1190
1191 CAResult_t get_network_type()
1192 {
1193     char buf[MAX_BUF_LEN];
1194
1195     printf("\n=============================================\n");
1196     printf("\tselect network type\n");
1197     printf("ETHERNET : 0\n");
1198     printf("WIFI : 1\n");
1199     printf("EDR : 2\n");
1200     printf("LE : 3\n");
1201     printf("select : ");
1202
1203     memset(buf, 0, sizeof(char) * MAX_BUF_LEN);
1204     gets(buf);
1205
1206     int number = buf[0] - '0';
1207
1208     number = (number < 0 || number > 3) ? 0 : 1 << number;
1209
1210     if (!(number & 0xf))
1211     {
1212         return CA_NOT_SUPPORTED;
1213     }
1214     if (number & CA_ETHERNET)
1215     {
1216         gSelectedNwType = CA_ETHERNET;
1217         return CA_STATUS_OK;
1218     }
1219     if (number & CA_WIFI)
1220     {
1221         gSelectedNwType = CA_WIFI;
1222         return CA_STATUS_OK;
1223     }
1224     if (number & CA_EDR)
1225     {
1226         gSelectedNwType = CA_EDR;
1227         return CA_STATUS_OK;
1228     }
1229     if (number & CA_LE)
1230     {
1231         gSelectedNwType = CA_LE;
1232         return CA_STATUS_OK;
1233     }
1234
1235     printf("\n=============================================\n");
1236 }