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