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