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                     return;
394                 }
395                 (*env)->ReleaseStringUTFChars(env, payload, path);
396
397                 requestData.payload = (CAPayload_t) malloc(payloadLength);
398                 if (NULL == requestData.payload)
399                 {
400                     LOGE("Memory allocation failed!");
401                     // destroy token
402                     CADestroyToken(token);
403                     // destroy remote endpoint
404                     CADestroyEndpoint(endpoint);
405                     return;
406                 }
407                 memcpy(requestData.payload, bigData, payloadLength);
408                 requestData.payloadSize = payloadLength;
409             }
410         }
411     }
412     else
413     {
414         if (isSecured)
415         {
416             payloadLength = sizeof(SECURE_INFO_DATA) + strlen(resourceURI);
417             requestData.payload = (CAPayload_t) malloc(payloadLength);
418             if (NULL == requestData.payload)
419             {
420                 LOGE("Memory allocation failed!");
421                 // destroy token
422                 CADestroyToken(token);
423                 // destroy remote endpoint
424                 CADestroyEndpoint(endpoint);
425                 return;
426             }
427             snprintf((char *) requestData.payload, payloadLength, SECURE_INFO_DATA,
428                      resourceURI, g_localSecurePort);
429             requestData.payloadSize = payloadLength;
430         }
431         else
432         {
433             payloadLength = sizeof(NORMAL_INFO_DATA) + strlen(resourceURI);
434             requestData.payload = (CAPayload_t) malloc(payloadLength);
435             if (NULL == requestData.payload)
436             {
437                 LOGE("Memory allocation failed!");
438                 // destroy token
439                 CADestroyToken(token);
440                 // destroy remote endpoint
441                 CADestroyEndpoint(endpoint);
442                 return;
443             }
444             snprintf((char *) requestData.payload, payloadLength, NORMAL_INFO_DATA, resourceURI);
445             requestData.payloadSize = payloadLength;
446         }
447     }
448
449     requestData.type = messageType;
450     requestData.resourceUri = (CAURI_t) malloc(sizeof(resourceURI));
451     if (NULL == requestData.resourceUri)
452     {
453         LOGE("Memory allocation failed!");
454         // destroy token
455         CADestroyToken(token);
456         // destroy remote endpoint
457         CADestroyEndpoint(endpoint);
458         free(requestData.payload);
459         return;
460     }
461     memcpy(requestData.resourceUri, resourceURI, sizeof(resourceURI));
462
463     CARequestInfo_t requestInfo = { 0 };
464     requestInfo.method = CA_GET;
465     requestInfo.isMulticast = false;
466     requestInfo.info = requestData;
467
468     // send request
469     if (CA_STATUS_OK != CASendRequest(endpoint, &requestInfo))
470     {
471         LOGE("Could not send request");
472     }
473
474     // destroy token
475     CADestroyToken(token);
476
477     // destroy remote endpoint
478     CADestroyEndpoint(endpoint);
479
480     free(requestData.payload);
481     free(requestData.resourceUri);
482 }
483
484 JNIEXPORT void JNICALL
485 Java_org_iotivity_ca_service_RMInterface_RMSendReqestToAll(JNIEnv *env, jobject obj, jstring uri,
486                                                            jint selectedNetwork)
487 {
488     LOGI("selectedNetwork - %d", selectedNetwork);
489     if (!env || !obj)
490     {
491         LOGI("Invalid input parameter");
492         return;
493     }
494
495     CAResult_t res = get_network_type(selectedNetwork);
496     if (CA_STATUS_OK != res)
497     {
498         return;
499     }
500
501     // create remote endpoint
502     CAEndpoint_t *endpoint = NULL;
503     res = CACreateEndpoint(CA_IPV4, g_selectedNwType, NULL, 0, &endpoint);
504
505     if (CA_STATUS_OK != res)
506     {
507         LOGE("create remote endpoint error, error code: %d", res);
508         return;
509     }
510
511     // create token
512     CAToken_t token = NULL;
513     uint8_t tokenLength = CA_MAX_TOKEN_LEN;
514
515     res = CAGenerateToken(&token, tokenLength);
516     if ((CA_STATUS_OK != res) || (!token))
517     {
518         LOGE("token generate error!!");
519         // destroy remote endpoint
520         CADestroyEndpoint(endpoint);
521         return;
522     }
523
524     LOGI("generated token %s", token);
525
526     CAInfo_t requestData = { 0 };
527     requestData.token = token;
528     requestData.tokenLength = tokenLength;
529     requestData.payload = (CAPayload_t) "TempJsonPayload";
530     requestData.payloadSize = strlen((const char *) requestData.payload);
531     requestData.type = CA_MSG_NONCONFIRM;
532
533     const char* strUri = (*env)->GetStringUTFChars(env, uri, NULL);
534     LOGI("resourceUri - %s", strUri);
535     requestData.resourceUri = (CAURI_t)strUri;
536
537     uint8_t optionNum = 2;
538     CAHeaderOption_t *headerOpt = (CAHeaderOption_t*) calloc(1,
539                                                              sizeof(CAHeaderOption_t) * optionNum);
540     if (NULL == headerOpt)
541     {
542         LOGE("Memory allocation failed");
543         // destroy remote endpoint
544         CADestroyEndpoint(endpoint);
545         return;
546     }
547
548     char* FirstOptionData = "Hello";
549     headerOpt[0].optionID = 3000;
550     memcpy(headerOpt[0].optionData, FirstOptionData, strlen(FirstOptionData));
551     headerOpt[0].optionLength = (uint16_t) strlen(FirstOptionData);
552
553     char* SecondOptionData2 = "World";
554     headerOpt[1].optionID = 3001;
555     memcpy(headerOpt[1].optionData, SecondOptionData2, strlen(SecondOptionData2));
556     headerOpt[1].optionLength = (uint16_t) strlen(SecondOptionData2);
557
558     requestData.numOptions = optionNum;
559     requestData.options = headerOpt;
560
561     CARequestInfo_t requestInfo = { 0 };
562     requestInfo.method = CA_GET;
563     requestInfo.isMulticast = true;
564     requestInfo.info = requestData;
565
566     // send request to all
567     res = CASendRequest(endpoint, &requestInfo);
568     if (CA_STATUS_OK != res)
569     {
570         LOGE("Could not send request to all");
571         //destroy token
572         CADestroyToken(token);
573     }
574     else
575     {
576         CADestroyToken(g_lastRequestToken);
577         g_lastRequestToken = token;
578         g_lastRequestTokenLength = tokenLength;
579     }
580
581     //ReleaseStringUTFChars for strUri
582     (*env)->ReleaseStringUTFChars(env, uri, strUri);
583
584     free(headerOpt);
585
586     // destroy remote endpoint
587     CADestroyEndpoint(endpoint);
588 }
589
590 JNIEXPORT void JNICALL
591 Java_org_iotivity_ca_service_RMInterface_RMSendResponse(JNIEnv *env, jobject obj,
592                                                         jint selectedNetwork,
593                                                         jint isSecured, jint msgType,
594                                                         jint responseValue)
595 {
596     LOGI("RMSendResponse");
597     if (!env || !obj)
598     {
599         LOGI("Invalid input parameter");
600         return;
601     }
602
603     LOGI("selectedNetwork - %d", selectedNetwork);
604
605     CAResult_t res = get_network_type(selectedNetwork);
606     if (CA_STATUS_OK != res)
607     {
608         LOGE("Not supported network type");
609         return;
610     }
611
612     if (NULL == g_clientEndpoint)
613     {
614         LOGE("No Request received");
615         return;
616     }
617
618     CAMessageType_t messageType = msgType;
619
620     CAInfo_t responseData = { 0 };
621     responseData.type = messageType;
622     responseData.messageId = g_clientMsgId;
623     responseData.resourceUri = (CAURI_t)g_resourceUri;
624
625     CAResponseInfo_t responseInfo = { 0 };
626
627     if (msgType != CA_MSG_RESET)
628     {
629         responseData.token = g_clientToken;
630         responseData.tokenLength = g_clientTokenLength;
631         responseInfo.result = responseValue;
632
633         if (1 == isSecured)
634         {
635             uint32_t length = strlen(SECURE_INFO_DATA) + strlen(g_resourceUri) + 1;
636             responseData.payload = (CAPayload_t) malloc(length);
637             sprintf((char *) responseData.payload, SECURE_INFO_DATA, g_resourceUri,
638                     g_localSecurePort);
639             responseData.payloadSize = length;
640         }
641         else
642         {
643             uint32_t length = strlen(NORMAL_INFO_DATA) + strlen(g_resourceUri) + 1;
644             responseData.payload = (CAPayload_t) malloc(length);
645             sprintf((char *) responseData.payload, NORMAL_INFO_DATA, g_resourceUri);
646             responseData.payloadSize = length;
647         }
648     }
649     //msgType is RESET
650     else
651     {
652         responseInfo.result = CA_EMPTY;
653     }
654
655     responseInfo.info = responseData;
656
657     // send response
658     res = CASendResponse(g_clientEndpoint, &responseInfo);
659     if (CA_STATUS_OK != res)
660     {
661         LOGE("Could not send response");
662     }
663
664     // destroy token
665     CADestroyToken(g_clientToken);
666     g_clientToken = NULL;
667     g_clientTokenLength = 0;
668
669     // destroy remote endpoint
670     CADestroyEndpoint(g_clientEndpoint);
671     g_clientEndpoint = NULL;
672 }
673
674 JNIEXPORT void JNICALL
675 Java_org_iotivity_ca_service_RMInterface_RMSendNotification(JNIEnv *env, jobject obj, jstring uri,
676                                                             jstring payload, jint selectedNetwork,
677                                                             jint isSecured, jint msgType,
678                                                             jint responseValue)
679 {
680     LOGI("selectedNetwork - %d", selectedNetwork);
681     if (!env || !obj)
682     {
683         LOGI("Invalid input parameter");
684         return;
685     }
686
687     if (!payload)
688     {
689         LOGE("payload is NULL");
690     }
691
692     if (!uri)
693     {
694         LOGE("Invalid input parameter : uri");
695         return;
696     }
697
698     CAResult_t res = get_network_type(selectedNetwork);
699     if (CA_STATUS_OK != res)
700     {
701         LOGE("Not supported network type");
702         return;
703     }
704
705     const char* strUri = (*env)->GetStringUTFChars(env, uri, NULL);
706     LOGI("RMSendNotification - %s", strUri);
707
708     CATransportFlags_t flags;
709     addressSet_t address = {{0}, 0};
710     parsing_coap_uri(strUri, &address, &flags);
711
712     //create remote endpoint
713     CAEndpoint_t* endpoint = NULL;
714     if (CA_STATUS_OK != CACreateEndpoint(flags, g_selectedNwType,
715                                          (const char*)address.ipAddress,
716                                          address.port, &endpoint))
717     {
718         //ReleaseStringUTFChars for strUri
719         (*env)->ReleaseStringUTFChars(env, uri, strUri);
720         LOGE("Could not create remote end point");
721         return;
722     }
723
724     char resourceURI[RESOURCE_URI_LENGTH + 1] = { 0 };
725     get_resource_uri(strUri, resourceURI, RESOURCE_URI_LENGTH);
726
727     //ReleaseStringUTFChars for strUri
728     (*env)->ReleaseStringUTFChars(env, uri, strUri);
729
730     CAMessageType_t messageType = msgType;
731
732     // create token
733     CAToken_t token = NULL;
734     uint8_t tokenLength = CA_MAX_TOKEN_LEN;
735
736     res = CAGenerateToken(&token, tokenLength);
737     if ((CA_STATUS_OK != res) || (!token))
738     {
739         LOGE("token generate error!");
740         CADestroyEndpoint(endpoint);
741         return;
742     }
743
744     CAInfo_t responseData = { 0 };
745     responseData.token = token;
746     responseData.tokenLength = tokenLength;
747     responseData.resourceUri = (CAURI_t) malloc(sizeof(resourceURI));
748     if (NULL == responseData.resourceUri)
749     {
750         LOGE("Memory allocation failed!");
751         // destroy token
752         CADestroyToken(token);
753         // destroy remote endpoint
754         CADestroyEndpoint(endpoint);
755         return;
756     }
757     memcpy(responseData.resourceUri, resourceURI, sizeof(resourceURI));
758
759     if (1 == isSecured)
760     {
761         uint32_t length = sizeof(SECURE_INFO_DATA) + strlen(resourceURI);
762         responseData.payload = (CAPayload_t) malloc(length);
763         if (NULL == responseData.payload)
764         {
765             LOGE("Memory allocation failed!");
766             // destroy token
767             CADestroyToken(token);
768             // destroy remote endpoint
769             CADestroyEndpoint(endpoint);
770
771             free(responseData.resourceUri);
772             return;
773         }
774         snprintf((char *) responseData.payload, length, SECURE_INFO_DATA, resourceURI, g_localSecurePort);
775         responseData.payloadSize = length;
776     }
777     else
778     {
779         uint32_t length = sizeof(NORMAL_INFO_DATA) + strlen(resourceURI);
780         responseData.payload = (CAPayload_t) malloc(length);
781         if (NULL == responseData.payload)
782         {
783             LOGE("Memory allocation failed!");
784             // destroy token
785             CADestroyToken(token);
786             // destroy remote endpoint
787             CADestroyEndpoint(endpoint);
788
789             free(responseData.resourceUri);
790             return;
791         }
792         snprintf((char *) responseData.payload, length, NORMAL_INFO_DATA, resourceURI);
793         responseData.payloadSize = length;
794     }
795
796     responseData.type = messageType;
797
798     CAResponseInfo_t responseInfo = { 0 };
799     responseInfo.result = responseValue;
800     responseInfo.info = responseData;
801
802     // send notification
803     if (CA_STATUS_OK != CASendNotification(endpoint, &responseInfo))
804     {
805         LOGE("Could not send notification");
806     }
807
808     LOGI("Send Notification");
809
810     // destroy token
811     CADestroyToken(token);
812
813     // destroy remote endpoint
814     CADestroyEndpoint(endpoint);
815
816     free(responseData.payload);
817     free(responseData.resourceUri);
818 }
819
820 JNIEXPORT void JNICALL
821 Java_org_iotivity_ca_service_RMInterface_RMSelectNetwork(JNIEnv *env, jobject obj,
822                                                          jint networkType)
823 {
824     LOGI("RMSelectNetwork Type : %d", networkType);
825     if (!env || !obj)
826     {
827         LOGI("Invalid input parameter");
828         return;
829     }
830
831     if (CA_STATUS_OK != CASelectNetwork(networkType))
832     {
833         LOGE("Could not select network");
834     }
835 }
836
837 JNIEXPORT void JNICALL
838 Java_org_iotivity_ca_service_RMInterface_RMUnSelectNetwork(JNIEnv *env, jobject obj,
839                                                            jint networkType)
840 {
841     LOGI("RMUnSelectNetwork Type : %d", networkType);
842     if (!env || !obj)
843     {
844         LOGI("Invalid input parameter");
845         return;
846     }
847
848     if (CA_STATUS_OK != CAUnSelectNetwork(networkType))
849     {
850         LOGE("Could not unselect network");
851     }
852 }
853
854 JNIEXPORT void JNICALL
855 Java_org_iotivity_ca_service_RMInterface_RMGetNetworkInfomation(JNIEnv *env, jobject obj)
856 {
857     LOGI("RMGetNetworkInfomation");
858     if (!env || !obj)
859     {
860         LOGI("Invalid input parameter");
861         return;
862     }
863
864     CAEndpoint_t *tempInfo = NULL;
865     uint32_t tempSize = 0;
866
867     CAResult_t res = CAGetNetworkInformation(&tempInfo, &tempSize);
868     if (CA_STATUS_OK != res)
869     {
870         LOGE("Could not start get network information");
871         free(tempInfo);
872         return;
873     }
874
875     LOGI("################## Network Information #######################");
876     callback("######## Network Information", "#######");
877     LOGI("Network info total size is %d", tempSize);
878
879     uint32_t index;
880     for (index = 0; index < tempSize; index++)
881     {
882         res = get_remote_address(tempInfo[index].addr);
883         if (CA_STATUS_OK != res)
884         {
885             free(tempInfo);
886             return;
887         }
888         if (NULL != g_responseListenerObject)
889         {
890             char networkInfo[NETWORK_INFO_LENGTH];
891             LOGI("Type: %d", tempInfo[index].adapter);
892             sprintf(networkInfo, "%d",tempInfo[index].adapter);
893             callback("Type :", networkInfo);
894             if (CA_ADAPTER_IP == tempInfo[index].adapter)
895             {
896                 LOGI("Port: %d", tempInfo[index].port);
897                 sprintf(networkInfo, "%d",tempInfo[index].port);
898                 callback("Port: ", networkInfo);
899             }
900             LOGI("Secured: %d", (tempInfo[index].flags & CA_SECURE));
901             LOGI("Address: %s", g_remoteAddress);
902             callback("Address: ", g_remoteAddress);
903             free(g_remoteAddress);
904         }
905         if (tempInfo[index].flags & CA_SECURE)
906         {
907             g_localSecurePort = tempInfo[index].port;
908         }
909     }
910
911     // free
912     free(tempInfo);
913
914     LOGI("##############################################################");
915 }
916
917 JNIEXPORT void JNICALL
918 Java_org_iotivity_ca_service_RMInterface_RMHandleRequestResponse(JNIEnv *env, jobject obj)
919 {
920     LOGI("RMHandleRequestResponse");
921     if(!env || !obj)
922     {
923         LOGI("Invalid input parameter");
924         return;
925     }
926
927     if (CA_STATUS_OK != CAHandleRequestResponse())
928     {
929         LOGE("Could not handle request and response");
930     }
931 }
932
933 void request_handler(const CAEndpoint_t* object, const CARequestInfo_t* requestInfo)
934 {
935
936     if (!object)
937     {
938         LOGE("Remote endpoint is NULL!");
939         return;
940     }
941
942     if (!requestInfo)
943     {
944         LOGE("Request info is NULL!");
945         return;
946     }
947
948     if ((NULL != g_lastRequestToken) && (NULL != requestInfo->info.token) &&
949             (strncmp(g_lastRequestToken, requestInfo->info.token,
950                      requestInfo->info.tokenLength) == 0))
951     {
952         LOGI("token is same. received request of it's own. skip.. ");
953         return;
954     }
955
956     CAResult_t res = get_remote_address(object->addr);
957     if (CA_STATUS_OK != res)
958     {
959         return;
960     }
961
962     LOGI("##########received request from remote device #############");
963     LOGI("Remote Address: %s", g_remoteAddress);
964     LOGI("Remote Port: %d", object->port);
965     LOGI("Uri: %s", requestInfo->info.resourceUri);
966     LOGI("Data: %s", requestInfo->info.payload);
967     LOGI("Token: %s", requestInfo->info.token);
968     LOGI("Code: %d", requestInfo->method);
969     LOGI("MessageType: %d", requestInfo->info.type);
970
971     if (NULL != g_responseListenerObject)
972     {
973         char *cloneUri = NULL;
974         uint32_t len = 0;
975
976         if (NULL != requestInfo->info.resourceUri)
977         {
978             len = strlen(requestInfo->info.resourceUri);
979             cloneUri = (char *)malloc(sizeof(char) * (len + 1));
980
981             if (NULL == cloneUri)
982             {
983                 LOGE("cloneUri Out of memory");
984                 free(g_remoteAddress);
985                 return;
986             }
987
988             memcpy(cloneUri, requestInfo->info.resourceUri, len + 1);
989             callback("Uri: ", cloneUri);
990         }
991
992         len = strlen(g_remoteAddress);
993         char *cloneRemoteAddress = (char *) malloc(sizeof(char) * (len + 1));
994
995         if (NULL == cloneRemoteAddress)
996         {
997             LOGE("cloneRemoteAddress Out of memory");
998             free(g_remoteAddress);
999             free(cloneUri);
1000             return;
1001         }
1002
1003         memcpy(cloneRemoteAddress, g_remoteAddress, len + 1);
1004
1005         callback("Remote Address: ", cloneRemoteAddress);
1006         free(cloneRemoteAddress);
1007         free(g_remoteAddress);
1008
1009         char portInfo[PORT_LENGTH] = { 0, };
1010         sprintf(portInfo, "%d", object->port);
1011         callback("Remote Port: ", portInfo);
1012
1013         //clone g_clientEndpoint
1014         g_clientEndpoint = (CAEndpoint_t *) malloc(sizeof(CAEndpoint_t));
1015         if (NULL == g_clientEndpoint)
1016         {
1017             LOGE("g_clientEndpoint Out of memory");
1018             free(cloneUri);
1019             return;
1020         }
1021         memcpy(g_clientEndpoint, object, sizeof(CAEndpoint_t));
1022
1023         if (NULL != cloneUri)
1024         {
1025             len = strlen(cloneUri);
1026             g_resourceUri = (char *) malloc(sizeof(char) * (len + 1));
1027             if (NULL == g_resourceUri)
1028             {
1029                 LOGE("g_clientEndpoint->resourceUri Out of memory");
1030                 free(g_clientEndpoint);
1031                 free(cloneUri);
1032                 return;
1033             }
1034             memcpy(g_resourceUri, cloneUri, len + 1);
1035             free(cloneUri);
1036         }
1037         //clone g_clientToken
1038         len = requestInfo->info.tokenLength;
1039
1040         g_clientToken = (char *) malloc(sizeof(char) * len);
1041         if (NULL == g_clientToken)
1042         {
1043             LOGE("g_clientToken Out of memory");
1044             free(g_clientEndpoint);
1045             return;
1046         }
1047
1048         if (NULL != requestInfo->info.token)
1049         {
1050             memcpy(g_clientToken, requestInfo->info.token, len);
1051             g_clientTokenLength = len;
1052
1053         }
1054
1055         //clone g_clientMsgId
1056         g_clientMsgId = requestInfo->info.messageId;
1057
1058         if (NULL != requestInfo->info.payload && requestInfo->info.payloadSize > 0)
1059         {
1060             len = requestInfo->info.payloadSize;
1061             char *clonePayload = (char *) malloc(len + 1);
1062             if (NULL == clonePayload)
1063             {
1064                 LOGE("clonePayload Out of memory");
1065                 free(g_clientEndpoint);
1066                 return;
1067             }
1068
1069             memcpy(clonePayload, requestInfo->info.payload, len);
1070             clonePayload[len] = '\0';
1071
1072             if (len > BIG_PAYLOAD_LENGTH)
1073             {
1074                 saveFile(clonePayload, len);
1075             }
1076             else
1077             {
1078                 callback("Data: ", clonePayload);
1079             }
1080             free(clonePayload);
1081         }
1082     }
1083
1084     if (requestInfo->info.options)
1085     {
1086         uint32_t len = requestInfo->info.numOptions;
1087         uint32_t i;
1088
1089         LOGI("Option count: %d", requestInfo->info.numOptions);
1090
1091         for (i = 0; i < len; i++)
1092         {
1093             LOGI("Option %d", i + 1);
1094             LOGI("ID : %d", requestInfo->info.options[i].optionID);
1095             LOGI("Data[%d]: %s", requestInfo->info.options[i].optionLength,
1096                  requestInfo->info.options[i].optionData);
1097
1098             if (NULL != g_responseListenerObject)
1099             {
1100                 char optionInfo[OPTION_INFO_LENGTH] = { 0, };
1101                 sprintf(optionInfo, "Num[%d] - ID : %d, Option Length : %d", i + 1,
1102                         requestInfo->info.options[i].optionID,
1103                         requestInfo->info.options[i].optionLength);
1104
1105                 callback("Option info: ", optionInfo);
1106
1107                 size_t optionDataLen = strlen(requestInfo->info.options[i].optionData);
1108                 char *cloneOptionData = (char *) malloc(sizeof(char) * (optionDataLen + 1));
1109                 if (NULL == cloneOptionData)
1110                 {
1111                     LOGE("cloneOptionData Out of memory");
1112                     free(g_clientEndpoint);
1113                     return;
1114                 }
1115
1116                 memcpy(cloneOptionData, requestInfo->info.options[i].optionData,
1117                        optionDataLen + 1);
1118
1119                 callback("Option Data: ", cloneOptionData);
1120                 free(cloneOptionData);
1121             }
1122         }
1123     }
1124     LOGI("############################################################");
1125
1126     //Check if this has secure communication information
1127     if (requestInfo->info.payload && CA_ADAPTER_IP == object->adapter)
1128     {
1129         uint32_t securePort = get_secure_information(requestInfo->info.payload);
1130         if (0 < securePort) //Set the remote endpoint secure details and send response
1131         {
1132             LOGI("This is secure resource...");
1133
1134             CAEndpoint_t *endpoint = NULL;
1135             if (CA_STATUS_OK != CACreateEndpoint(CA_SECURE,
1136                         object->adapter, object->addr, securePort, &endpoint))
1137             {
1138                 LOGE("Failed to create duplicate of remote endpoint!");
1139                 return;
1140             }
1141             object = endpoint;
1142         }
1143     }
1144 }
1145
1146 void response_handler(const CAEndpoint_t* object, const CAResponseInfo_t* responseInfo)
1147 {
1148     if (!object || !responseInfo)
1149     {
1150         LOGE("Invalid input parameter");
1151         return;
1152     }
1153
1154     CAResult_t res = get_remote_address(object->addr);
1155     if (CA_STATUS_OK != res)
1156     {
1157         return;
1158     }
1159
1160     LOGI("##########Received response from remote device #############");
1161     LOGI("Uri: %s", responseInfo->info.resourceUri);
1162     LOGI("Remote Address: %s", g_remoteAddress);
1163     LOGI("Remote Port: %d", object->port);
1164     LOGI("response result: %d", responseInfo->result);
1165     LOGI("Data: %s", responseInfo->info.payload);
1166     LOGI("Token: %s", responseInfo->info.token);
1167     LOGI("MessageType: %d", responseInfo->info.type);
1168
1169     if (NULL != g_responseListenerObject)
1170     {
1171         uint32_t len = 0;
1172
1173         if (NULL != responseInfo->info.resourceUri)
1174         {
1175             len = strlen(responseInfo->info.resourceUri);
1176             char *cloneUri = (char *) malloc(sizeof(char) * (len + 1));
1177
1178             if (NULL == cloneUri)
1179             {
1180                 LOGE("cloneUri Out of memory");
1181                 free(g_remoteAddress);
1182                 return;
1183             }
1184
1185             memcpy(cloneUri, responseInfo->info.resourceUri, len + 1);
1186
1187             callback("Uri: ", cloneUri);
1188             free(cloneUri);
1189         }
1190
1191         len = strlen(g_remoteAddress);
1192         char *cloneRemoteAddress = (char *) malloc(sizeof(char) * (len + 1));
1193
1194         if (NULL == cloneRemoteAddress)
1195         {
1196             LOGE("cloneRemoteAddress Out of memory");
1197             free(g_remoteAddress);
1198             return;
1199         }
1200
1201         memcpy(cloneRemoteAddress, g_remoteAddress, len + 1);
1202
1203         callback("Remote Address: ", cloneRemoteAddress);
1204         free(cloneRemoteAddress);
1205         free(g_remoteAddress);
1206
1207         char portInfo[PORT_LENGTH] = { 0, };
1208         sprintf(portInfo, "%d", object->port);
1209         callback("Remote Port: ", portInfo);
1210
1211         if (NULL != responseInfo->info.payload && responseInfo->info.payloadSize)
1212         {
1213             len = responseInfo->info.payloadSize;
1214             char *clonePayload = (char *) malloc(len + 1);
1215             if (NULL == clonePayload)
1216             {
1217                 LOGE("clonePayload Out of memory");
1218                 return;
1219             }
1220
1221             memcpy(clonePayload, responseInfo->info.payload, len);
1222             clonePayload[len] = '\0';
1223
1224             if (len > BIG_PAYLOAD_LENGTH)
1225             {
1226                 saveFile(clonePayload, len);
1227             }
1228             else
1229             {
1230                 callback("Data: ", clonePayload);
1231             }
1232             free(clonePayload);
1233         }
1234     }
1235
1236     if (responseInfo->info.options)
1237     {
1238         uint32_t len = responseInfo->info.numOptions;
1239         uint32_t i;
1240         for (i = 0; i < len; i++)
1241         {
1242             LOGI("Option %d", i + 1);
1243             LOGI("ID : %d", responseInfo->info.options[i].optionID);
1244             LOGI("Data[%d]: %s", responseInfo->info.options[i].optionLength,
1245                  responseInfo->info.options[i].optionData);
1246
1247             if (NULL != g_responseListenerObject)
1248             {
1249                 char optionInfo[OPTION_INFO_LENGTH] = { 0, };
1250                 sprintf(optionInfo, "Num[%d] - ID : %d, Option Length : %d", i + 1,
1251                         responseInfo->info.options[i].optionID,
1252                         responseInfo->info.options[i].optionLength);
1253
1254                 callback("Option info: ", optionInfo);
1255
1256                 size_t optionDataLen = strlen(responseInfo->info.options[i].optionData);
1257                 char *cloneOptionData = (char *) malloc(sizeof(char) * (optionDataLen + 1));
1258                 if (NULL == cloneOptionData)
1259                 {
1260                     LOGE("cloneOptionData Out of memory");
1261                     return;
1262                 }
1263                 memcpy(cloneOptionData, responseInfo->info.options[i].optionData,
1264                        optionDataLen + 1);
1265                 callback("Option Data: ", cloneOptionData);
1266                 free(cloneOptionData);
1267             }
1268         }
1269     }
1270     LOGI("############################################################");
1271
1272     //Check if this has secure communication information
1273     if (responseInfo->info.payload && CA_ADAPTER_IP == object->adapter)
1274     {
1275         uint32_t securePort = get_secure_information(responseInfo->info.payload);
1276         if (0 < securePort) //Set the remote endpoint secure details and send response
1277         {
1278             LOGI("This is secure resource...");
1279         }
1280     }
1281 }
1282
1283 void error_handler(const CAEndpoint_t *rep, const CAErrorInfo_t* errorInfo)
1284 {
1285     LOGI("+++++++++++++++++++++++++++++++++++ErrorInfo+++++++++++++++++++++++++++++++++++");
1286
1287     if (rep)
1288     {
1289         LOGI("Error Handler, Adapter Type : %d", rep->adapter);
1290         LOGI("Error Handler, Adapter Type : %s", rep->addr);
1291     }
1292
1293     if (errorInfo)
1294     {
1295         const CAInfo_t *info = &errorInfo->info;
1296         LOGI("Error Handler, ErrorInfo :");
1297         LOGI("Error Handler result    : %d", errorInfo->result);
1298         LOGI("Error Handler token     : %s", info->token);
1299         LOGI("Error Handler messageId : %d", (uint16_t) info->messageId);
1300         LOGI("Error Handler resourceUri : %s", info->resourceUri);
1301         LOGI("Error Handler type      : %d", info->type);
1302         LOGI("Error Handler payload   : %s", info->payload);
1303
1304         if(CA_ADAPTER_NOT_ENABLED == errorInfo->result)
1305         {
1306             LOGE("CA_ADAPTER_NOT_ENABLED, enable the adapter");
1307         }
1308         else if(CA_SEND_FAILED == errorInfo->result)
1309         {
1310             LOGE("CA_SEND_FAILED, unable to send the message, check parameters");
1311         }
1312         else if(CA_MEMORY_ALLOC_FAILED == errorInfo->result)
1313         {
1314             LOGE("CA_MEMORY_ALLOC_FAILED, insufficient memory");
1315         }
1316         else if(CA_SOCKET_OPERATION_FAILED == errorInfo->result)
1317         {
1318             LOGE("CA_SOCKET_OPERATION_FAILED, socket operation failed");
1319         }
1320         else if(CA_STATUS_FAILED == errorInfo->result)
1321         {
1322             LOGE("CA_STATUS_FAILED, message could not be delivered, internal error");
1323         }
1324     }
1325     LOGI("++++++++++++++++++++++++++++++++End of ErrorInfo++++++++++++++++++++++++++++++++");
1326
1327     return;
1328 }
1329
1330 void get_resource_uri(const char *URI, char *resourceURI, int32_t length)
1331 {
1332     const char *startPos = URI;
1333     const char *temp = strstr(URI, "://");
1334     if (NULL != temp)
1335     {
1336         startPos = strchr(temp + 3, '/');
1337         if (!startPos)
1338         {
1339             LOGE("Resource URI is missing");
1340             return;
1341         }
1342     }
1343
1344     const char *endPos = strchr(startPos, '?');
1345     if (!endPos)
1346     {
1347         endPos = URI + strlen(URI);
1348     }
1349     --endPos;
1350
1351     if (endPos - startPos <= length)
1352     {
1353         memcpy(resourceURI, startPos + 1, endPos - startPos);
1354     }
1355
1356     LOGI("URI: %s, ResourceURI: %s", URI, resourceURI);
1357 }
1358
1359 uint32_t get_secure_information(CAPayload_t payLoad)
1360 {
1361     LOGI("entering get_secure_information");
1362
1363     if (!payLoad)
1364     {
1365         LOGE("Payload is NULL");
1366         return -1;
1367     }
1368
1369     const char *subString = NULL;
1370     if (NULL == (subString = strstr((const char *) payLoad, "\"sec\":1")))
1371     {
1372         LOGE("This is not secure resource");
1373         return -1;
1374     }
1375
1376     if (NULL == (subString = strstr((const char *) payLoad, "\"port\":")))
1377     {
1378         LOGE("This secure resource does not have port information");
1379         return -1;
1380     }
1381
1382     const char *startPos = strstr(subString, ":");
1383     if (!startPos)
1384     {
1385         LOGE("Parsing failed !");
1386         return -1;
1387     }
1388
1389     const char *endPos = strstr(startPos, "}");
1390     if (!endPos)
1391     {
1392         LOGE("Parsing failed !");
1393         return -1;
1394     }
1395
1396     char portStr[6] = { 0 };
1397     memcpy(portStr, startPos + 1, (endPos - 1) - startPos);
1398
1399     LOGI("secured port is: %s", portStr);
1400     return atoi(portStr);
1401 }
1402
1403 CAResult_t get_network_type(uint32_t selectedNetwork)
1404 {
1405
1406     uint32_t number = selectedNetwork;
1407
1408     if (!(number & 0xf))
1409     {
1410         return CA_NOT_SUPPORTED;
1411     }
1412     if (number & CA_ADAPTER_IP)
1413     {
1414         g_selectedNwType = CA_ADAPTER_IP;
1415         return CA_STATUS_OK;
1416     }
1417     if (number & CA_ADAPTER_RFCOMM_BTEDR)
1418     {
1419         g_selectedNwType = CA_ADAPTER_RFCOMM_BTEDR;
1420         return CA_STATUS_OK;
1421     }
1422     if (number & CA_ADAPTER_GATT_BTLE)
1423     {
1424         g_selectedNwType = CA_ADAPTER_GATT_BTLE;
1425         return CA_STATUS_OK;
1426     }
1427
1428     return CA_NOT_SUPPORTED;
1429 }
1430
1431 void callback(char *subject, char *receivedData)
1432 {
1433     bool isAttached = false;
1434     JNIEnv* env;
1435
1436     if (!g_responseListenerObject)
1437     {
1438         LOGE("g_responseListenerObject is NULL, cannot have callback");
1439         return;
1440     }
1441
1442     jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
1443     if (JNI_OK != res)
1444     {
1445         LOGI("Could not get JNIEnv pointer");
1446         res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
1447
1448         if (JNI_OK != res)
1449         {
1450             LOGE("AttachCurrentThread has failed");
1451             return;
1452         }
1453         isAttached = true;
1454     }
1455
1456     jclass cls = (*env)->GetObjectClass(env, g_responseListenerObject);
1457     if (!cls)
1458     {
1459         LOGE("could not get class");
1460         goto detach_thread;
1461     }
1462
1463     jmethodID mid = (*env)->GetMethodID(env, cls, "OnResponseReceived",
1464                                         "(Ljava/lang/String;Ljava/lang/String;)V");
1465     if (!mid)
1466     {
1467         LOGE("could not get Method ID");
1468         goto detach_thread;
1469     }
1470
1471     jstring jsubject = (*env)->NewStringUTF(env, (char*) subject);
1472     if (!jsubject)
1473     {
1474         LOGE("NewStringUTF failed");
1475         goto detach_thread;
1476     }
1477
1478     jstring jreceivedData = (*env)->NewStringUTF(env, (char*) receivedData);
1479     if (!jreceivedData)
1480     {
1481         LOGE("NewStringUTF failed");
1482         goto detach_thread;
1483     }
1484
1485     (*env)->CallVoidMethod(env, g_responseListenerObject, mid, jsubject, jreceivedData);
1486
1487 detach_thread :
1488     if (isAttached)
1489     {
1490         (*g_jvm)->DetachCurrentThread(g_jvm);
1491         LOGI("DetachCurrentThread");
1492     }
1493 }
1494
1495 CAResult_t get_remote_address(const char *address)
1496 {
1497     uint32_t len = strlen(address);
1498
1499     g_remoteAddress = (char *)malloc(sizeof (char) * (len + 1));
1500     if (NULL == g_remoteAddress)
1501     {
1502         LOGE("g_remoteAddress Out of memory");
1503         return CA_MEMORY_ALLOC_FAILED;
1504     }
1505
1506     memcpy(g_remoteAddress, address, len + 1);
1507
1508     return CA_STATUS_OK;
1509 }
1510
1511
1512 void parsing_coap_uri(const char* uri, addressSet_t* address, CATransportFlags_t *flags)
1513 {
1514     if (NULL == uri || NULL == address)
1515     {
1516         LOGE("parameter is null");
1517         return;
1518     }
1519
1520     // parse uri
1521     // #1. check prefix
1522     uint8_t startIndex = 0;
1523     if (strncmp(COAPS_PREFIX, uri, COAPS_PREFIX_LEN) == 0)
1524     {
1525         LOGI("uri has '%s' prefix", COAPS_PREFIX);
1526         startIndex = COAPS_PREFIX_LEN;
1527         *flags = CA_SECURE;
1528     }
1529     else if (strncmp(COAP_PREFIX, uri, COAP_PREFIX_LEN) == 0)
1530     {
1531         LOGI("uri has '%s' prefix", COAP_PREFIX);
1532         startIndex = COAP_PREFIX_LEN;
1533         *flags = CA_IPV4;
1534     }
1535
1536     // #2. copy uri for parse
1537     size_t len = strlen(uri) - startIndex;
1538
1539     if (len <= 0)
1540     {
1541         LOGE("uri length is 0!");
1542         return;
1543     }
1544
1545     char *cloneUri = (char *) calloc(len + 1, sizeof(char));
1546     if (NULL == cloneUri)
1547     {
1548         LOGE("Out of memory");
1549         return;
1550     }
1551
1552     OICStrcpy(cloneUri, len+1, &uri[startIndex]);
1553
1554     char *pstr = NULL;
1555     //filter out the resource uri
1556     char *pUrl = strtok_r(cloneUri, "/", &pstr);
1557
1558     if (pUrl)
1559     {
1560         LOGI("pAddress : %s", pUrl);
1561         int res = get_address_set(pUrl, address);
1562         if (res == -1)
1563         {
1564             LOGE("address parse error");
1565
1566             return;
1567         }
1568     }
1569     else
1570     {
1571         LOGE("strtok_r error, could not get the address");
1572     }
1573
1574     return;
1575 }
1576
1577 int get_address_set(const char *pAddress, addressSet_t* outAddress)
1578 {
1579     if (NULL == pAddress || NULL == outAddress)
1580     {
1581         LOGE("parameter is null");
1582         return -1;
1583     }
1584
1585     size_t len = strlen(pAddress);
1586     int isIp = 0;
1587     size_t ipLen = 0;
1588
1589     for (size_t i = 0; i < len; i++)
1590     {
1591         if (pAddress[i] == '.')
1592         {
1593             isIp = 1;
1594         }
1595
1596         // found port number start index
1597         if (isIp && pAddress[i] == ':')
1598         {
1599             ipLen = i;
1600             break;
1601         }
1602     }
1603
1604     if (isIp)
1605     {
1606         if(ipLen && (ipLen <  sizeof(outAddress->ipAddress)))
1607         {
1608             strncpy(outAddress->ipAddress, pAddress, ipLen);
1609             outAddress->ipAddress[ipLen] = '\0';
1610         }
1611         else if (!ipLen && (len <  sizeof(outAddress->ipAddress)))
1612         {
1613             strncpy(outAddress->ipAddress, pAddress, len);
1614             outAddress->ipAddress[len] = '\0';
1615         }
1616         else
1617         {
1618             LOGE("IP Address too long: %d", ipLen==0 ? len : ipLen);
1619             return -1;
1620         }
1621
1622         if (ipLen > 0)
1623         {
1624             outAddress->port = atoi(pAddress + ipLen + 1);
1625         }
1626     }
1627     else
1628     {
1629         strncpy(outAddress->ipAddress, pAddress, len);
1630         outAddress->ipAddress[len] = '\0';
1631     }
1632
1633     return isIp;
1634 }
1635
1636 void delete_global_references(JNIEnv *env, jobject obj)
1637 {
1638     LOGI("delete_global_references");
1639     if (!env || !obj )
1640     {
1641         LOGI("Invalid input parameter");
1642         return;
1643     }
1644
1645     (*env)->DeleteGlobalRef(env, g_responseListenerObject);
1646 }
1647
1648
1649 bool read_file(const char* name, char** bytes, size_t* length)
1650 {
1651     if (NULL == name)
1652     {
1653         LOGE("parameter is null");
1654         return false;
1655     }
1656
1657     FILE* file;
1658     char* buffer;
1659     size_t fileLen;
1660
1661     // Open file
1662     file = fopen(name, "rt");
1663     if (!file)
1664     {
1665         fprintf(stderr, "Unable to open file %s", name);
1666         return false;
1667     }
1668
1669     // Get file length
1670     fseek(file, 0, SEEK_END);
1671     fileLen = ftell(file);
1672     fseek(file, 0, SEEK_SET);
1673
1674     LOGI("file size: %d", fileLen);
1675
1676     // Allocate memory
1677     buffer = calloc(1, sizeof(char) * fileLen + 1);
1678     if (!buffer)
1679     {
1680         fprintf(stderr, "Memory error!");
1681         fclose(file);
1682         return false;
1683     }
1684
1685     // Read file contents into buffer
1686     fread(buffer, fileLen, 1, file);
1687     fclose(file);
1688
1689     LOGI("file bytes: %s", buffer);
1690
1691     *bytes = buffer;
1692     *length = fileLen;
1693
1694     return true;
1695 }
1696
1697 void saveFile(const char *payload, size_t payloadSize)
1698 {
1699     // 1. get day
1700     uint32_t day = gettodaydate();
1701
1702     // 2. get time
1703     time_t current_time;
1704     struct tm * time_info;
1705     char timeString[RECEIVED_FILE_NAME_PREFIX_LENGTH];
1706
1707     time(&current_time);
1708     time_info = localtime(&current_time);
1709
1710     strftime(timeString, sizeof(timeString), "%H%M%S", time_info);
1711
1712     uint32_t path_length = strlen(RECEIVED_FILE_PATH) + RECEIVED_FILE_NAME_LENGTH + 1;
1713     char* path = calloc(1, sizeof(char) * path_length);
1714     if (path != NULL)
1715     {
1716         sprintf(path, RECEIVED_FILE_PATH, day, timeString);
1717         LOGI("received file path: %s", path);
1718
1719         FILE *fp = fopen(path, "wt");
1720         fwrite(payload, 1, payloadSize, fp);
1721         fclose(fp);
1722
1723         callback("File Path: ", path);
1724     }
1725     else
1726     {
1727         LOGE("path Out of memory");
1728     }
1729 }
1730
1731 uint32_t gettodaydate()
1732 {
1733     uint32_t ldate;
1734     time_t clock;
1735     struct tm *date;
1736
1737     clock = time(0);
1738     date = localtime(&clock);
1739     ldate = date->tm_year * 100000;
1740     ldate += (date->tm_mon + 1) * 1000;
1741     ldate += date->tm_mday * 10;
1742     ldate += date->tm_wday;
1743     ldate += 190000000;
1744     ldate /= 10;
1745
1746     return(ldate);
1747 }