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