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