88396eeafaa423bff084b108f06e125bc546f9d4
[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     }
684     else
685     {
686         CADestroyToken(g_last_request_token);
687         g_last_request_token = token;
688     }
689
690     // destroy remote endpoint
691     CADestroyEndpoint(endpoint);
692
693     printf("=============================================\n");
694 }
695
696 void send_notification()
697 {
698     CAResult_t res = get_network_type();
699     if (CA_STATUS_OK != res)
700     {
701         return;
702     }
703
704     printf("\n=============================================\n");
705     printf("Enter the URI like below....\n");
706     printf("coap://10.11.12.13:4545/resource_uri ( for IP )\n");
707     printf("coap://10:11:12:13:45:45/resource_uri ( for BT )\n");
708     printf("uri : ");
709
710     char uri[MAX_BUF_LEN] = { 0 };
711     if (CA_STATUS_OK != get_input_data(uri, MAX_BUF_LEN))
712     {
713         return;
714     }
715
716     printf("\n=============================================\n");
717     printf("\tselect message type\n");
718     printf("CON     : 0\n");
719     printf("NON     : 1\n");
720     printf("ACK     : 2\n");
721     printf("RESET   : 3\n");
722
723     printf("select : ");
724
725     char messageTypeBuf[MAX_BUF_LEN] = { 0 };
726     if (CA_STATUS_OK != get_input_data(messageTypeBuf, MAX_BUF_LEN))
727     {
728         return;
729     }
730
731     int messageType = messageTypeBuf[0] - '0';
732
733     switch(messageType)
734     {
735         case 0:
736                 printf("CONFIRM messagetype is selected\n");
737                 break;
738         case 1:
739                 printf("NONCONFIRM messagetype is selected\n");
740                 break;
741         default:
742                 printf("Invalid Selection\n");
743                 return;
744     }
745
746     CATransportFlags_t flags;
747     addressSet_t address = {};
748     parse_coap_uri(uri, &address, &flags);
749
750     // create remote endpoint
751     CAEndpoint_t *endpoint = NULL;
752     res = CACreateEndpoint(flags, g_selected_nw_type, address.ipAddress, address.port, &endpoint);
753     if (CA_STATUS_OK != res)
754     {
755         printf("Create remote endpoint error, error code: %d\n", res);
756         return;
757     }
758
759     // create token
760     CAToken_t token = NULL;
761     uint8_t tokenLength = CA_MAX_TOKEN_LEN;
762
763     res = CAGenerateToken(&token, tokenLength);
764     if ((CA_STATUS_OK != res) || (!token))
765     {
766         printf("Token generate error!!\n");
767         CADestroyEndpoint(endpoint);
768         return;
769     }
770
771     printf("Generated token %s\n", token);
772
773     CAInfo_t respondData = { 0 };
774     respondData.token = token;
775     respondData.tokenLength = tokenLength;
776     respondData.payload = (CAPayload_t) "TempNotificationData";
777     respondData.payloadSize = strlen((const char *) respondData.payload);
778     respondData.type = messageType;
779     respondData.resourceUri = (CAURI_t)uri;
780
781     CAResponseInfo_t responseInfo = { 0 };
782     responseInfo.result = CA_CONTENT;
783     responseInfo.info = respondData;
784
785     // send notification
786     res = CASendNotification(endpoint, &responseInfo);
787     if (CA_STATUS_OK != res)
788     {
789         printf("Send notification error, error code: %d\n", res);
790     }
791     else
792     {
793         printf("Send notification success\n");
794     }
795
796     // destroy token
797     CADestroyToken(token);
798     // destroy remote endpoint
799     CADestroyEndpoint(endpoint);
800
801     printf("\n=============================================\n");
802 }
803
804 void select_network()
805 {
806     printf("\n=============================================\n");
807     printf("\tselect network\n");
808     printf("IP     : 0\n");
809     printf("GATT   : 1\n");
810     printf("RFCOMM : 2\n");
811     printf("select : ");
812
813     char buf[MAX_BUF_LEN] = { 0 };
814     if (CA_STATUS_OK != get_input_data(buf, MAX_BUF_LEN))
815     {
816         return;
817     }
818
819     int number = buf[0] - '0';
820
821     if (number < 0 || number > 3)
822     {
823         printf("Invalid network type\n");
824         return;
825     }
826
827     CAResult_t res = CASelectNetwork(1 << number);
828     if (CA_STATUS_OK != res)
829     {
830         printf("Select network error\n");
831         g_selected_nw_type = 1 << number;
832     }
833     else
834     {
835         printf("Select network success\n");
836     }
837     printf("=============================================\n");
838 }
839
840 void unselect_network()
841 {
842     printf("\n=============================================\n");
843     printf("\tunselect enabled network\n");
844     printf("IP     : 0\n");
845     printf("GATT   : 1\n");
846     printf("RFCOMM : 2\n");
847     printf("select : ");
848
849     char buf[MAX_BUF_LEN] = { 0 };
850     if (CA_STATUS_OK != get_input_data(buf, MAX_BUF_LEN))
851     {
852         return;
853     }
854
855     int number = buf[0] - '0';
856
857     if (number < 0 || number > 3)
858     {
859         printf("Invalid network type\n");
860         return;
861     }
862
863     CAResult_t res = CAUnSelectNetwork(1 << number);
864     if (CA_STATUS_OK != res)
865     {
866         printf("Unselect network error\n");
867     }
868     else
869     {
870         printf("Unselect network success\n");
871     }
872
873     printf("=============================================\n");
874 }
875
876 char get_menu()
877 {
878     printf("\n=============================================\n");
879     printf("\t\tMenu\n");
880     printf("\ts : start server\n");
881     printf("\tc : start client\n");
882     printf("\tr : send request\n");
883     printf("\tt : send request to all\n");
884     printf("\tb : send notification\n");
885     printf("\tn : select network\n");
886     printf("\tx : unselect network\n");
887     printf("\tg : get network information\n");
888     printf("\th : handle request response\n");
889     printf("\tz : run static server\n");
890     printf("\tw : send secure request\n");
891     printf("\tq : quit\n");
892     printf("=============================================\n");
893     printf("select : ");
894
895     char buf[MAX_BUF_LEN] = { 0 };
896     if (CA_STATUS_OK != get_input_data(buf, MAX_BUF_LEN))
897     {
898         printf("Failed to get input data\n");
899     }
900
901     return buf[0];
902 }
903
904 void handle_request_response()
905 {
906     printf("Handle_request_response\n");
907
908     CAResult_t res = CAHandleRequestResponse();
909     if (CA_STATUS_OK != res)
910     {
911         printf("Handle request error, error code: %d\n", res);
912     }
913     else
914     {
915         printf("Handle request success\n");
916     }
917 }
918
919 void get_network_info()
920 {
921     CAEndpoint_t *tempInfo = NULL;
922     uint32_t tempSize = 0;
923
924     CAResult_t res = CAGetNetworkInformation(&tempInfo, &tempSize);
925     if (CA_STATUS_OK != res || NULL == tempInfo || 0 >= tempSize)
926     {
927         printf("Network not connected\n");
928         free(tempInfo);
929         return;
930     }
931
932     printf("################## Network Information #######################\n");
933     printf("Network info total size is %d\n\n", tempSize);
934
935     int index;
936     for (index = 0; index < tempSize; index++)
937     {
938         printf("Type: %d\n", tempInfo[index].adapter);
939         if (CA_ADAPTER_IP == tempInfo[index].adapter)
940         {
941             printf("Address: %s\n", tempInfo[index].addr);
942             printf("Port: %d\n", tempInfo[index].port);
943         }
944         else
945         {
946             printf("Address: %s\n", tempInfo[index].addr);
947         }
948
949         printf("Secured: %s\n\n", (tempInfo[index].flags & CA_SECURE) ? "true" : "false");
950
951         if (tempInfo[index].flags & CA_SECURE)
952         {
953             g_local_secure_port = tempInfo[index].port;
954             printf("Secured: in global %d\n\n", g_local_secure_port);
955         }
956     }
957
958     free(tempInfo);
959     printf("##############################################################");
960 }
961
962 void request_handler(const CAEndpoint_t *object, const CARequestInfo_t *requestInfo)
963 {
964     if (NULL == object || NULL == requestInfo)
965     {
966         printf("Input parameter is NULL\n");
967         return;
968     }
969
970     if ((NULL != g_last_request_token) && (NULL != requestInfo->info.token)
971         && (strncmp(g_last_request_token, requestInfo->info.token,
972                     requestInfo->info.tokenLength) == 0))
973     {
974         printf("Token is same. received request of it's own. skip.. \n");
975         return;
976     }
977
978     printf("##########received request from remote device #############\n");
979     if (CA_ADAPTER_IP == object->adapter)
980     {
981         printf("Remote Address: %s Port: %d secured:%d\n", object->addr,
982                object->port, object->flags & CA_SECURE);
983     }
984     else
985     {
986         printf("Remote Address: %s \n", object->addr);
987     }
988     printf("Data: %s\n", requestInfo->info.payload);
989     printf("Message type: %s\n", MESSAGE_TYPE[requestInfo->info.type]);
990
991     if (requestInfo->info.options)
992     {
993         uint32_t len = requestInfo->info.numOptions;
994         uint32_t i;
995         for (i = 0; i < len; i++)
996         {
997             printf("Option %d\n", i + 1);
998             printf("ID : %d\n", requestInfo->info.options[i].optionID);
999             printf("Data[%d]: %s\n", requestInfo->info.options[i].optionLength,
1000                    requestInfo->info.options[i].optionData);
1001         }
1002     }
1003     printf("############################################################\n");
1004
1005     //Check if this has secure communication information
1006     if (requestInfo->info.payload &&
1007             (CA_ADAPTER_IP == object->adapter))
1008     {
1009         int securePort = get_secure_information(requestInfo->info.payload);
1010         if (0 < securePort) //Set the remote endpoint secure details and send response
1011         {
1012             printf("This is secure resource...\n");
1013
1014             CAEndpoint_t *endpoint = NULL;
1015             if (CA_STATUS_OK != CACreateEndpoint(0, object->adapter, object->addr,
1016                                                  object->port, &endpoint))
1017             {
1018                 printf("Failed to create duplicate of remote endpoint!\n");
1019                 return;
1020             }
1021             endpoint->flags = CA_SECURE;
1022             object = endpoint;
1023         }
1024     }
1025
1026     printf("Send response with URI\n");
1027     send_response(object, &requestInfo->info);
1028
1029     g_received = 1;
1030 }
1031
1032 void response_handler(const CAEndpoint_t *object, const CAResponseInfo_t *responseInfo)
1033 {
1034     printf("##########Received response from remote device #############\n");
1035     if (CA_ADAPTER_IP == object->adapter)
1036     {
1037         printf("Remote Address: %s Port: %d secured:%d\n", object->addr,
1038                object->port, object->flags & CA_SECURE);
1039     }
1040     else
1041     {
1042         printf("Remote Address: %s \n", object->addr);
1043     }
1044
1045     printf("resource uri : %s\n", responseInfo->info.resourceUri);
1046     printf("response result : %d\n", responseInfo->result);
1047     printf("Data: %s\n", responseInfo->info.payload);
1048     printf("Message type: %s\n", MESSAGE_TYPE[responseInfo->info.type]);
1049     printf("Token: %s\n", responseInfo->info.token);
1050     if (responseInfo->info.options)
1051     {
1052         uint32_t len = responseInfo->info.numOptions;
1053         uint32_t i;
1054         for (i = 0; i < len; i++)
1055         {
1056             printf("Option %d\n", i + 1);
1057             printf("ID : %d\n", responseInfo->info.options[i].optionID);
1058             printf("Data[%d]: %s\n", responseInfo->info.options[i].optionLength,
1059                    responseInfo->info.options[i].optionData);
1060         }
1061     }
1062     printf("############################################################\n");
1063     g_received = 1;
1064
1065     //Check if this has secure communication information
1066     if (responseInfo->info.payload)
1067     {
1068         int securePort = get_secure_information(responseInfo->info.payload);
1069         if (0 < securePort) //Set the remote endpoint secure details and send response
1070         {
1071             printf("This is secure resource...\n");
1072         }
1073     }
1074 }
1075
1076 void error_handler(const CAEndpoint_t *rep, const CAErrorInfo_t* errorInfo)
1077 {
1078     printf("+++++++++++++++++++++++++++++++++++ErrorInfo+++++++++++++++++++++++++++++++++++\n");
1079
1080     if(errorInfo)
1081     {
1082         const CAInfo_t *info = &errorInfo->info;
1083         printf("Error Handler, ErrorInfo :\n");
1084         printf("Error Handler result    : %d\n", errorInfo->result);
1085         printf("Error Handler token     : %s\n", info->token);
1086         printf("Error Handler messageId : %d\n", (uint16_t) info->messageId);
1087         printf("Error Handler type      : %d\n", info->type);
1088         printf("Error Handler resourceUri : %s\n", info->resourceUri);
1089         printf("Error Handler payload   : %s\n", info->payload);
1090
1091         if(CA_ADAPTER_NOT_ENABLED == errorInfo->result)
1092         {
1093             printf("CA_ADAPTER_NOT_ENABLED, enable the adapter\n");
1094         }
1095         else if(CA_SEND_FAILED == errorInfo->result)
1096         {
1097             printf("CA_SEND_FAILED, unable to send the message, check parameters\n");
1098         }
1099         else if(CA_MEMORY_ALLOC_FAILED == errorInfo->result)
1100         {
1101             printf("CA_MEMORY_ALLOC_FAILED, insufficient memory\n");
1102         }
1103         else if(CA_SOCKET_OPERATION_FAILED == errorInfo->result)
1104         {
1105             printf("CA_SOCKET_OPERATION_FAILED, socket operation failed\n");
1106         }
1107         else if(CA_STATUS_FAILED == errorInfo->result)
1108         {
1109             printf("CA_STATUS_FAILED, message could not be delivered, internal error\n");
1110         }
1111     }
1112     printf("++++++++++++++++++++++++++++++++End of ErrorInfo++++++++++++++++++++++++++++++++\n");
1113
1114     return;
1115 }
1116
1117 void send_response(const CAEndpoint_t *endpoint, const CAInfo_t *info)
1118 {
1119     printf("entering send_response\n");
1120
1121     printf("\n=============================================\n");
1122     printf("\tselect message type\n");
1123     printf("CON     : 0\n");
1124     printf("NON     : 1\n");
1125     printf("ACK     : 2\n");
1126     printf("RESET   : 3\n");
1127     printf("select : ");
1128
1129     char buf[MAX_BUF_LEN] = { 0 };
1130     if (CA_STATUS_OK != get_input_data(buf, MAX_BUF_LEN))
1131     {
1132         return;
1133     }
1134
1135     int messageType = buf[0] - '0';
1136     int responseCode = 0 ;
1137     char responseCodeBuf[MAX_BUF_LEN] = { 0 };
1138     if (CA_MSG_RESET != messageType)
1139     {
1140         printf("\n=============================================\n");
1141         printf("\tselect response code\n");
1142         printf("EMPTY                    :   0\n");
1143         printf("CREATED                  : 201\n");
1144         printf("DELETED                  : 202\n");
1145         printf("VALID                    : 203\n");
1146         printf("CHANGED                  : 204\n");
1147         printf("CONTENT                  : 205\n");
1148         printf("BAD_REQ                  : 400\n");
1149         printf("BAD_OPT                  : 402\n");
1150         printf("NOT_FOUND                : 404\n");
1151         printf("INTERNAL_SERVER_ERROR    : 500\n");
1152         printf("RETRANSMIT_TIMEOUT       : 504\n");
1153         printf("select : ");
1154
1155         if (CA_STATUS_OK != get_input_data(responseCodeBuf, MAX_BUF_LEN))
1156         {
1157             return;
1158         }
1159         responseCode = atoi(responseCodeBuf);
1160     }
1161     CAInfo_t responseData = { 0 };
1162     responseData.type = messageType;
1163     responseData.messageId = (info != NULL) ? info->messageId : 0;
1164     responseData.resourceUri = (info != NULL) ? info->resourceUri : 0;
1165
1166     if(CA_MSG_RESET != messageType)
1167     {
1168         responseData.token = (info != NULL) ? info->token : NULL;
1169         responseData.tokenLength = (info != NULL) ? info->tokenLength : 0;
1170
1171         if (endpoint->flags & CA_SECURE)
1172         {
1173             printf("Sending response on secure communication\n");
1174
1175             uint32_t length = sizeof(SECURE_INFO_DATA) + strlen(responseData.resourceUri)
1176                               + sizeof(g_local_secure_port);
1177             responseData.payload = (CAPayload_t) calloc(length,  sizeof(char));
1178             if (NULL == responseData.payload)
1179             {
1180                 printf("Memory allocation fail\n");
1181                 return;
1182             }
1183             snprintf((char *) responseData.payload, length, SECURE_INFO_DATA,
1184                      (const char *) responseData.resourceUri, g_local_secure_port);
1185         }
1186         else
1187         {
1188             printf("Sending response on non-secure communication\n");
1189
1190             bool useBigPayload = select_payload();
1191             if (useBigPayload)
1192             {
1193                 responseData.payload = (CAPayload_t) calloc(BIG_PAYLOAD_SIZE, sizeof(char));
1194                 if (NULL == responseData.payload)
1195                 {
1196                     printf("Memory allocation fail\n");
1197                     return;
1198                 }
1199                 populate_binary_payload(responseData.payload, BIG_PAYLOAD_SIZE);
1200             }
1201             else
1202             {
1203                 size_t length = sizeof(NORMAL_INFO_DATA) + strlen(responseData.resourceUri);
1204                 responseData.payload = (CAPayload_t) calloc(length, sizeof(char));
1205                 if (NULL == responseData.payload)
1206                 {
1207                     printf("Memory allocation fail\n");
1208                     return;
1209                 }
1210                 snprintf((char *) responseData.payload, length, NORMAL_INFO_DATA,
1211                          (const char *) responseData.resourceUri);
1212             }
1213         }
1214     }
1215     responseData.payloadSize = strlen((char *)responseData.payload)+1;
1216     CAResponseInfo_t responseInfo = { 0 };
1217     responseInfo.result = responseCode;
1218     responseInfo.info = responseData;
1219
1220     // send response (transportType from remoteEndpoint of request Info)
1221     CAResult_t res = CASendResponse(endpoint, &responseInfo);
1222     if (CA_STATUS_OK != res)
1223     {
1224         printf("Send response error\n");
1225     }
1226     else
1227     {
1228         printf("Send response success\n");
1229     }
1230
1231     printf("=============================================\n");
1232 }
1233
1234 int get_secure_information(CAPayload_t payLoad)
1235 {
1236     printf("Entering get_secure_information\n");
1237
1238     if (!payLoad)
1239     {
1240         printf("Payload is NULL\n");
1241         return -1;
1242     }
1243
1244     char *subString = NULL;
1245     if (NULL == (subString = strstr((const char *) payLoad, "\"sec\":1")))
1246     {
1247         printf("This is not secure resource\n");
1248         return -1;
1249     }
1250
1251     if (NULL == (subString = strstr((const char *) payLoad, "\"port\":")))
1252     {
1253         printf("This secure resource does not have port information\n");
1254         return -1;
1255     }
1256
1257     char *startPos = strstr(subString, ":");
1258     if (!startPos)
1259     {
1260         printf("Parsing failed !\n");
1261         return -1;
1262     }
1263
1264     char *endPos = strstr(startPos, "}");
1265     if (!endPos)
1266     {
1267         printf("Parsing failed !\n");
1268         return -1;
1269     }
1270
1271     char portStr[6] = {0};
1272     memcpy(portStr, startPos + 1, (endPos - 1) - startPos);
1273
1274     printf("secured port is: %s\n", portStr);
1275     return atoi(portStr);
1276 }
1277
1278 void get_resource_uri(char *URI, char *resourceURI, int length)
1279 {
1280     char *startPos = URI;
1281     char *temp = NULL;
1282     if (NULL != (temp = strstr(URI, "://")))
1283     {
1284         startPos = strchr(temp + 3, '/');
1285         if (!startPos)
1286         {
1287             printf("Resource URI is missing\n");
1288             return;
1289         }
1290     }
1291
1292     char *endPos = strchr(startPos, '?');
1293     if (!endPos)
1294     {
1295         endPos = URI + strlen(URI);
1296     }
1297     endPos -= 1;
1298
1299     if (endPos - startPos <= length)
1300     {
1301         memcpy(resourceURI, startPos + 1, endPos - startPos);
1302     }
1303
1304     printf("URI: %s, ResourceURI:%s\n", URI, resourceURI);
1305 }
1306
1307 CAResult_t get_network_type()
1308 {
1309     printf("\n=============================================\n");
1310     printf("\tselect network type\n");
1311     printf("IP     : 0\n");
1312     printf("GATT   : 1\n");
1313     printf("RFCOMM : 2\n");
1314     printf("select : ");
1315
1316     char buf[MAX_BUF_LEN] = { 0 };
1317     if (CA_STATUS_OK != get_input_data(buf, MAX_BUF_LEN))
1318     {
1319         return CA_NOT_SUPPORTED ;
1320     }
1321
1322     int number = buf[0] - '0';
1323     if (0 > number || 2 < number)
1324     {
1325         printf("\nInvalid Network type");
1326         return CA_NOT_SUPPORTED;
1327     }
1328
1329     g_selected_nw_type = 1 << number;
1330
1331     return CA_STATUS_OK;
1332 }
1333
1334 CAResult_t get_input_data(char *buf, int32_t length)
1335 {
1336     if (!fgets(buf, length, stdin))
1337     {
1338         printf("fgets error\n");
1339         return CA_STATUS_FAILED;
1340     }
1341
1342     char *p = NULL;
1343     if ((p = strchr(buf, '\n')) != NULL)
1344     {
1345         *p = '\0';
1346     }
1347
1348     return CA_STATUS_OK;
1349 }
1350
1351
1352 void parse_coap_uri(const char* uri, addressSet_t* address, CATransportFlags_t *flags)
1353 {
1354     if (NULL == uri)
1355     {
1356         printf("parameter is null\n");
1357         return;
1358     }
1359
1360     // parse uri
1361     // #1. check prefix
1362     uint8_t startIndex = 0;
1363     if (strncmp(COAPS_PREFIX, uri, COAPS_PREFIX_LEN) == 0)
1364     {
1365         printf("uri has '%s' prefix\n", COAPS_PREFIX);
1366         startIndex = COAPS_PREFIX_LEN;
1367         *flags = CA_SECURE;
1368     }
1369     else if (strncmp(COAP_PREFIX, uri, COAP_PREFIX_LEN) == 0)
1370     {
1371         printf("uri has '%s' prefix\n", COAP_PREFIX);
1372         startIndex = COAP_PREFIX_LEN;
1373         *flags = CA_IPV4;
1374     }
1375
1376     // #2. copy uri for parse
1377     int32_t len = strlen(uri) - startIndex;
1378
1379     if (len <= 0)
1380     {
1381         printf("uri length is 0!\n");
1382         return;
1383     }
1384
1385     int res = get_address_set(uri + startIndex, address);
1386     if (res == -1)
1387     {
1388         printf("address parse error\n");
1389         return;
1390     }
1391
1392     return;
1393 }
1394
1395 int get_address_set(const char *uri, addressSet_t* outAddress)
1396 {
1397     if (NULL == uri || NULL == outAddress)
1398     {
1399         printf("parameter is null !\n");
1400         return -1;
1401     }
1402
1403     int32_t len = strlen(uri);
1404     if (len <= 0)
1405     {
1406         printf("uri length is 0!\n");
1407         return -1;
1408     }
1409
1410     int32_t isIp = 0;
1411     int32_t ipLen = 0;
1412     for (int i = 0; i < len; i++)
1413     {
1414         if (uri[i] == '.')
1415         {
1416             isIp = 1;
1417         }
1418
1419         // found port number start index
1420         if (isIp && uri[i] == ':')
1421         {
1422             ipLen = i;
1423             outAddress->port = atoi(uri + ipLen + 1);
1424             break;
1425         }
1426
1427         if (uri[i] == '/')
1428         {
1429             break;
1430         }
1431
1432         outAddress->ipAddress[i] = uri[i];
1433     }
1434
1435     return isIp;
1436 }