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