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