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