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