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