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