56f1ba6eab85b77937939de2e1196d9c8e7072be
[platform/upstream/iotivity.git] / resource / csdk / connectivity / samples / android / casample / sampleService / src / main / jni / ResourceModel.c
1 #include <jni.h>
2 #include <android/log.h>
3 #include <stdio.h>
4 #include <dlfcn.h>
5 #include <stdlib.h>
6 #include <string.h>
7 #include <time.h>
8
9 #include "cainterface.h"
10 #include "cacommon.h"
11 #include "caadapterutils.h"
12 #include "oic_string.h"
13
14 #include "org_iotivity_ca_service_RMInterface.h"
15
16 #define  LOG_TAG   "JNI_INTERFACE_SAMPLE"
17 #define  LOGI(...) __android_log_print(ANDROID_LOG_INFO, LOG_TAG, __VA_ARGS__)
18 #define  LOGE(...) __android_log_print(ANDROID_LOG_ERROR, LOG_TAG, __VA_ARGS__)
19
20 // Iotivity Device Identity.
21 const unsigned char IDENTITY[] = ("1111111111111111");
22
23 // PSK between this device and peer device.
24 const unsigned char RS_CLIENT_PSK[] = ("AAAAAAAAAAAAAAAA");
25
26 #define PORT_LENGTH 5
27 #define SECURE_DEFAULT_PORT 5684
28 #define RESOURCE_URI_LENGTH 14
29 #define OPTION_INFO_LENGTH 1024
30 #define NETWORK_INFO_LENGTH 1024
31 #define BIG_PAYLOAD_LENGTH 1024
32 #define RECEIVED_FILE_NAME_PREFIX_LENGTH 7
33 #define RECEIVED_FILE_NAME_LENGTH 14
34
35 typedef struct
36 {
37     char ipAddress[CA_IPADDR_SIZE];
38     uint16_t port;
39 } addressSet_t;
40
41 static void request_handler(const CAEndpoint_t* object, const CARequestInfo_t* requestInfo);
42 static void response_handler(const CAEndpoint_t* object, const CAResponseInfo_t* responseInfo);
43 static void error_handler(const CAEndpoint_t *object, const CAErrorInfo_t* errorInfo);
44 static void get_resource_uri(const char *URI, char *resourceURI, int32_t length);
45 static uint32_t get_secure_information(CAPayload_t payLoad);
46 static CAResult_t get_network_type(uint32_t selectedNetwork, CATransportFlags_t *flags);
47 static void callback(char *subject, char *receivedData);
48 static CAResult_t get_remote_address(const char *address);
49 static void parsing_coap_uri(const char* uri, addressSet_t* address, CATransportFlags_t *flags);
50 static void delete_global_references(JNIEnv *env, jobject obj);
51 static int get_address_set(const char *pAddress, addressSet_t* outAddress);
52 bool read_file(const char* name, char** bytes, size_t* length);
53 uint32_t gettodaydate();
54 void saveFile(const char *payload, size_t payloadSize);
55
56 uint16_t g_localSecurePort = SECURE_DEFAULT_PORT;
57 CATransportAdapter_t g_selectedNwType = CA_ADAPTER_IP;
58 static CAToken_t g_lastRequestToken = NULL;
59 static uint8_t g_lastRequestTokenLength = 0;
60
61 static const char COAP_PREFIX[] =  "coap://";
62 static const char COAPS_PREFIX[] = "coaps://";
63 static const char COAP_TCP_PREFIX[] =  "coap+tcp://";
64
65 static const uint16_t COAP_PREFIX_LEN = sizeof(COAP_PREFIX) - 1;
66 static const uint16_t COAPS_PREFIX_LEN = sizeof(COAPS_PREFIX) - 1;
67 static const uint16_t COAP_TCP_PREFIX_LEN = sizeof(COAP_TCP_PREFIX) - 1;
68
69 static const char RECEIVED_FILE_PATH[] = "/storage/emulated/0/Download/%d%s.txt";
70
71 static const char SECURE_INFO_DATA[]
72                                    = "{\"oc\":[{\"href\":\"%s\",\"prop\":{\"rt\":[\"core.led\"],"
73                                      "\"if\":[\"oic.if.baseline\"],\"obs\":1,\"sec\":1,\"port\":"
74                                      "%d}}]}";
75 static const char NORMAL_INFO_DATA[]
76                                    = "{\"oc\":[{\"href\":\"%s\",\"prop\":{\"rt\":[\"core.led\"],"
77                                      "\"if\":[\"oic.if.baseline\"],\"obs\":1}}]}";
78
79 static jobject g_responseListenerObject = NULL;
80 static JavaVM *g_jvm;
81
82 static CAEndpoint_t *g_clientEndpoint = NULL;
83 static char *g_resourceUri = NULL;
84 static CAToken_t g_clientToken = NULL;
85 static uint8_t g_clientTokenLength = 0;
86
87 static uint16_t g_clientMsgId = 0;
88 static char *g_remoteAddress = NULL;
89
90 // init
91 JNIEXPORT void JNICALL
92 Java_org_iotivity_ca_service_RMInterface_setNativeResponseListener(JNIEnv *env, jobject obj,
93                                                                    jobject listener)
94 {
95     LOGI("setNativeResponseListener");
96     if (!env || !obj || !listener)
97     {
98         LOGI("Invalid input parameter");
99         return;
100     }
101
102     g_responseListenerObject = (*env)->NewGlobalRef(env, listener);
103 }
104
105 #ifdef __WITH_DTLS__
106 // Internal API. Invoked by OC stack to retrieve credentials from this module
107 int32_t CAGetDtlsPskCredentials( CADtlsPskCredType_t type,
108               const unsigned char *desc, size_t desc_len,
109               unsigned char *result, size_t result_length)
110 {
111     LOGI("CAGetDtlsPskCredentials IN");
112
113     int32_t ret = -1;
114
115     if (NULL == result)
116     {
117         return ret;
118     }
119
120     switch (type)
121     {
122         case CA_DTLS_PSK_HINT:
123         case CA_DTLS_PSK_IDENTITY:
124
125             if (result_length < sizeof(IDENTITY))
126             {
127                 LOGE("ERROR : Wrong value for result for storing IDENTITY");
128                 return ret;
129             }
130
131             memcpy(result, IDENTITY, sizeof(IDENTITY));
132             ret = sizeof(IDENTITY);
133             break;
134
135         case CA_DTLS_PSK_KEY:
136
137             if ((desc_len == sizeof(IDENTITY)) &&
138                 memcmp(desc, IDENTITY, sizeof(IDENTITY)) == 0)
139             {
140                 if (result_length < sizeof(RS_CLIENT_PSK))
141                 {
142                     LOGE("ERROR : Wrong value for result for storing RS_CLIENT_PSK");
143                     return ret;
144                 }
145
146                 memcpy(result, RS_CLIENT_PSK, sizeof(RS_CLIENT_PSK));
147                 ret = sizeof(RS_CLIENT_PSK);
148             }
149             break;
150
151         default:
152
153             LOGE("Wrong value passed for PSK_CRED_TYPE.");
154             ret = -1;
155     }
156
157     LOGI("CAGetDtlsPskCredentials OUT\n");
158     return ret;
159 }
160
161 #endif
162
163 JNIEXPORT jint JNI_OnLoad(JavaVM *jvm, void *reserved)
164 {
165     LOGI("JNI_OnLoad");
166     (void)reserved;
167
168     JNIEnv* env;
169     if (JNI_OK != (*jvm)->GetEnv(jvm, (void**) &env, JNI_VERSION_1_6))
170     {
171         return -1;
172     }
173     g_jvm = jvm; /* cache the JavaVM pointer */
174
175     CANativeJNISetJavaVM(g_jvm);
176
177     return JNI_VERSION_1_6;
178 }
179
180 void JNI_OnUnload(JavaVM *jvm, void *reserved)
181 {
182     LOGI("JNI_OnUnload");
183     (void)reserved;
184
185     JNIEnv* env;
186     if (JNI_OK != (*jvm)->GetEnv(jvm, (void**) &env, JNI_VERSION_1_6))
187     {
188         return;
189     }
190     g_jvm = 0;
191     return;
192 }
193
194 JNIEXPORT void JNICALL
195 Java_org_iotivity_ca_service_RMInterface_RMInitialize(JNIEnv *env, jobject obj, jobject context,
196                                                       jobject activity)
197 {
198     LOGI("RMInitialize");
199     if (!env || !obj || !context || !activity)
200     {
201         LOGI("Invalid input parameter");
202         return;
203     }
204
205     //Currently set context for Android Platform
206     CANativeJNISetContext(env, context);
207     CANativeSetActivity(env, activity);
208
209     CAResult_t res = CAInitialize();
210
211     if (CA_STATUS_OK != res)
212     {
213         LOGE("Could not Initialize");
214     }
215
216 #ifdef __WITH_DTLS__
217     res = CARegisterDTLSCredentialsHandler(CAGetDtlsPskCredentials);
218     if(CA_STATUS_OK != res)
219     {
220         LOGE("Set credential handler fail");
221         return;
222     }
223 #endif
224 }
225
226 JNIEXPORT void JNICALL
227 Java_org_iotivity_ca_service_RMInterface_RMTerminate(JNIEnv *env, jobject obj)
228 {
229     LOGI("RMTerminate");
230     if (!env || !obj)
231     {
232         LOGI("Invalid input parameter");
233         return;
234     }
235
236     CADestroyToken(g_lastRequestToken);
237     CATerminate();
238     delete_global_references(env, obj);
239 }
240
241 JNIEXPORT void JNICALL
242 Java_org_iotivity_ca_service_RMInterface_RMStartListeningServer(JNIEnv *env, jobject obj)
243 {
244     LOGI("RMStartListeningServer");
245     if (!env || !obj)
246     {
247         LOGI("Invalid input parameter");
248         return;
249     }
250
251     if (CA_STATUS_OK != CAStartListeningServer())
252     {
253         LOGE("Could not start Listening server");
254     }
255 }
256
257 JNIEXPORT void JNICALL
258 Java_org_iotivity_ca_service_RMInterface_RMStartDiscoveryServer(JNIEnv *env, jobject obj)
259 {
260     LOGI("RMStartDiscoveryServer");
261     if (!env || !obj)
262     {
263         LOGI("Invalid input parameter");
264         return;
265     }
266
267     if (CA_STATUS_OK != CAStartDiscoveryServer())
268     {
269         LOGE("Could not start discovery server");
270     }
271 }
272
273 JNIEXPORT void JNICALL
274 Java_org_iotivity_ca_service_RMInterface_RMRegisterHandler(JNIEnv *env, jobject obj)
275 {
276     LOGI("RMRegisterHandler");
277     if(!env || !obj)
278     {
279         LOGI("Invalid input parameter");
280         return;
281     }
282
283     CARegisterHandler(request_handler, response_handler, error_handler);
284 }
285
286 JNIEXPORT void JNICALL
287 Java_org_iotivity_ca_service_RMInterface_RMSendRequest(JNIEnv *env, jobject obj, jstring uri,
288                                                        jstring payload, jint selectedNetwork,
289                                                        jint isSecured, jint msgType,
290                                                        jboolean isBigData)
291 {
292     LOGI("selectedNetwork - %d", selectedNetwork);
293     if (!env || !obj)
294     {
295         LOGI("Invalid input parameter");
296         return;
297     }
298
299     if (!uri)
300     {
301         LOGE("Invalid input parameter : uri");
302         return;
303     }
304
305     CATransportFlags_t flags = CA_DEFAULT_FLAGS;
306     CAResult_t res = get_network_type(selectedNetwork, &flags);
307     if (CA_STATUS_OK != res)
308     {
309         return;
310     }
311
312     const char* strUri = (*env)->GetStringUTFChars(env, uri, NULL);
313     LOGI("RMSendRequest - %s", strUri);
314
315     addressSet_t address = {{0}, 0};
316     parsing_coap_uri(strUri, &address, &flags);
317
318     //create remote endpoint
319     CAEndpoint_t* endpoint = NULL;
320     res = CACreateEndpoint(flags, g_selectedNwType, (const char*)(address.ipAddress),
321                            address.port, &endpoint);
322     if (CA_STATUS_OK != res)
323     {
324         LOGE("Could not create remote end point");
325         (*env)->ReleaseStringUTFChars(env, uri, strUri);
326         return;
327     }
328
329     CAMessageType_t messageType = msgType;
330
331     // create token
332     CAToken_t token = NULL;
333     uint8_t tokenLength = CA_MAX_TOKEN_LEN;
334
335     res = CAGenerateToken(&token, tokenLength);
336     if ((CA_STATUS_OK != res) || (!token))
337     {
338         LOGE("token generate error!!");
339         // destroy remote endpoint
340         CADestroyEndpoint(endpoint);
341         (*env)->ReleaseStringUTFChars(env, uri, strUri);
342         return;
343     }
344
345     char resourceURI[RESOURCE_URI_LENGTH + 1] = { 0 };
346
347     get_resource_uri((const CAURI_t) strUri, resourceURI, RESOURCE_URI_LENGTH);
348     (*env)->ReleaseStringUTFChars(env, uri, strUri);
349
350     CAInfo_t requestData = { 0 };
351     requestData.token = token;
352     requestData.tokenLength = tokenLength;
353
354     size_t payloadLength = 0;
355     if (isBigData)
356     {
357         const char* path = NULL;
358         if (payload)
359         {
360             path = (*env)->GetStringUTFChars(env, payload, NULL);
361             if(path)
362             {
363                 char* bigData = NULL;
364                 bool result = read_file(path, &bigData, &payloadLength);
365                 if (!result)
366                 {
367                     LOGE("read has failed");
368                     (*env)->ReleaseStringUTFChars(env, payload, path);
369                     CADestroyToken(token);
370                     CADestroyEndpoint(endpoint);
371                     return;
372                 }
373                 (*env)->ReleaseStringUTFChars(env, payload, path);
374
375                 requestData.payload = (CAPayload_t) malloc(payloadLength);
376                 if (NULL == requestData.payload)
377                 {
378                     LOGE("Memory allocation failed!");
379                     // destroy token
380                     CADestroyToken(token);
381                     // destroy remote endpoint
382                     CADestroyEndpoint(endpoint);
383                     return;
384                 }
385                 memcpy(requestData.payload, bigData, payloadLength);
386                 requestData.payloadSize = payloadLength;
387             }
388         }
389     }
390     else
391     {
392         if (isSecured)
393         {
394             payloadLength = sizeof(SECURE_INFO_DATA) + strlen(resourceURI);
395             requestData.payload = (CAPayload_t) malloc(payloadLength);
396             if (NULL == requestData.payload)
397             {
398                 LOGE("Memory allocation failed!");
399                 // destroy token
400                 CADestroyToken(token);
401                 // destroy remote endpoint
402                 CADestroyEndpoint(endpoint);
403                 return;
404             }
405             snprintf((char *) requestData.payload, payloadLength, SECURE_INFO_DATA,
406                      resourceURI, g_localSecurePort);
407             requestData.payloadSize = payloadLength;
408         }
409         else
410         {
411             payloadLength = sizeof(NORMAL_INFO_DATA) + strlen(resourceURI);
412             requestData.payload = (CAPayload_t) malloc(payloadLength);
413             if (NULL == requestData.payload)
414             {
415                 LOGE("Memory allocation failed!");
416                 // destroy token
417                 CADestroyToken(token);
418                 // destroy remote endpoint
419                 CADestroyEndpoint(endpoint);
420                 return;
421             }
422             snprintf((char *) requestData.payload, payloadLength, NORMAL_INFO_DATA, resourceURI);
423             requestData.payloadSize = payloadLength;
424         }
425     }
426
427     requestData.type = messageType;
428     requestData.resourceUri = (CAURI_t) malloc(sizeof(resourceURI));
429     if (NULL == requestData.resourceUri)
430     {
431         LOGE("Memory allocation failed!");
432         // destroy token
433         CADestroyToken(token);
434         // destroy remote endpoint
435         CADestroyEndpoint(endpoint);
436         free(requestData.payload);
437         return;
438     }
439     memcpy(requestData.resourceUri, resourceURI, sizeof(resourceURI));
440
441     CARequestInfo_t requestInfo = { 0 };
442     requestInfo.method = CA_GET;
443     requestInfo.isMulticast = false;
444     requestInfo.info = requestData;
445
446     // send request
447     if (CA_STATUS_OK != CASendRequest(endpoint, &requestInfo))
448     {
449         LOGE("Could not send request");
450     }
451
452     // destroy token
453     CADestroyToken(token);
454
455     // destroy remote endpoint
456     CADestroyEndpoint(endpoint);
457
458     free(requestData.payload);
459     free(requestData.resourceUri);
460     LOGI("send request success");
461 }
462
463 JNIEXPORT void JNICALL
464 Java_org_iotivity_ca_service_RMInterface_RMSendReqestToAll(JNIEnv *env, jobject obj, jstring uri,
465                                                            jint selectedNetwork)
466 {
467     LOGI("selectedNetwork - %d", selectedNetwork);
468     if (!env || !obj)
469     {
470         LOGI("Invalid input parameter");
471         return;
472     }
473
474     CATransportFlags_t flags = CA_DEFAULT_FLAGS;
475     CAResult_t res = get_network_type(selectedNetwork, &flags);
476     if (CA_STATUS_OK != res)
477     {
478         LOGE("Not supported network type");
479         return;
480     }
481
482     // create remote endpoint
483     CAEndpoint_t *endpoint = NULL;
484     res = CACreateEndpoint(flags, g_selectedNwType, NULL, 0, &endpoint);
485
486     if (CA_STATUS_OK != res)
487     {
488         LOGE("create remote endpoint error, error code: %d", res);
489         return;
490     }
491
492     // create token
493     CAToken_t token = NULL;
494     uint8_t tokenLength = CA_MAX_TOKEN_LEN;
495
496     res = CAGenerateToken(&token, tokenLength);
497     if ((CA_STATUS_OK != res) || (!token))
498     {
499         LOGE("token generate error!!");
500         // destroy remote endpoint
501         CADestroyEndpoint(endpoint);
502         return;
503     }
504
505     LOGI("generated token %s", token);
506
507     CAInfo_t requestData = { 0 };
508     requestData.token = token;
509     requestData.tokenLength = tokenLength;
510     requestData.payload = (CAPayload_t) "TempJsonPayload";
511     requestData.payloadSize = strlen((const char *) requestData.payload);
512     requestData.type = CA_MSG_NONCONFIRM;
513
514     const char* strUri = (*env)->GetStringUTFChars(env, uri, NULL);
515     LOGI("resourceUri - %s", strUri);
516     requestData.resourceUri = (CAURI_t)strUri;
517
518     uint8_t optionNum = 2;
519     CAHeaderOption_t *headerOpt = (CAHeaderOption_t*) calloc(1,
520                                                              sizeof(CAHeaderOption_t) * optionNum);
521     if (NULL == headerOpt)
522     {
523         LOGE("Memory allocation failed");
524         // destroy remote endpoint
525         CADestroyEndpoint(endpoint);
526         return;
527     }
528
529     char* FirstOptionData = "Hello";
530     headerOpt[0].optionID = 3000;
531     memcpy(headerOpt[0].optionData, FirstOptionData, strlen(FirstOptionData));
532     headerOpt[0].optionLength = (uint16_t) strlen(FirstOptionData);
533
534     char* SecondOptionData2 = "World";
535     headerOpt[1].optionID = 3001;
536     memcpy(headerOpt[1].optionData, SecondOptionData2, strlen(SecondOptionData2));
537     headerOpt[1].optionLength = (uint16_t) strlen(SecondOptionData2);
538
539     requestData.numOptions = optionNum;
540     requestData.options = headerOpt;
541
542     CARequestInfo_t requestInfo = { 0 };
543     requestInfo.method = CA_GET;
544     requestInfo.isMulticast = true;
545     requestInfo.info = requestData;
546
547     // send request to all
548     res = CASendRequest(endpoint, &requestInfo);
549     if (CA_STATUS_OK != res)
550     {
551         LOGE("Could not send request to all");
552         //destroy token
553         CADestroyToken(token);
554     }
555     else
556     {
557         CADestroyToken(g_lastRequestToken);
558         g_lastRequestToken = token;
559         g_lastRequestTokenLength = tokenLength;
560     }
561
562     //ReleaseStringUTFChars for strUri
563     (*env)->ReleaseStringUTFChars(env, uri, strUri);
564
565     free(headerOpt);
566
567     // destroy remote endpoint
568     CADestroyEndpoint(endpoint);
569 }
570
571 JNIEXPORT void JNICALL
572 Java_org_iotivity_ca_service_RMInterface_RMSendResponse(JNIEnv *env, jobject obj,
573                                                         jint selectedNetwork,
574                                                         jint isSecured, jint msgType,
575                                                         jint responseValue)
576 {
577     LOGI("RMSendResponse");
578     if (!env || !obj)
579     {
580         LOGI("Invalid input parameter");
581         return;
582     }
583
584     LOGI("selectedNetwork - %d", selectedNetwork);
585
586     CATransportFlags_t flags = CA_DEFAULT_FLAGS;
587     CAResult_t res = get_network_type(selectedNetwork, &flags);
588     if (CA_STATUS_OK != res)
589     {
590         LOGE("Not supported network type");
591         return;
592     }
593
594     if (NULL == g_clientEndpoint)
595     {
596         LOGE("No Request received");
597         return;
598     }
599
600     CAMessageType_t messageType = msgType;
601
602     CAInfo_t responseData = { 0 };
603     responseData.type = messageType;
604     responseData.messageId = g_clientMsgId;
605     responseData.resourceUri = (CAURI_t)g_resourceUri;
606
607     CAResponseInfo_t responseInfo = { 0 };
608
609     if (CA_MSG_RESET == msgType ||
610         (CA_MSG_ACKNOWLEDGE == msgType && CA_EMPTY == responseValue))
611     {
612         printf("RESET or ACK/EMPTY. there will be not payload/option\n");
613         responseInfo.result = CA_EMPTY;
614     }
615     else
616     {
617         responseData.token = g_clientToken;
618         responseData.tokenLength = g_clientTokenLength;
619         responseInfo.result = responseValue;
620
621         if (1 == isSecured)
622         {
623             uint32_t length = strlen(SECURE_INFO_DATA) + strlen(g_resourceUri) + 1;
624             responseData.payload = (CAPayload_t) malloc(length);
625             snprintf((char *) responseData.payload, length, SECURE_INFO_DATA,
626                      g_resourceUri, g_localSecurePort);
627             responseData.payloadSize = length;
628         }
629         else
630         {
631             uint32_t length = strlen(NORMAL_INFO_DATA) + strlen(g_resourceUri) + 1;
632             responseData.payload = (CAPayload_t) malloc(length);
633             snprintf((char *) responseData.payload, length, NORMAL_INFO_DATA, g_resourceUri);
634             responseData.payloadSize = length;
635         }
636     }
637
638     responseInfo.info = responseData;
639
640     // send response
641     res = CASendResponse(g_clientEndpoint, &responseInfo);
642     if (CA_STATUS_OK != res)
643     {
644         LOGE("Could not send response");
645     }
646
647     // destroy token
648     CADestroyToken(g_clientToken);
649     g_clientToken = NULL;
650     g_clientTokenLength = 0;
651
652     // destroy remote endpoint
653     CADestroyEndpoint(g_clientEndpoint);
654     g_clientEndpoint = NULL;
655     free(responseData.payload);
656 }
657
658 JNIEXPORT void JNICALL
659 Java_org_iotivity_ca_service_RMInterface_RMSendNotification(JNIEnv *env, jobject obj, jstring uri,
660                                                             jstring payload, jint selectedNetwork,
661                                                             jint isSecured, jint msgType)
662 {
663     LOGI("selectedNetwork - %d", selectedNetwork);
664     if (!env || !obj)
665     {
666         LOGI("Invalid input parameter");
667         return;
668     }
669
670     if (!payload)
671     {
672         LOGE("payload is NULL");
673     }
674
675     if (!uri)
676     {
677         LOGE("Invalid input parameter : uri");
678         return;
679     }
680
681     CATransportFlags_t flags = CA_DEFAULT_FLAGS;
682     CAResult_t res = get_network_type(selectedNetwork, &flags);
683     if (CA_STATUS_OK != res)
684     {
685         LOGE("Not supported network type");
686         return;
687     }
688
689     const char* strUri = (*env)->GetStringUTFChars(env, uri, NULL);
690     LOGI("RMSendNotification - %s", strUri);
691
692     addressSet_t address = {{0}, 0};
693     parsing_coap_uri(strUri, &address, &flags);
694
695     //create remote endpoint
696     CAEndpoint_t* endpoint = NULL;
697     if (CA_STATUS_OK != CACreateEndpoint(flags, g_selectedNwType,
698                                          (const char*)address.ipAddress,
699                                          address.port, &endpoint))
700     {
701         //ReleaseStringUTFChars for strUri
702         (*env)->ReleaseStringUTFChars(env, uri, strUri);
703         LOGE("Could not create remote end point");
704         return;
705     }
706
707     char resourceURI[RESOURCE_URI_LENGTH + 1] = { 0 };
708     get_resource_uri(strUri, resourceURI, RESOURCE_URI_LENGTH);
709
710     //ReleaseStringUTFChars for strUri
711     (*env)->ReleaseStringUTFChars(env, uri, strUri);
712
713     CAMessageType_t messageType = msgType;
714
715     // create token
716     CAToken_t token = NULL;
717     uint8_t tokenLength = CA_MAX_TOKEN_LEN;
718
719     res = CAGenerateToken(&token, tokenLength);
720     if ((CA_STATUS_OK != res) || (!token))
721     {
722         LOGE("token generate error!");
723         CADestroyEndpoint(endpoint);
724         return;
725     }
726
727     CAInfo_t requestData = { 0 };
728     requestData.token = token;
729     requestData.tokenLength = tokenLength;
730     requestData.resourceUri = (CAURI_t) malloc(sizeof(resourceURI));
731     if (NULL == requestData.resourceUri)
732     {
733         LOGE("Memory allocation failed!");
734         // destroy token
735         CADestroyToken(token);
736         // destroy remote endpoint
737         CADestroyEndpoint(endpoint);
738         return;
739     }
740     memcpy(requestData.resourceUri, resourceURI, sizeof(resourceURI));
741
742     if (1 == isSecured)
743     {
744         uint32_t length = sizeof(SECURE_INFO_DATA) + strlen(resourceURI);
745         requestData.payload = (CAPayload_t) malloc(length);
746         if (NULL == requestData.payload)
747         {
748             LOGE("Memory allocation failed!");
749             // destroy token
750             CADestroyToken(token);
751             // destroy remote endpoint
752             CADestroyEndpoint(endpoint);
753
754             free(requestData.resourceUri);
755             return;
756         }
757         snprintf((char *) requestData.payload, length, SECURE_INFO_DATA,
758                  resourceURI, g_localSecurePort);
759         requestData.payloadSize = length;
760     }
761     else
762     {
763         uint32_t length = sizeof(NORMAL_INFO_DATA) + strlen(resourceURI);
764         requestData.payload = (CAPayload_t) malloc(length);
765         if (NULL == requestData.payload)
766         {
767             LOGE("Memory allocation failed!");
768             // destroy token
769             CADestroyToken(token);
770             // destroy remote endpoint
771             CADestroyEndpoint(endpoint);
772
773             free(requestData.resourceUri);
774             return;
775         }
776         snprintf((char *) requestData.payload, length, NORMAL_INFO_DATA, resourceURI);
777         requestData.payloadSize = length;
778     }
779
780     requestData.type = messageType;
781
782     CARequestInfo_t requestInfo = { 0 };
783     requestInfo.method = CA_GET;
784     requestInfo.info = requestData;
785
786     // send notification
787     if (CA_STATUS_OK != CASendRequest(endpoint, &requestInfo))
788     {
789         LOGE("Could not send notification");
790     }
791
792     LOGI("Send Notification");
793
794     // destroy token
795     CADestroyToken(token);
796
797     // destroy remote endpoint
798     CADestroyEndpoint(endpoint);
799
800     free(requestData.payload);
801     free(requestData.resourceUri);
802 }
803
804 JNIEXPORT void JNICALL
805 Java_org_iotivity_ca_service_RMInterface_RMSelectNetwork(JNIEnv *env, jobject obj,
806                                                          jint networkType)
807 {
808     LOGI("RMSelectNetwork Type : %d", networkType);
809     if (!env || !obj)
810     {
811         LOGI("Invalid input parameter");
812         return;
813     }
814
815     if (CA_STATUS_OK != CASelectNetwork(networkType))
816     {
817         LOGE("Could not select network");
818     }
819 }
820
821 JNIEXPORT void JNICALL
822 Java_org_iotivity_ca_service_RMInterface_RMUnSelectNetwork(JNIEnv *env, jobject obj,
823                                                            jint networkType)
824 {
825     LOGI("RMUnSelectNetwork Type : %d", networkType);
826     if (!env || !obj)
827     {
828         LOGI("Invalid input parameter");
829         return;
830     }
831
832     if (CA_STATUS_OK != CAUnSelectNetwork(networkType))
833     {
834         LOGE("Could not unselect network");
835     }
836 }
837
838 JNIEXPORT void JNICALL
839 Java_org_iotivity_ca_service_RMInterface_RMGetNetworkInfomation(JNIEnv *env, jobject obj)
840 {
841     LOGI("RMGetNetworkInfomation");
842     if (!env || !obj)
843     {
844         LOGI("Invalid input parameter");
845         return;
846     }
847
848     CAEndpoint_t *tempInfo = NULL;
849     uint32_t tempSize = 0;
850
851     CAResult_t res = CAGetNetworkInformation(&tempInfo, &tempSize);
852     if (CA_STATUS_OK != res)
853     {
854         LOGE("Could not start get network information");
855         free(tempInfo);
856         return;
857     }
858
859     LOGI("################## Network Information #######################");
860     callback("######## Network Information", "#######");
861     LOGI("Network info total size is %d", tempSize);
862
863     uint32_t index;
864     for (index = 0; index < tempSize; index++)
865     {
866         res = get_remote_address(tempInfo[index].addr);
867         if (CA_STATUS_OK != res)
868         {
869             free(tempInfo);
870             return;
871         }
872         if (NULL != g_responseListenerObject)
873         {
874             char networkInfo[NETWORK_INFO_LENGTH];
875             LOGI("Type: %d", tempInfo[index].adapter);
876             snprintf(networkInfo, NETWORK_INFO_LENGTH, "%d",tempInfo[index].adapter);
877             callback("Type :", networkInfo);
878             if (CA_ADAPTER_IP == tempInfo[index].adapter)
879             {
880                 LOGI("Port: %d", tempInfo[index].port);
881                 snprintf(networkInfo, NETWORK_INFO_LENGTH, "%d",tempInfo[index].port);
882                 callback("Port: ", networkInfo);
883             }
884             LOGI("Secured: %d", (tempInfo[index].flags & CA_SECURE));
885             LOGI("Address: %s", g_remoteAddress);
886             callback("Address: ", g_remoteAddress);
887             free(g_remoteAddress);
888         }
889         if (tempInfo[index].flags & CA_SECURE)
890         {
891             g_localSecurePort = tempInfo[index].port;
892         }
893     }
894
895     // free
896     free(tempInfo);
897
898     LOGI("##############################################################");
899 }
900
901 JNIEXPORT void JNICALL
902 Java_org_iotivity_ca_service_RMInterface_RMHandleRequestResponse(JNIEnv *env, jobject obj)
903 {
904     LOGI("RMHandleRequestResponse");
905     if(!env || !obj)
906     {
907         LOGI("Invalid input parameter");
908         return;
909     }
910
911     if (CA_STATUS_OK != CAHandleRequestResponse())
912     {
913         LOGE("Could not handle request and response");
914     }
915 }
916
917 void request_handler(const CAEndpoint_t* object, const CARequestInfo_t* requestInfo)
918 {
919
920     if (!object)
921     {
922         LOGE("Remote endpoint is NULL!");
923         return;
924     }
925
926     if (!requestInfo)
927     {
928         LOGE("Request info is NULL!");
929         return;
930     }
931
932     if ((NULL != g_lastRequestToken) && (NULL != requestInfo->info.token) &&
933             (strncmp(g_lastRequestToken, requestInfo->info.token,
934                      requestInfo->info.tokenLength) == 0))
935     {
936         LOGI("token is same. received request of it's own. skip.. ");
937         return;
938     }
939
940     CAResult_t res = get_remote_address(object->addr);
941     if (CA_STATUS_OK != res)
942     {
943         return;
944     }
945
946     LOGI("##########received request from remote device #############");
947     LOGI("Remote Address: %s", g_remoteAddress);
948     LOGI("Remote Port: %d", object->port);
949     LOGI("Uri: %s", requestInfo->info.resourceUri);
950     LOGI("Data: %s", requestInfo->info.payload);
951     LOGI("Token: %s", requestInfo->info.token);
952     LOGI("Code: %d", requestInfo->method);
953     LOGI("MessageType: %d", requestInfo->info.type);
954
955     if (NULL != g_responseListenerObject)
956     {
957         char *cloneUri = NULL;
958         uint32_t len = 0;
959
960         if (NULL != requestInfo->info.resourceUri)
961         {
962             len = strlen(requestInfo->info.resourceUri);
963             cloneUri = (char *)malloc(sizeof(char) * (len + 1));
964
965             if (NULL == cloneUri)
966             {
967                 LOGE("cloneUri Out of memory");
968                 free(g_remoteAddress);
969                 return;
970             }
971
972             memcpy(cloneUri, requestInfo->info.resourceUri, len + 1);
973             callback("Uri: ", cloneUri);
974         }
975
976         len = strlen(g_remoteAddress);
977         char *cloneRemoteAddress = (char *) malloc(sizeof(char) * (len + 1));
978
979         if (NULL == cloneRemoteAddress)
980         {
981             LOGE("cloneRemoteAddress Out of memory");
982             free(g_remoteAddress);
983             free(cloneUri);
984             return;
985         }
986
987         memcpy(cloneRemoteAddress, g_remoteAddress, len + 1);
988
989         callback("Remote Address: ", cloneRemoteAddress);
990         free(cloneRemoteAddress);
991         free(g_remoteAddress);
992
993         char portInfo[PORT_LENGTH] = { 0, };
994         snprintf(portInfo, PORT_LENGTH, "%d", object->port);
995         callback("Remote Port: ", portInfo);
996
997         //clone g_clientEndpoint
998         g_clientEndpoint = (CAEndpoint_t *) malloc(sizeof(CAEndpoint_t));
999         if (NULL == g_clientEndpoint)
1000         {
1001             LOGE("g_clientEndpoint Out of memory");
1002             free(cloneUri);
1003             return;
1004         }
1005         memcpy(g_clientEndpoint, object, sizeof(CAEndpoint_t));
1006
1007         if (NULL != cloneUri)
1008         {
1009             len = strlen(cloneUri);
1010             g_resourceUri = (char *) malloc(sizeof(char) * (len + 1));
1011             if (NULL == g_resourceUri)
1012             {
1013                 LOGE("g_clientEndpoint->resourceUri Out of memory");
1014                 free(g_clientEndpoint);
1015                 free(cloneUri);
1016                 return;
1017             }
1018             memcpy(g_resourceUri, cloneUri, len + 1);
1019             free(cloneUri);
1020         }
1021         //clone g_clientToken
1022         len = requestInfo->info.tokenLength;
1023
1024         g_clientToken = (char *) malloc(sizeof(char) * len);
1025         if (NULL == g_clientToken)
1026         {
1027             LOGE("g_clientToken Out of memory");
1028             free(g_clientEndpoint);
1029             return;
1030         }
1031
1032         if (NULL != requestInfo->info.token)
1033         {
1034             memcpy(g_clientToken, requestInfo->info.token, len);
1035             g_clientTokenLength = len;
1036
1037         }
1038
1039         //clone g_clientMsgId
1040         g_clientMsgId = requestInfo->info.messageId;
1041
1042         if (NULL != requestInfo->info.payload && requestInfo->info.payloadSize > 0)
1043         {
1044             len = requestInfo->info.payloadSize;
1045             char *clonePayload = (char *) malloc(len + 1);
1046             if (NULL == clonePayload)
1047             {
1048                 LOGE("clonePayload Out of memory");
1049                 free(g_clientEndpoint);
1050                 return;
1051             }
1052
1053             memcpy(clonePayload, requestInfo->info.payload, len);
1054             clonePayload[len] = '\0';
1055
1056             if (len > BIG_PAYLOAD_LENGTH)
1057             {
1058                 saveFile(clonePayload, len);
1059             }
1060             else
1061             {
1062                 callback("Data: ", clonePayload);
1063             }
1064             free(clonePayload);
1065         }
1066     }
1067
1068     if (requestInfo->info.options)
1069     {
1070         uint32_t len = requestInfo->info.numOptions;
1071         uint32_t i;
1072
1073         LOGI("Option count: %d", requestInfo->info.numOptions);
1074
1075         for (i = 0; i < len; i++)
1076         {
1077             LOGI("Option %d", i + 1);
1078             LOGI("ID : %d", requestInfo->info.options[i].optionID);
1079             LOGI("Data[%d]: %s", requestInfo->info.options[i].optionLength,
1080                  requestInfo->info.options[i].optionData);
1081
1082             if (NULL != g_responseListenerObject)
1083             {
1084                 char optionInfo[OPTION_INFO_LENGTH] = { 0, };
1085                 snprintf(optionInfo, OPTION_INFO_LENGTH,
1086                          "Num[%d] - ID : %d, Option Length : %d", i + 1,
1087                          requestInfo->info.options[i].optionID,
1088                          requestInfo->info.options[i].optionLength);
1089
1090                 callback("Option info: ", optionInfo);
1091
1092                 size_t optionDataLen = strlen(requestInfo->info.options[i].optionData);
1093                 char *cloneOptionData = (char *) malloc(sizeof(char) * (optionDataLen + 1));
1094                 if (NULL == cloneOptionData)
1095                 {
1096                     LOGE("cloneOptionData Out of memory");
1097                     free(g_clientEndpoint);
1098                     return;
1099                 }
1100
1101                 memcpy(cloneOptionData, requestInfo->info.options[i].optionData,
1102                        optionDataLen + 1);
1103
1104                 callback("Option Data: ", cloneOptionData);
1105                 free(cloneOptionData);
1106             }
1107         }
1108     }
1109     LOGI("############################################################");
1110
1111     //Check if this has secure communication information
1112     if (requestInfo->info.payload && CA_ADAPTER_IP == object->adapter)
1113     {
1114         uint32_t securePort = get_secure_information(requestInfo->info.payload);
1115         if (0 < securePort) //Set the remote endpoint secure details and send response
1116         {
1117             LOGI("This is secure resource...");
1118
1119             CAEndpoint_t *endpoint = NULL;
1120             if (CA_STATUS_OK != CACreateEndpoint(CA_SECURE,
1121                         object->adapter, object->addr, securePort, &endpoint))
1122             {
1123                 LOGE("Failed to create duplicate of remote endpoint!");
1124                 return;
1125             }
1126             object = endpoint;
1127         }
1128     }
1129 }
1130
1131 void response_handler(const CAEndpoint_t* object, const CAResponseInfo_t* responseInfo)
1132 {
1133     if (!object || !responseInfo)
1134     {
1135         LOGE("Invalid input parameter");
1136         return;
1137     }
1138
1139     CAResult_t res = get_remote_address(object->addr);
1140     if (CA_STATUS_OK != res)
1141     {
1142         return;
1143     }
1144
1145     LOGI("##########Received response from remote device #############");
1146     LOGI("Uri: %s", responseInfo->info.resourceUri);
1147     LOGI("Remote Address: %s", g_remoteAddress);
1148     LOGI("Remote Port: %d", object->port);
1149     LOGI("response result: %d", responseInfo->result);
1150     LOGI("Data: %s", responseInfo->info.payload);
1151     LOGI("Token: %s", responseInfo->info.token);
1152     LOGI("MessageType: %d", responseInfo->info.type);
1153
1154     if (NULL != g_responseListenerObject)
1155     {
1156         uint32_t len = 0;
1157
1158         if (NULL != responseInfo->info.resourceUri)
1159         {
1160             len = strlen(responseInfo->info.resourceUri);
1161             char *cloneUri = (char *) malloc(sizeof(char) * (len + 1));
1162
1163             if (NULL == cloneUri)
1164             {
1165                 LOGE("cloneUri Out of memory");
1166                 free(g_remoteAddress);
1167                 return;
1168             }
1169
1170             memcpy(cloneUri, responseInfo->info.resourceUri, len + 1);
1171
1172             callback("Uri: ", cloneUri);
1173             free(cloneUri);
1174         }
1175
1176         len = strlen(g_remoteAddress);
1177         char *cloneRemoteAddress = (char *) malloc(sizeof(char) * (len + 1));
1178
1179         if (NULL == cloneRemoteAddress)
1180         {
1181             LOGE("cloneRemoteAddress Out of memory");
1182             free(g_remoteAddress);
1183             return;
1184         }
1185
1186         memcpy(cloneRemoteAddress, g_remoteAddress, len + 1);
1187
1188         callback("Remote Address: ", cloneRemoteAddress);
1189         free(cloneRemoteAddress);
1190         free(g_remoteAddress);
1191
1192         char portInfo[PORT_LENGTH] = { 0, };
1193         snprintf(portInfo, PORT_LENGTH, "%d", object->port);
1194         callback("Remote Port: ", portInfo);
1195
1196         if (NULL != responseInfo->info.payload && responseInfo->info.payloadSize)
1197         {
1198             len = responseInfo->info.payloadSize;
1199             char *clonePayload = (char *) malloc(len + 1);
1200             if (NULL == clonePayload)
1201             {
1202                 LOGE("clonePayload Out of memory");
1203                 return;
1204             }
1205
1206             memcpy(clonePayload, responseInfo->info.payload, len);
1207             clonePayload[len] = '\0';
1208
1209             if (len > BIG_PAYLOAD_LENGTH)
1210             {
1211                 saveFile(clonePayload, len);
1212             }
1213             else
1214             {
1215                 callback("Data: ", clonePayload);
1216             }
1217             free(clonePayload);
1218         }
1219     }
1220
1221     if (responseInfo->info.options)
1222     {
1223         uint32_t len = responseInfo->info.numOptions;
1224         uint32_t i;
1225         for (i = 0; i < len; i++)
1226         {
1227             LOGI("Option %d", i + 1);
1228             LOGI("ID : %d", responseInfo->info.options[i].optionID);
1229             LOGI("Data[%d]: %s", responseInfo->info.options[i].optionLength,
1230                  responseInfo->info.options[i].optionData);
1231
1232             if (NULL != g_responseListenerObject)
1233             {
1234                 char optionInfo[OPTION_INFO_LENGTH] = { 0, };
1235                 snprintf(optionInfo, OPTION_INFO_LENGTH,
1236                          "Num[%d] - ID : %d, Option Length : %d", i + 1,
1237                          responseInfo->info.options[i].optionID,
1238                          responseInfo->info.options[i].optionLength);
1239
1240                 callback("Option info: ", optionInfo);
1241
1242                 size_t optionDataLen = strlen(responseInfo->info.options[i].optionData);
1243                 char *cloneOptionData = (char *) malloc(sizeof(char) * (optionDataLen + 1));
1244                 if (NULL == cloneOptionData)
1245                 {
1246                     LOGE("cloneOptionData Out of memory");
1247                     return;
1248                 }
1249                 memcpy(cloneOptionData, responseInfo->info.options[i].optionData,
1250                        optionDataLen + 1);
1251                 callback("Option Data: ", cloneOptionData);
1252                 free(cloneOptionData);
1253             }
1254         }
1255     }
1256     LOGI("############################################################");
1257
1258     //Check if this has secure communication information
1259     if (responseInfo->info.payload && CA_ADAPTER_IP == object->adapter)
1260     {
1261         uint32_t securePort = get_secure_information(responseInfo->info.payload);
1262         if (0 < securePort) //Set the remote endpoint secure details and send response
1263         {
1264             LOGI("This is secure resource...");
1265         }
1266     }
1267 }
1268
1269 void error_handler(const CAEndpoint_t *rep, const CAErrorInfo_t* errorInfo)
1270 {
1271     LOGI("+++++++++++++++++++++++++++++++++++ErrorInfo+++++++++++++++++++++++++++++++++++");
1272
1273     if (rep)
1274     {
1275         LOGI("Error Handler, Adapter Type : %d", rep->adapter);
1276         LOGI("Error Handler, Adapter Type : %s", rep->addr);
1277     }
1278
1279     if (errorInfo)
1280     {
1281         const CAInfo_t *info = &errorInfo->info;
1282         LOGI("Error Handler, ErrorInfo :");
1283         LOGI("Error Handler result    : %d", errorInfo->result);
1284         LOGI("Error Handler token     : %s", info->token);
1285         LOGI("Error Handler messageId : %d", (uint16_t) info->messageId);
1286         LOGI("Error Handler resourceUri : %s", info->resourceUri);
1287         LOGI("Error Handler type      : %d", info->type);
1288         LOGI("Error Handler payload   : %s", info->payload);
1289
1290         if(CA_ADAPTER_NOT_ENABLED == errorInfo->result)
1291         {
1292             LOGE("CA_ADAPTER_NOT_ENABLED, enable the adapter");
1293         }
1294         else if(CA_SEND_FAILED == errorInfo->result)
1295         {
1296             LOGE("CA_SEND_FAILED, unable to send the message, check parameters");
1297         }
1298         else if(CA_MEMORY_ALLOC_FAILED == errorInfo->result)
1299         {
1300             LOGE("CA_MEMORY_ALLOC_FAILED, insufficient memory");
1301         }
1302         else if(CA_SOCKET_OPERATION_FAILED == errorInfo->result)
1303         {
1304             LOGE("CA_SOCKET_OPERATION_FAILED, socket operation failed");
1305         }
1306         else if(CA_STATUS_FAILED == errorInfo->result)
1307         {
1308             LOGE("CA_STATUS_FAILED, message could not be delivered, internal error");
1309         }
1310     }
1311     LOGI("++++++++++++++++++++++++++++++++End of ErrorInfo++++++++++++++++++++++++++++++++");
1312
1313     return;
1314 }
1315
1316 void get_resource_uri(const char *URI, char *resourceURI, int32_t length)
1317 {
1318     const char *startPos = URI;
1319     const char *temp = strstr(URI, "://");
1320     if (NULL != temp)
1321     {
1322         startPos = strchr(temp + 3, '/');
1323         if (!startPos)
1324         {
1325             LOGE("Resource URI is missing");
1326             return;
1327         }
1328     }
1329
1330     const char *endPos = strchr(startPos, '?');
1331     if (!endPos)
1332     {
1333         endPos = URI + strlen(URI);
1334     }
1335     --endPos;
1336
1337     if (endPos - startPos <= length)
1338     {
1339         memcpy(resourceURI, startPos + 1, endPos - startPos);
1340     }
1341
1342     LOGI("URI: %s, ResourceURI: %s", URI, resourceURI);
1343 }
1344
1345 uint32_t get_secure_information(CAPayload_t payLoad)
1346 {
1347     LOGI("entering get_secure_information");
1348
1349     if (!payLoad)
1350     {
1351         LOGE("Payload is NULL");
1352         return -1;
1353     }
1354
1355     const char *subString = NULL;
1356     if (NULL == (subString = strstr((const char *) payLoad, "\"sec\":1")))
1357     {
1358         LOGE("This is not secure resource");
1359         return -1;
1360     }
1361
1362     if (NULL == (subString = strstr((const char *) payLoad, "\"port\":")))
1363     {
1364         LOGE("This secure resource does not have port information");
1365         return -1;
1366     }
1367
1368     const char *startPos = strstr(subString, ":");
1369     if (!startPos)
1370     {
1371         LOGE("Parsing failed !");
1372         return -1;
1373     }
1374
1375     const char *endPos = strstr(startPos, "}");
1376     if (!endPos)
1377     {
1378         LOGE("Parsing failed !");
1379         return -1;
1380     }
1381
1382     char portStr[6] = { 0 };
1383     memcpy(portStr, startPos + 1, (endPos - 1) - startPos);
1384
1385     LOGI("secured port is: %s", portStr);
1386     return atoi(portStr);
1387 }
1388
1389 CAResult_t get_network_type(uint32_t selectedNetwork, CATransportFlags_t *flags)
1390 {
1391
1392     uint32_t number = selectedNetwork;
1393
1394     if (!(number & CA_ALL_ADAPTERS))
1395     {
1396         LOGE("get_network_type Out of range");
1397         return CA_NOT_SUPPORTED;
1398     }
1399     if ((number & CA_ADAPTER_IP) == CA_ADAPTER_IP)
1400     {
1401         *flags = CA_IPV4;
1402         g_selectedNwType = CA_ADAPTER_IP;
1403         return CA_STATUS_OK;
1404     }
1405     if ((number & CA_ADAPTER_RFCOMM_BTEDR) == CA_ADAPTER_RFCOMM_BTEDR)
1406     {
1407         g_selectedNwType = CA_ADAPTER_RFCOMM_BTEDR;
1408         return CA_STATUS_OK;
1409     }
1410     if ((number & CA_ADAPTER_GATT_BTLE) == CA_ADAPTER_GATT_BTLE)
1411     {
1412         g_selectedNwType = CA_ADAPTER_GATT_BTLE;
1413         return CA_STATUS_OK;
1414     }
1415     if ((number & CA_ADAPTER_TCP) == CA_ADAPTER_TCP)
1416     {
1417         g_selectedNwType = CA_ADAPTER_TCP;
1418         return CA_STATUS_OK;
1419     }
1420     if ((number & CA_ADAPTER_NFC) == CA_ADAPTER_NFC)
1421     {
1422         g_selectedNwType = CA_ADAPTER_NFC;
1423         return CA_STATUS_OK;
1424     }
1425
1426    LOGE("Invalid transport");
1427    return CA_NOT_SUPPORTED;
1428 }
1429
1430 void callback(char *subject, char *receivedData)
1431 {
1432     bool isAttached = false;
1433     JNIEnv* env;
1434
1435     if (!g_responseListenerObject)
1436     {
1437         LOGE("g_responseListenerObject is NULL, cannot have callback");
1438         return;
1439     }
1440
1441     jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
1442     if (JNI_OK != res)
1443     {
1444         LOGI("Could not get JNIEnv pointer");
1445         res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
1446
1447         if (JNI_OK != res)
1448         {
1449             LOGE("AttachCurrentThread has failed");
1450             return;
1451         }
1452         isAttached = true;
1453     }
1454
1455     jclass cls = (*env)->GetObjectClass(env, g_responseListenerObject);
1456     if (!cls)
1457     {
1458         LOGE("could not get class");
1459         goto detach_thread;
1460     }
1461
1462     jmethodID mid = (*env)->GetMethodID(env, cls, "OnResponseReceived",
1463                                         "(Ljava/lang/String;Ljava/lang/String;)V");
1464     if (!mid)
1465     {
1466         LOGE("could not get Method ID");
1467         goto detach_thread;
1468     }
1469
1470     jstring jsubject = (*env)->NewStringUTF(env, (char*) subject);
1471     if (!jsubject)
1472     {
1473         LOGE("NewStringUTF failed");
1474         goto detach_thread;
1475     }
1476
1477     jstring jreceivedData = (*env)->NewStringUTF(env, (char*) receivedData);
1478     if (!jreceivedData)
1479     {
1480         LOGE("NewStringUTF failed");
1481         goto detach_thread;
1482     }
1483
1484     (*env)->CallVoidMethod(env, g_responseListenerObject, mid, jsubject, jreceivedData);
1485
1486 detach_thread :
1487     if (isAttached)
1488     {
1489         (*g_jvm)->DetachCurrentThread(g_jvm);
1490         LOGI("DetachCurrentThread");
1491     }
1492 }
1493
1494 CAResult_t get_remote_address(const char *address)
1495 {
1496     uint32_t len = strlen(address);
1497
1498     g_remoteAddress = (char *)malloc(sizeof (char) * (len + 1));
1499     if (NULL == g_remoteAddress)
1500     {
1501         LOGE("g_remoteAddress Out of memory");
1502         return CA_MEMORY_ALLOC_FAILED;
1503     }
1504
1505     memcpy(g_remoteAddress, address, len + 1);
1506
1507     return CA_STATUS_OK;
1508 }
1509
1510
1511 void parsing_coap_uri(const char* uri, addressSet_t* address, CATransportFlags_t *flags)
1512 {
1513     if (NULL == uri || NULL == address)
1514     {
1515         LOGE("parameter is null");
1516         return;
1517     }
1518
1519     // parse uri
1520     // #1. check prefix
1521     uint8_t startIndex = 0;
1522     if (strncmp(COAPS_PREFIX, uri, COAPS_PREFIX_LEN) == 0)
1523     {
1524         LOGI("uri has '%s' prefix", COAPS_PREFIX);
1525         startIndex = COAPS_PREFIX_LEN;
1526         *flags = CA_SECURE;
1527     }
1528     else if (strncmp(COAP_PREFIX, uri, COAP_PREFIX_LEN) == 0)
1529     {
1530         LOGI("uri has '%s' prefix", COAP_PREFIX);
1531         startIndex = COAP_PREFIX_LEN;
1532     }
1533     else if (strncmp(COAP_TCP_PREFIX, uri, COAP_TCP_PREFIX_LEN) == 0)
1534     {
1535         LOGI("uri has '%s' prefix\n", COAP_TCP_PREFIX);
1536         startIndex = COAP_TCP_PREFIX_LEN;
1537         *flags = CA_IPV4;
1538     }
1539
1540     // #2. copy uri for parse
1541     size_t len = strlen(uri) - startIndex;
1542
1543     if (len <= 0)
1544     {
1545         LOGE("uri length is 0!");
1546         return;
1547     }
1548
1549     char *cloneUri = (char *) calloc(len + 1, sizeof(char));
1550     if (NULL == cloneUri)
1551     {
1552         LOGE("Out of memory");
1553         return;
1554     }
1555
1556     OICStrcpy(cloneUri, len+1, &uri[startIndex]);
1557
1558     char *pstr = NULL;
1559     //filter out the resource uri
1560     char *pUrl = strtok_r(cloneUri, "/", &pstr);
1561
1562     if (pUrl)
1563     {
1564         LOGI("pAddress : %s", pUrl);
1565         int res = get_address_set(pUrl, address);
1566         if (res == -1)
1567         {
1568             LOGE("address parse error");
1569             return;
1570         }
1571     }
1572     else
1573     {
1574         LOGE("strtok_r error, could not get the address");
1575     }
1576
1577     return;
1578 }
1579
1580 int get_address_set(const char *pAddress, addressSet_t* outAddress)
1581 {
1582     if (NULL == pAddress || NULL == outAddress)
1583     {
1584         LOGE("parameter is null");
1585         return -1;
1586     }
1587
1588     size_t len = strlen(pAddress);
1589     int isIp = 0;
1590     size_t ipLen = 0;
1591
1592     for (size_t i = 0; i < len; i++)
1593     {
1594         if (pAddress[i] == '.')
1595         {
1596             isIp = 1;
1597         }
1598
1599         // found port number start index
1600         if (isIp && pAddress[i] == ':')
1601         {
1602             ipLen = i;
1603             break;
1604         }
1605     }
1606
1607     if (isIp)
1608     {
1609         if(ipLen && (ipLen <  sizeof(outAddress->ipAddress)))
1610         {
1611             strncpy(outAddress->ipAddress, pAddress, ipLen);
1612             outAddress->ipAddress[ipLen] = '\0';
1613         }
1614         else if (!ipLen && (len <  sizeof(outAddress->ipAddress)))
1615         {
1616             strncpy(outAddress->ipAddress, pAddress, len);
1617             outAddress->ipAddress[len] = '\0';
1618         }
1619         else
1620         {
1621             LOGE("IP Address too long: %d", ipLen==0 ? len : ipLen);
1622             return -1;
1623         }
1624
1625         if (ipLen > 0)
1626         {
1627             outAddress->port = atoi(pAddress + ipLen + 1);
1628         }
1629     }
1630     else
1631     {
1632         strncpy(outAddress->ipAddress, pAddress, len);
1633         outAddress->ipAddress[len] = '\0';
1634     }
1635
1636     return isIp;
1637 }
1638
1639 void delete_global_references(JNIEnv *env, jobject obj)
1640 {
1641     LOGI("delete_global_references");
1642     if (!env || !obj )
1643     {
1644         LOGI("Invalid input parameter");
1645         return;
1646     }
1647
1648     CADeleteGlobalReferences(env);
1649     (*env)->DeleteGlobalRef(env, g_responseListenerObject);
1650 }
1651
1652
1653 bool read_file(const char* name, char** bytes, size_t* length)
1654 {
1655     if (NULL == name)
1656     {
1657         LOGE("parameter is null");
1658         return false;
1659     }
1660
1661     FILE* file;
1662     char* buffer;
1663     long fileLen;
1664
1665     // Open file
1666     file = fopen(name, "rt");
1667     if (!file)
1668     {
1669         fprintf(stderr, "Unable to open file %s", name);
1670         return false;
1671     }
1672
1673     // Get file length
1674     fseek(file, 0, SEEK_END);
1675     fileLen = ftell(file);
1676     if (-1 == fileLen)
1677     {
1678         fprintf(stderr, "Failed to read file length");
1679         fclose(file);
1680         return false;
1681     }
1682     fseek(file, 0, SEEK_SET);
1683
1684     LOGI("file size: %ld", fileLen);
1685
1686     // Allocate memory
1687     buffer = calloc(1, sizeof(char) * fileLen + 1);
1688     if (!buffer)
1689     {
1690         fprintf(stderr, "Memory error!");
1691         fclose(file);
1692         return false;
1693     }
1694
1695     // Read file contents into buffer
1696     size_t ret = fread(buffer, fileLen, 1, file);
1697     if (ret != 1)
1698     {
1699         printf("Failed to read data from file, %s\n", name);
1700         fclose(file);
1701         free(buffer);
1702         return false;
1703     }
1704
1705     fclose(file);
1706
1707     LOGI("file bytes: %s", buffer);
1708
1709     *bytes = buffer;
1710     *length = fileLen;
1711
1712     return true;
1713 }
1714
1715 void saveFile(const char *payload, size_t payloadSize)
1716 {
1717     // 1. get day
1718     uint32_t day = gettodaydate();
1719
1720     // 2. get time
1721     time_t current_time;
1722     struct tm * time_info;
1723     char timeString[RECEIVED_FILE_NAME_PREFIX_LENGTH];
1724
1725     time(&current_time);
1726     time_info = localtime(&current_time);
1727
1728     strftime(timeString, sizeof(timeString), "%H%M%S", time_info);
1729
1730     uint32_t path_length = strlen(RECEIVED_FILE_PATH) + RECEIVED_FILE_NAME_LENGTH + 1;
1731     char* path = calloc(1, sizeof(char) * path_length);
1732     if (path != NULL)
1733     {
1734         snprintf(path, path_length, RECEIVED_FILE_PATH, day, timeString);
1735         LOGI("received file path: %s", path);
1736
1737         FILE *fp = fopen(path, "wt");
1738         fwrite(payload, 1, payloadSize, fp);
1739         fclose(fp);
1740
1741         callback("File Path: ", path);
1742     }
1743     else
1744     {
1745         LOGE("path Out of memory");
1746     }
1747 }
1748
1749 uint32_t gettodaydate()
1750 {
1751     uint32_t ldate;
1752     time_t clock;
1753     struct tm *date;
1754
1755     clock = time(0);
1756     date = localtime(&clock);
1757     ldate = date->tm_year * 100000;
1758     ldate += (date->tm_mon + 1) * 1000;
1759     ldate += date->tm_mday * 10;
1760     ldate += date->tm_wday;
1761     ldate += 190000000;
1762     ldate /= 10;
1763
1764     return(ldate);
1765 }