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