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