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