Removed Token ASCII-char limit and length limit
[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     uint8_t tokenLength = CA_MAX_TOKEN_LEN;
380
381     CAResult_t res = CAGenerateToken(&token, tokenLength);
382     if ((CA_STATUS_OK != res) || (!token))
383     {
384         printf("token generate error!!");
385         return;
386     }
387
388     printf("Generated token %s\n", token);
389
390     res = CAFindResource(buf, token, tokenLength);
391     if (res != CA_STATUS_OK)
392     {
393         printf("find resource error : %d\n", res);
394     }
395     else
396     {
397         printf("find resource to %s URI\n", buf);
398     }
399
400     // delete token
401     CADestroyToken(token);
402
403     printf("=============================================\n");
404 }
405
406 void FindResource()
407 {
408     char buf[MAX_BUF_LEN] = {0};
409
410     printf("\n=============================================\n");
411     printf("ex) /a/light\n");
412     printf("reference uri : ");
413
414     if(!fgets(buf, MAX_BUF_LEN, stdin))
415     {
416         printf("fgets error\n");
417         return;
418     }
419
420     // create token
421     CAToken_t token = NULL;
422     uint8_t tokenLength = CA_MAX_TOKEN_LEN;
423
424     CAResult_t res = CAGenerateToken(&token, tokenLength);
425     if ((CA_STATUS_OK != res) || (!token))
426     {
427         printf("token generate error!!\n");
428         return;
429     }
430
431     printf("Generated token %s\n", token);
432
433     res = CAFindResource(buf, token, tokenLength);
434     if (res != CA_STATUS_OK)
435     {
436         printf("find resource error : %d\n", res);
437         CADestroyToken(token);
438     }
439     else
440     {
441         printf("find resource to %s URI\n", buf);
442
443         CADestroyToken(g_lastRequestToken);
444
445         g_lastRequestToken = token;
446     }
447
448     printf("=============================================\n");
449 }
450
451 void SendRequest()
452 {
453     char secureRequest[2] = {0};
454     CAResult_t res = CA_STATUS_FAILED;
455     char uri[MAX_BUF_LEN] = {'\0'};
456
457     res = GetNetworkType();
458     if (res != CA_STATUS_OK)
459     {
460         return;
461     }
462
463     printf("Do you want to send secure request ?.... enter (0/1): \n");
464     if(!fgets(secureRequest, 1, stdin))
465     {
466         printf("fgets error\n");
467         return;
468     }
469
470     if ('1' == secureRequest[0])
471     {
472         printf("Enter the URI like below....\n");
473         printf("coaps://10.11.12.13:4545/resource_uri ( for IP secure)\n");
474         printf("uri:  ");
475     }
476     else
477     {
478         printf("Enter the URI like below....\n");
479         printf("coap://10.11.12.13:4545/resource_uri ( for IP )\n");
480         printf("coap://10:11:12:13:45:45/resource_uri ( for BT )\n");
481         printf("uri:  ");
482     }
483
484     if(!fgets(uri, MAX_BUF_LEN, stdin))
485     {
486         printf("fgets error\n");
487         return;
488     }
489
490     // create remote endpoint
491     CARemoteEndpoint_t *endpoint = NULL;
492     if (CA_STATUS_OK != CACreateRemoteEndpoint(uri, g_selectedNwType, &endpoint)
493         || !endpoint)
494     {
495         printf("Failed to create remote endpoint!\n");
496         CADestroyRemoteEndpoint(endpoint);
497         return;
498     }
499
500     char buf[MAX_BUF_LEN]={0};
501
502     printf("\n=============================================\n");
503     printf("0:CON, 1:NON\n");
504     printf("select message type : ");
505
506     if(!fgets(buf, MAX_BUF_LEN, stdin))
507     {
508         printf("fgets error\n");
509         CADestroyRemoteEndpoint(endpoint);
510         return;
511     }
512
513     CAMessageType_t msgType = (buf[0] == '0' || buf[0] == '1') ? buf[0] - '0' : 0;
514
515     // create token
516     CAToken_t token = NULL;
517     uint8_t tokenLength = CA_MAX_TOKEN_LEN;
518
519     res = CAGenerateToken(&token, tokenLength);
520     if ((CA_STATUS_OK != res) || (!token))
521     {
522         printf("token generate error, error code : %d\n", res);
523         return;
524     }
525
526     printf("Generated token %s\n", token);
527
528     // extract relative resourceuri from give uri
529     char resourceURI[15] = {0};
530
531     printf("URI : %s\n", uri);
532     GetResourceUri(uri, resourceURI, 14);
533
534     // create request data
535     CAInfo_t requestData = {CA_MSG_RESET};
536     requestData.token = token;
537     if ('1' == secureRequest[0])
538     {
539         int length = strlen(g_secureInfoData) + strlen(resourceURI) + 1;
540         requestData.payload = (CAPayload_t) malloc(length);
541         if(!requestData.payload)
542         {
543             printf("Memory allocation is failed\n");
544             CADestroyToken(token);
545             CADestroyRemoteEndpoint(endpoint);
546             return;
547         }
548         sprintf(requestData.payload, g_secureInfoData, resourceURI, g_localSecurePort);
549     }
550     else
551     {
552         int length = strlen(g_normalInfoData) + strlen(resourceURI) + 1;
553         requestData.payload = (CAPayload_t) malloc(length);
554         if(!requestData.payload)
555         {
556             printf("Memory allocation is failed\n");
557             CADestroyToken(token);
558             CADestroyRemoteEndpoint(endpoint);
559             return;
560         }
561         sprintf(requestData.payload, g_normalInfoData, resourceURI);
562     }
563     requestData.type = msgType;
564
565     CARequestInfo_t requestInfo = {CA_GET, {CA_MSG_RESET}};
566     requestInfo.method = CA_GET;
567     requestInfo.info = requestData;
568
569     // send request
570     CASendRequest(endpoint, &requestInfo);
571
572     CADestroyToken(token);
573
574     free(requestData.payload);
575
576     // destroy remote endpoint
577     CADestroyRemoteEndpoint(endpoint);
578     printf("=============================================\n");
579 }
580
581 void SendRequestAll()
582 {
583     char buf[MAX_BUF_LEN] = {0};
584
585     CAResult_t res = CA_STATUS_FAILED;
586
587     res = GetNetworkType();
588     if (res != CA_STATUS_OK)
589     {
590         return;
591     }
592
593     printf("\n=============================================\n");
594     printf("10.11.12.13:4545/resource_uri ( for IP )\n");
595     printf("10:11:12:13:45:45/resource_uri ( for BT )\n");
596     printf("uri : ");
597
598     if(!fgets(buf, MAX_BUF_LEN, stdin))
599     {
600         printf("fgets error\n");
601         return;
602     }
603
604     // create remote endpoint
605     CARemoteEndpoint_t *endpoint = NULL;
606     res = CACreateRemoteEndpoint(buf, g_selectedNwType, &endpoint);
607
608     if (res != CA_STATUS_OK)
609     {
610         printf("create remote endpoint error!!\n");
611         CADestroyRemoteEndpoint(endpoint);
612         return;
613     }
614
615     CAGroupEndpoint_t *group = NULL;
616     group = (CAGroupEndpoint_t *)malloc(sizeof(CAGroupEndpoint_t));
617      if (NULL == group)
618     {
619         printf("Memory allocation failed!\n");
620         CADestroyRemoteEndpoint(endpoint);
621         return;
622     }
623     group->connectivityType = endpoint->connectivityType;
624     group->resourceUri = endpoint->resourceUri;
625
626     // create token
627     CAToken_t token = NULL;
628     uint8_t tokenLength = CA_MAX_TOKEN_LEN;
629
630     res = CAGenerateToken(&token, tokenLength);
631     if ((CA_STATUS_OK != res) || (!token))
632     {
633         printf("token generate error!!\n");
634         return;
635     }
636
637     printf("generated token %s\n", token);
638
639     CAInfo_t requestData = {CA_MSG_RESET};
640     requestData.token = token;
641     requestData.tokenLength = tokenLength;
642     requestData.payload = "Temp Json Payload";
643     requestData.type = CA_MSG_NONCONFIRM;
644
645     CARequestInfo_t requestInfo = {CA_GET, {CA_MSG_RESET}};
646     requestInfo.method = CA_GET;
647     requestInfo.info = requestData;
648
649     // send request
650     CASendRequestToAll(group, &requestInfo);
651
652     CADestroyToken(token);
653
654     // destroy remote endpoint
655     CADestroyRemoteEndpoint(endpoint);
656
657     free(group);
658
659     printf("=============================================\n");
660 }
661
662 void AdvertiseResource()
663 {
664     char buf[MAX_BUF_LEN] = {0};
665
666     printf("\n=============================================\n");
667     printf("uri : ");
668
669     if(!fgets(buf, MAX_BUF_LEN, stdin))
670     {
671         printf("fgets error\n");
672         return;
673     }
674
675     int optionNum = 0;
676     char optionData[MAX_OPT_LEN] = {0};
677
678     printf("Option Num : ");
679     scanf("%d", &optionNum);
680     CAHeaderOption_t *headerOpt = NULL;
681     headerOpt = (CAHeaderOption_t *) malloc(sizeof(CAHeaderOption_t) * optionNum);
682     if (NULL == headerOpt)
683     {
684         printf("Memory allocation failed!\n");
685         return;
686     }
687     memset(headerOpt, 0, sizeof(CAHeaderOption_t) * optionNum);
688
689     int i = 0;
690     for (i = 0 ; i < optionNum ; i++)
691     {
692         int optionID = 0;
693         printf("[%d] Option ID : ", i + 1);
694         scanf("%d", &optionID);
695         headerOpt[i].optionID = optionID;
696
697         printf("[%d] Option Data : ", i + 1);
698         scanf("%s", optionData);
699         int len = strlen(optionData);
700         memcpy(headerOpt[i].optionData, optionData, len + 1);
701         printf("[%d] inputed option : ID : %d, data : %s\n", i + 1, optionID, optionData );
702
703         headerOpt[i].optionLength = (uint16_t)len;
704     }
705     printf("\n=============================================\n");
706
707     // create token
708     CAToken_t token = NULL;
709     uint8_t tokenLength = CA_MAX_TOKEN_LEN;
710
711     CAResult_t res = CAGenerateToken(&token, tokenLength);
712     if ((CA_STATUS_OK != res) || (!token))
713     {
714         printf("token generate error!!\n");
715         return;
716     }
717
718     printf("generated token %s\n", token);
719
720     CAAdvertiseResource(buf, token, tokenLength, headerOpt, (uint8_t)optionNum);
721
722     // delete token
723     CADestroyToken(token);
724
725     free(headerOpt);
726 }
727
728 void SendNotification()
729 {
730     char buf[MAX_BUF_LEN] = {0};
731
732     CAResult_t res = CA_STATUS_FAILED;
733
734     res = GetNetworkType();
735     if (res != CA_STATUS_OK)
736     {
737         return;
738     }
739
740     printf("\n=============================================\n");
741     printf("10.11.12.13:4545/resource_uri ( for IP )\n");
742     printf("10:11:12:13:45:45/resource_uri ( for BT )\n");
743     printf("uri : ");
744
745      if(!fgets(buf, MAX_BUF_LEN, stdin))
746     {
747         printf("fgets error\n");
748         return;
749     }
750
751     // create remote endpoint
752     CARemoteEndpoint_t *endpoint = NULL;
753     res = CACreateRemoteEndpoint(buf, g_selectedNwType, &endpoint);
754     if (res != CA_STATUS_OK)
755     {
756         printf("create remote endpoint error!!\n");
757         CADestroyRemoteEndpoint(endpoint);
758         return;
759     }
760
761     CAInfo_t respondData = {CA_MSG_RESET};
762     respondData.tokenLength = CA_MAX_TOKEN_LEN;
763
764     res = CAGenerateToken(&respondData.token, respondData.tokenLength);
765     if ((CA_STATUS_OK != res) || (!respondData.token))
766     {
767         printf("token generate error!!\n");
768         return;
769     }
770
771     respondData.payload = "Temp Notification Data";
772
773     CAResponseInfo_t responseInfo = {0};
774     responseInfo.result = CA_SUCCESS;
775     responseInfo.info = respondData;
776
777     // send request
778     res = CASendNotification(endpoint, &responseInfo);
779     if (res != CA_STATUS_OK)
780     {
781         printf("send notification error, error code: %d\n", res);
782     }
783     else
784     {
785         printf("send notification success\n");
786     }
787
788     // delete token
789     CADestroyToken(respondData.token);
790     // destroy remote endpoint
791     CADestroyRemoteEndpoint(endpoint);
792
793     printf("\n=============================================\n");
794 }
795 void SelectNetwork()
796 {
797     char buf[MAX_BUF_LEN] = {0};
798
799     printf("\n=============================================\n");
800     printf("\tselect network\n");
801     printf("ETHERNET : 0\n");
802     printf("WIFI : 1\n");
803     printf("EDR : 2\n");
804     printf("LE : 3\n");
805     printf("select : ");
806
807     if(!fgets(buf, MAX_BUF_LEN, stdin))
808     {
809         printf("fgets error\n");
810         return;
811     }
812
813     int number = buf[0] - '0';
814
815     number = (number < 0 || number > 3) ? 0 : number;
816
817     CAResult_t res = CASelectNetwork(1 << number);
818     if (res != CA_STATUS_OK)
819     {
820         printf("select network error\n");
821         g_selectedNwType = 1 << number;
822     }
823     else
824     {
825         printf("select network success\n");
826     }
827
828     printf("=============================================\n");
829 }
830
831 void UnselectNetwork()
832 {
833     char buf[MAX_BUF_LEN] = {0};
834
835     printf("\n=============================================\n");
836     printf("\tunselect enabled network\n");
837     printf("ETHERNET : 0\n");
838     printf("WIFI : 1\n");
839     printf("EDR : 2\n");
840     printf("LE : 3\n");
841     printf("select : ");
842
843     if(!fgets(buf, MAX_BUF_LEN, stdin))
844     {
845         printf("fgets error\n");
846         return;
847     }
848
849     int number = buf[0] - '0';
850
851     number = (number < 0 || number > 3) ? 1 : number;
852
853     CAResult_t res = CAUnSelectNetwork(1 << number);
854     if (res != CA_STATUS_OK)
855     {
856         printf("unselect network error\n");
857     }
858     else
859     {
860         printf("unselect network success\n");
861     }
862     printf("=============================================\n");
863 }
864
865 char PrintOptions()
866 {
867     char buf[MAX_BUF_LEN] = {0};
868
869     printf("\n=============================================\n");
870     printf("\t\tMenu\n");
871     printf("\tm : show menu\n");
872     printf("\ts : start server\n");
873     printf("\tc : start client\n");
874     printf("\tf : find resource\n");
875     printf("\tr : send request\n");
876     printf("\tt : send request to all\n");
877     printf("\ta : advertise resource\n");
878     printf("\tb : send notification\n");
879     printf("\tn : select network\n");
880     printf("\tx : unselect network\n");
881     printf("\tg : get network information\n");
882     printf("\th : handle request response\n");
883     printf("\ty : run static client\n");
884     printf("\tz : run static server\n");
885     printf("\tq : quit\n");
886     printf("=============================================\n");
887     printf("select : ");
888
889     if(!fgets(buf, MAX_BUF_LEN, stdin))
890     {
891         printf("fgets error\n");
892         return '\0';
893     }
894
895     return buf[0];
896 }
897
898 void HandleRequestResponse()
899 {
900     printf("handle_request_response\n");
901
902     CAResult_t res = CAHandleRequestResponse();
903     if (res != CA_STATUS_OK)
904     {
905         printf("handle request error\n");
906     }
907     else
908     {
909         printf("handle request success\n");
910     }
911 }
912
913 void GetNetworkInfo()
914 {
915     int index = 0;
916     CALocalConnectivity_t *tempInfo = NULL;
917     uint32_t tempSize = 0;
918
919     CAGetNetworkInformation(&tempInfo, &tempSize);
920     if (tempInfo == NULL || tempSize <= 0)
921     {
922         printf("network not connected\n");
923         return;
924     }
925
926     printf("################## Network Information #######################\n");
927     printf("network info total size is %d\n\n", tempSize);
928
929     for (index = 0; index < tempSize; index++)
930     {
931         printf("Type: %d\n", tempInfo[index].type);
932         printf("Address: %s\n", tempInfo[index].addressInfo.IP.ipAddress);
933         printf("Port: %d\n", tempInfo[index].addressInfo.IP.port);
934         printf("Secured: %d\n\n", tempInfo[index].isSecured);
935
936         if (true == tempInfo[index].isSecured)
937         {
938             g_localSecurePort = tempInfo[index].addressInfo.IP.port;
939         }
940         else
941         {
942             g_localUnicastPort = tempInfo[index].addressInfo.IP.port;
943         }
944     }
945
946     // free
947     free(tempInfo);
948
949     printf("##############################################################");
950 }
951
952 void RequestHandler(const CARemoteEndpoint_t *object, const CARequestInfo_t *requestInfo)
953 {
954     printf("##########received request from remote device #############\n");
955     if (!object)
956     {
957         printf("Remote endpoint is NULL!\n");
958         return;
959     }
960
961     if (!requestInfo)
962     {
963         printf("Request info is NULL!\n");
964         return;
965     }
966
967     printf("Uri: %s\n", object->resourceUri);
968     printf("Remote Address: %s Port: %d secured:%d\n", object->addressInfo.IP.ipAddress,
969            object->addressInfo.IP.port, object->isSecured);
970
971     printf("Data: %s\n", requestInfo->info.payload);
972     printf("Message type: %s\n", g_messageType[requestInfo->info.type]);
973     if (g_lastRequestToken != NULL && requestInfo->info.token != NULL
974         && (strcmp((char *)g_lastRequestToken, requestInfo->info.token) == 0))
975     {
976         printf("token is same. received request of it's own. skip.. \n");
977         return;
978     }
979
980     if (requestInfo->info.options)
981     {
982         uint32_t len = requestInfo->info.numOptions;
983         uint32_t i = 0;
984         for (i = 0; i < len; i++)
985         {
986             printf("Option %d\n", i + 1);
987             printf("ID : %d\n", requestInfo->info.options[i].optionID);
988             printf("Data[%d]: %s\n", requestInfo->info.options[i].optionLength,
989                    requestInfo->info.options[i].optionData);
990         }
991     }
992     printf("############################################################\n");
993
994     //Check if this has secure communication information
995     if (requestInfo->info.payload)
996     {
997         int securePort = GetSecureInformation(requestInfo->info.payload);
998         if (0 < securePort) //Set the remote endpoint secure details and send response
999         {
1000             printf("This is secure resource...\n");
1001             char *uri = NULL;
1002             int length = 0;
1003
1004             length = 8; //length of "coaps://"
1005             length += strlen(object->addressInfo.IP.ipAddress) + 5; // length of "ipaddress:port"
1006             length += strlen(object->resourceUri) + 1;
1007
1008             uri = calloc(1, sizeof(char) * length);
1009             if (!uri)
1010             {
1011                 printf("Failed to create new uri\n");
1012                 return;
1013             }
1014             sprintf(uri, "coaps://%s:%d/%s", object->addressInfo.IP.ipAddress,
1015                     securePort, object->resourceUri);
1016
1017             CARemoteEndpoint_t *endpoint = NULL;
1018             if (CA_STATUS_OK != CACreateRemoteEndpoint(uri, object->connectivityType, &endpoint))
1019             {
1020                 printf("Failed to create duplicate of remote endpoint!\n");
1021                 return;
1022             }
1023             //endpoint->connectivityType = object->connectivityType;
1024             endpoint->isSecured = true;
1025             object = endpoint;
1026
1027             free(uri);
1028         }
1029     }
1030
1031     printf("send response with URI\n");
1032     SendResponse(object, &requestInfo->info);
1033
1034     g_received = 1;
1035 }
1036
1037 void ResponseHandler(const CARemoteEndpoint_t *object, const CAResponseInfo_t *responseInfo)
1038 {
1039     printf("##########Received response from remote device #############\n");
1040     if(!object)
1041     {
1042         printf("response_handler object is null\n");
1043         return;
1044     }
1045
1046      if(!responseInfo)
1047     {
1048         printf("response_handler responseInfo is null\n");
1049         return;
1050     }
1051
1052     printf("Uri: %s\n", object->resourceUri);
1053     printf("Remote Address: %s Port: %d secured:%d\n", object->addressInfo.IP.ipAddress,
1054            object->addressInfo.IP.port, object->isSecured);
1055     printf("response result : %d\n", responseInfo->result);
1056     printf("Data: %s\n", responseInfo->info.payload);
1057     printf("Message type: %s\n", g_messageType[responseInfo->info.type]);
1058     printf("Token: %s\n", responseInfo->info.token);
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         responseData.tokenLength = info->tokenLength;
1107     }
1108     responseData.payload = "response payload";
1109
1110     CAResponseInfo_t responseInfo = {0};
1111     responseInfo.result = 203;
1112     responseInfo.info = responseData;
1113
1114     if (true == endpoint->isSecured)
1115     {
1116         printf("Sending response on secure communication\n");
1117     }
1118     else
1119     {
1120         printf("Sending response on non-secure communication\n");
1121     }
1122
1123     // send request (connectivityType from remoteEndpoint of request Info)
1124     CAResult_t res = CASendResponse(endpoint, &responseInfo);
1125     if (res != CA_STATUS_OK)
1126     {
1127         printf("send response failed\n");
1128     }
1129     else
1130     {
1131         printf("send response success\n");
1132     }
1133
1134     printf("=============================================\n");
1135 }
1136
1137 void SendRequestTemp(CARemoteEndpoint_t *endpoint, CAToken_t token, uint8_t tokenLength)
1138 {
1139     printf("\n=============================================\n");
1140
1141     if(!endpoint)
1142     {
1143         printf("endpoint is null\n");
1144         return;
1145     }
1146
1147     CAInfo_t requestData ={CA_MSG_RESET};
1148     requestData.token = token;
1149     requestData.tokenLength = tokenLength;
1150     requestData.payload = "Temp Json Payload";
1151
1152     CARequestInfo_t requestInfo ={CA_GET, {CA_MSG_RESET}};
1153     memset(&requestInfo, 0, sizeof(CARequestInfo_t));
1154     requestInfo.method = CA_GET;
1155     requestInfo.info = requestData;
1156
1157     // send request
1158     endpoint->connectivityType = CA_WIFI;
1159
1160     CAResult_t res = CASendRequest(endpoint, &requestInfo);
1161     if (res != CA_STATUS_OK)
1162     {
1163         printf("send request failed\n");
1164     }
1165     else
1166     {
1167         printf("send request success\n");
1168     }
1169
1170     printf("=============================================\n");
1171
1172 }
1173
1174 int GetSecureInformation(CAPayload_t payLoad)
1175 {
1176     printf("entering get_secure_information\n");
1177
1178     if (!payLoad)
1179     {
1180         printf("Payload is NULL\n");
1181         return -1;
1182     }
1183
1184     char *subString = NULL;
1185     if (NULL == (subString = strstr(payLoad, "\"sec\":1")))
1186     {
1187         printf("This is not secure resource\n");
1188         return -1;
1189     }
1190
1191     if (NULL == (subString = strstr(payLoad, "\"port\":")))
1192     {
1193         printf("This secure resource does not have port information\n");
1194         return -1;
1195     }
1196
1197     char *startPos = strstr(subString, ":");
1198     if (!startPos)
1199     {
1200         printf("Parsing failed !\n");
1201         return -1;
1202     }
1203
1204     char *endPos = strstr(startPos, "}");
1205     if (!endPos)
1206     {
1207         printf("Parsing failed !\n");
1208         return -1;
1209     }
1210
1211     if(((endPos - 1) - startPos) > 4)
1212     {
1213         printf("port length is not proper.Exceeding length 4\n");
1214         return -1;
1215     }
1216
1217     char portStr[4] = {0};
1218     memcpy(portStr, startPos + 1, (endPos - 1) - startPos);
1219
1220     printf("secured port is: %s\n", portStr);
1221     return atoi(portStr);
1222 }
1223
1224 void GetResourceUri(char *URI, char *resourceURI, int length)
1225 {
1226     char *startPos = URI;
1227     char *temp = NULL;
1228     if (NULL != (temp = strstr(URI, "://")))
1229     {
1230         startPos = strchr(temp + 3, '/');
1231         if (!startPos)
1232         {
1233             printf("Resource URI is missing\n");
1234             return;
1235         }
1236     }
1237
1238     char *endPos = strchr(startPos, '?');
1239     if (!endPos)
1240     {
1241         endPos = URI + strlen(URI);
1242     }
1243     endPos -= 1;
1244
1245     if (endPos - startPos <= length)
1246         memcpy(resourceURI, startPos + 1, endPos - startPos);
1247
1248     printf("URI: %s, ResourceURI:%s\n", URI, resourceURI);
1249 }
1250
1251 CAResult_t GetNetworkType()
1252 {
1253     char buf[MAX_BUF_LEN] = {0};
1254
1255     printf("\n=============================================\n");
1256     printf("\tselect network type\n");
1257     printf("ETHERNET : 0\n");
1258     printf("WIFI : 1\n");
1259     printf("EDR : 2\n");
1260     printf("LE : 3\n");
1261     printf("select : ");
1262
1263     if(!fgets(buf, MAX_BUF_LEN, stdin))
1264     {
1265         printf("fgets error\n");
1266         return CA_STATUS_FAILED;
1267     }
1268
1269     int number = buf[0] - '0';
1270
1271     number = (number < 0 || number > 3) ? 0 : 1 << number;
1272
1273     if (!(number & 0xf))
1274     {
1275         return CA_NOT_SUPPORTED;
1276     }
1277
1278     if (number & CA_ETHERNET)
1279     {
1280         g_selectedNwType = CA_ETHERNET;
1281         return CA_STATUS_OK;
1282     }
1283
1284     if (number & CA_WIFI)
1285     {
1286         g_selectedNwType = CA_WIFI;
1287         return CA_STATUS_OK;
1288     }
1289
1290     if (number & CA_EDR)
1291     {
1292         g_selectedNwType = CA_EDR;
1293         return CA_STATUS_OK;
1294     }
1295
1296     if (number & CA_LE)
1297     {
1298         g_selectedNwType = CA_LE;
1299         return CA_STATUS_OK;
1300     }
1301
1302     printf("\n=============================================\n");
1303
1304     return CA_STATUS_FAILED;
1305 }
1306
1307