997feeb2f592e592c648f054b8705f07c4075c3f
[platform/upstream/iotivity.git] / resource / csdk / connectivity / samples / android / sample_service / 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
11 #include "org_iotivity_service_RMInterface.h"
12
13 #define  LOG_TAG   "JNI_INTERFACE_SAMPLE"
14 #define  LOGI(...) __android_log_print(ANDROID_LOG_INFO, LOG_TAG, __VA_ARGS__)
15 #define  LOGE(...) __android_log_print(ANDROID_LOG_ERROR, LOG_TAG, __VA_ARGS__)
16
17 /**
18  * @def RS_IDENTITY
19  * @brief
20  */
21 #define IDENTITY     ("1111111111111111")
22 /* @def RS_CLIENT_PSK
23  * @brief
24  */
25 #define RS_CLIENT_PSK   ("AAAAAAAAAAAAAAAA")
26
27 #define PORT_LENGTH 5
28 #define SECURE_DEFAULT_PORT 5684
29 #define RESOURCE_URI_LENGTH 14
30 #define OPTION_INFO_LENGTH 1024
31 #define NETWORK_INFO_LENGTH 1024
32
33 uint16_t g_localSecurePort = SECURE_DEFAULT_PORT;
34
35 void request_handler(const CARemoteEndpoint_t* object, const CARequestInfo_t* requestInfo);
36 void response_handler(const CARemoteEndpoint_t* object, const CAResponseInfo_t* responseInfo);
37 void get_resource_uri(const char *URI, char *resourceURI, uint32_t length);
38 uint32_t get_secure_information(CAPayload_t payLoad);
39 CAResult_t get_network_type(uint32_t selectedNetwork);
40 void callback(char *subject, char *receivedData);
41 CAResult_t get_remote_address(CATransportType_t transportType, CAAddress_t addressInfo);
42
43 CATransportType_t g_selectedNwType = CA_IPV4;
44 static CAToken_t g_lastRequestToken = NULL;
45 static uint8_t g_lastRequestTokenLength;
46
47 static const char SECURE_COAPS_PREFIX[] = "coaps://";
48
49 static const char SECURE_INFO_DATA[]
50                                    = "{\"oc\":[{\"href\":\"%s\",\"prop\":{\"rt\":[\"core.led\"],"
51                                      "\"if\":[\"oic.if.baseline\"],\"obs\":1,\"sec\":1,\"port\":%d}}]}";
52 static const char NORMAL_INFO_DATA[]
53                                    = "{\"oc\":[{\"href\":\"%s\",\"prop\":{\"rt\":[\"core.led\"],"
54                                      "\"if\":[\"oic.if.baseline\"],\"obs\":1}}]}";
55
56
57 static jobject g_responseListenerObject = NULL;
58 static JavaVM *g_jvm;
59
60 static CARemoteEndpoint_t *g_clientEndpoint = NULL;
61 static CAToken_t g_clientToken;
62 static uint8_t g_clientTokenLength = NULL;
63
64 static uint16_t g_clientMsgId;
65 static char *g_remoteAddress = NULL;
66
67 // init
68 JNIEXPORT void JNICALL
69 Java_org_iotivity_service_RMInterface_setNativeResponseListener(JNIEnv *env, jobject obj,
70                                                                 jobject listener)
71 {
72     LOGI("setNativeResponseListener");
73     g_responseListenerObject = (*env)->NewGlobalRef(env, obj);
74 }
75
76 #ifdef __WITH_DTLS__
77 static CADtlsPskCredsBlob_t *pskCredsBlob = NULL;
78
79 void clearDtlsCredentialInfo()
80 {
81     LOGI("clearDtlsCredentialInfo IN");
82     if (pskCredsBlob)
83     {
84         // Initialize sensitive data to zeroes before freeing.
85         if (NULL != pskCredsBlob->creds)
86         {
87             memset(pskCredsBlob->creds, 0, sizeof(OCDtlsPskCreds)*(pskCredsBlob->num));
88             free(pskCredsBlob->creds);
89         }
90
91         memset(pskCredsBlob, 0, sizeof(CADtlsPskCredsBlob_t));
92         free(pskCredsBlob);
93         pskCredsBlob = NULL;
94     }
95     LOGI("clearDtlsCredentialInfo OUT");
96 }
97
98 // Internal API. Invoked by OC stack to retrieve credentials from this module
99 void CAGetDtlsPskCredentials(CADtlsPskCredsBlob_t **credInfo)
100 {
101     LOGI("CAGetDtlsPskCredentials IN");
102     *credInfo = (CADtlsPskCredsBlob_t *) malloc(sizeof(CADtlsPskCredsBlob_t));
103     if (NULL == *credInfo)
104     {
105         LOGE("Failed to allocate credential blob.");
106         return;
107     }
108
109     int16_t credLen = sizeof(OCDtlsPskCreds) * (pskCredsBlob->num);
110     (*credInfo)->creds = (OCDtlsPskCreds *) malloc(credLen);
111     if (NULL == (*credInfo)->creds)
112     {
113         LOGE("Failed to allocate crentials.");
114         free(*credInfo);
115         *credInfo = NULL;
116         return;
117     }
118
119     memcpy((*credInfo)->identity, pskCredsBlob->identity, DTLS_PSK_ID_LEN);
120     (*credInfo)->num = pskCredsBlob->num;
121     memcpy((*credInfo)->creds, pskCredsBlob->creds, credLen);
122
123     LOGI("CAGetDtlsPskCredentials OUT");
124 }
125
126 CAResult_t SetCredentials()
127 {
128     LOGI("SetCredentials IN");
129     pskCredsBlob = (CADtlsPskCredsBlob_t *)malloc(sizeof(CADtlsPskCredsBlob_t));
130     if (NULL == pskCredsBlob)
131     {
132         LOGE("Memory allocation failed!");
133         return CA_MEMORY_ALLOC_FAILED;
134     }
135     memcpy(pskCredsBlob->identity, IDENTITY, DTLS_PSK_ID_LEN);
136
137     pskCredsBlob->num = 1;
138
139     pskCredsBlob->creds = (OCDtlsPskCreds *)malloc(sizeof(OCDtlsPskCreds) *(pskCredsBlob->num));
140     if (NULL == pskCredsBlob->creds)
141     {
142         LOGE("Memory allocation failed!");
143         return CA_MEMORY_ALLOC_FAILED;
144     }
145     memcpy(pskCredsBlob->creds[0].id, IDENTITY, DTLS_PSK_ID_LEN);
146     memcpy(pskCredsBlob->creds[0].psk, RS_CLIENT_PSK, DTLS_PSK_PSK_LEN);
147
148     LOGI("SetCredentials OUT");
149     return CA_STATUS_OK;
150 }
151 #endif
152
153 JNIEXPORT jint JNI_OnLoad(JavaVM *jvm, void *reserved)
154 {
155     LOGI("JNI_OnLoad");
156
157     JNIEnv* env;
158     if (JNI_OK != (*jvm)->GetEnv(jvm, (void**) &env, JNI_VERSION_1_6))
159     {
160         return -1;
161     }
162     g_jvm = jvm; /* cache the JavaVM pointer */
163
164     CANativeJNISetJavaVM(g_jvm);
165
166     return JNI_VERSION_1_6;
167 }
168
169 void JNI_OnUnload(JavaVM *jvm, void *reserved)
170 {
171     LOGI("JNI_OnUnload");
172
173     JNIEnv* env;
174     if (JNI_OK != (*jvm)->GetEnv(jvm, (void**) &env, JNI_VERSION_1_6))
175     {
176         return;
177     }
178     g_jvm = 0;
179     return;
180 }
181
182 JNIEXPORT void JNICALL
183 Java_org_iotivity_service_RMInterface_RMInitialize(JNIEnv *env, jobject obj, jobject context)
184 {
185     LOGI("RMInitialize");
186
187     //Currently set context for Android Platform
188     CANativeJNISetContext(env, context);
189
190     CAResult_t res = CAInitialize();
191
192     if (CA_STATUS_OK != res)
193     {
194         LOGE("Could not Initialize");
195     }
196
197 #ifdef __WITH_DTLS__
198     if (CA_STATUS_OK != SetCredentials())
199     {
200         LOGE("SetCredentials failed");
201         return;
202     }
203
204     res = CARegisterDTLSCredentialsHandler(CAGetDtlsPskCredentials);
205     if(CA_STATUS_OK != res)
206     {
207         LOGE("Set credential handler fail");
208         return;
209     }
210 #endif
211 }
212
213 JNIEXPORT void JNICALL
214 Java_org_iotivity_service_RMInterface_RMTerminate(JNIEnv *env, jobject obj)
215 {
216     LOGI("RMTerminate");
217     CADestroyToken(g_lastRequestToken);
218     CATerminate();
219 }
220
221 JNIEXPORT void JNICALL
222 Java_org_iotivity_service_RMInterface_RMStartListeningServer(JNIEnv *env, jobject obj)
223 {
224     LOGI("RMStartListeningServer");
225
226     if (CA_STATUS_OK != CAStartListeningServer())
227     {
228         LOGE("Could not start Listening server");
229     }
230 }
231
232 JNIEXPORT void JNICALL
233 Java_org_iotivity_service_RMInterface_RMStartDiscoveryServer(JNIEnv *env, jobject obj)
234 {
235     LOGI("RMStartDiscoveryServer");
236
237     if (CA_STATUS_OK != CAStartDiscoveryServer())
238     {
239         LOGE("Could not start discovery server");
240     }
241 }
242
243 JNIEXPORT void JNICALL
244 Java_org_iotivity_service_RMInterface_RMRegisterHandler(JNIEnv *env, jobject obj)
245 {
246     LOGI("RMRegisterHandler");
247
248     CARegisterHandler(request_handler, response_handler);
249 }
250
251 JNIEXPORT void JNICALL
252 Java_org_iotivity_service_RMInterface_RMFindResource(JNIEnv *env, jobject obj, jstring uri)
253 {
254     // create token
255     CAToken_t token = NULL;
256     uint8_t tokenLength = CA_MAX_TOKEN_LEN;
257
258     CAResult_t res = CAGenerateToken(&token, tokenLength);
259     if ((CA_STATUS_OK != res) || (!token))
260     {
261         LOGE("token generate error!!");
262         return;
263     }
264
265     printf("Generated token %s\n", token);
266
267     const char* strUri = (*env)->GetStringUTFChars(env, uri, NULL);
268     LOGI("RMFindResource - %s", strUri);
269
270     res = CAFindResource((const CAURI_t) strUri, token, tokenLength);
271
272     //ReleseStringUTFCharss for strUri
273     (*env)->ReleaseStringUTFChars(env, uri, strUri);
274
275     if (CA_STATUS_OK != res)
276     {
277         LOGE("Could not find resource");
278         //destroy token
279         CADestroyToken(token);
280     }
281     else
282     {
283         LOGI("find resource to %s URI", strUri);
284         CADestroyToken(g_lastRequestToken);
285         g_lastRequestToken = token;
286         g_lastRequestTokenLength = tokenLength;
287     }
288 }
289
290 JNIEXPORT void JNICALL
291 Java_org_iotivity_service_RMInterface_RMSendRequest(JNIEnv *env, jobject obj, jstring uri,
292                                                     jstring payload, jint selectedNetwork,
293                                                     jint isSecured, jint msgType)
294 {
295     LOGI("selectedNetwork - %d", selectedNetwork);
296     CAResult_t res = get_network_type(selectedNetwork);
297     if (CA_STATUS_OK != res)
298     {
299         return;
300     }
301
302     const char* strUri = (*env)->GetStringUTFChars(env, uri, NULL);
303     LOGI("RMSendRequest - %s", strUri);
304
305     //create remote endpoint
306     CARemoteEndpoint_t* endpoint = NULL;
307     res = CACreateRemoteEndpoint((const CAURI_t) strUri, g_selectedNwType, &endpoint);
308
309     //ReleaseStringUTFChars for strUri
310     (*env)->ReleaseStringUTFChars(env, uri, strUri);
311
312     if (CA_STATUS_OK != res)
313     {
314         LOGE("Could not create remote end point");
315         return;
316     }
317
318     CAMessageType_t messageType = msgType;
319
320     // create token
321     CAToken_t token = NULL;
322     uint8_t tokenLength = CA_MAX_TOKEN_LEN;
323
324     res = CAGenerateToken(&token, tokenLength);
325     if ((CA_STATUS_OK != res) || (!token))
326     {
327         LOGE("token generate error!!");
328         // destroy remote endpoint
329         CADestroyRemoteEndpoint(endpoint);
330         return;
331     }
332
333     char resourceURI[RESOURCE_URI_LENGTH + 1] = { 0 };
334
335     get_resource_uri((const CAURI_t) strUri, resourceURI, RESOURCE_URI_LENGTH);
336
337     CAInfo_t requestData = { 0 };
338     requestData.token = token;
339     requestData.tokenLength = tokenLength;
340
341     if (1 == isSecured)
342     {
343         uint32_t length = sizeof(SECURE_INFO_DATA) + strlen(resourceURI);
344         requestData.payload = (CAPayload_t) malloc(length);
345         if (NULL == requestData.payload)
346         {
347             LOGE("Memory allocation failed!");
348             // destroy token
349             CADestroyToken(token);
350             // destroy remote endpoint
351             CADestroyRemoteEndpoint(endpoint);
352             return;
353         }
354         snprintf(requestData.payload, length, SECURE_INFO_DATA, resourceURI, g_localSecurePort);
355     }
356     else
357     {
358         uint32_t length = sizeof(NORMAL_INFO_DATA) + strlen(resourceURI);
359         requestData.payload = (CAPayload_t) malloc(length);
360         if (NULL == requestData.payload)
361         {
362             LOGE("Memory allocation failed!");
363             // destroy token
364             CADestroyToken(token);
365             // destroy remote endpoint
366             CADestroyRemoteEndpoint(endpoint);
367             return;
368         }
369         snprintf(requestData.payload, length, NORMAL_INFO_DATA, resourceURI);
370     }
371
372     requestData.type = messageType;
373
374     CARequestInfo_t requestInfo = { 0 };
375     requestInfo.method = CA_GET;
376     requestInfo.info = requestData;
377
378     // send request
379     if (CA_STATUS_OK != CASendRequest(endpoint, &requestInfo))
380     {
381         LOGE("Could not send request");
382     }
383
384     // destroy token
385     CADestroyToken(token);
386
387     // destroy remote endpoint
388     CADestroyRemoteEndpoint(endpoint);
389
390     free(requestData.payload);
391 }
392
393 JNIEXPORT void JNICALL
394 Java_org_iotivity_service_RMInterface_RMSendReqestToAll(JNIEnv *env, jobject obj, jstring uri,
395                                                         jint selectedNetwork)
396 {
397     LOGI("selectedNetwork - %d", selectedNetwork);
398     CAResult_t res = get_network_type(selectedNetwork);
399     if (CA_STATUS_OK != res)
400     {
401         return;
402     }
403
404     const char* strUri = (*env)->GetStringUTFChars(env, uri, NULL);
405     LOGI("RMSendReqestToAll - %s", strUri);
406
407     // create remote endpoint
408     CARemoteEndpoint_t *endpoint = NULL;
409     res = CACreateRemoteEndpoint((const CAURI_t) strUri, g_selectedNwType, &endpoint);
410
411     //ReleaseStringUTFChars for strUri
412     (*env)->ReleaseStringUTFChars(env, uri, strUri);
413
414     if (CA_STATUS_OK != res)
415     {
416         LOGE("create remote endpoint error, error code: %d", res);
417         return;
418     }
419
420     CAGroupEndpoint_t *group = (CAGroupEndpoint_t *) malloc(sizeof(CAGroupEndpoint_t));
421     if (NULL == group)
422     {
423         LOGE("Memory allocation failed!");
424         CADestroyRemoteEndpoint(endpoint);
425         return;
426     }
427     group->transportType = endpoint->transportType;
428     group->resourceUri = endpoint->resourceUri;
429
430     // create token
431     CAToken_t token = NULL;
432     uint8_t tokenLength = CA_MAX_TOKEN_LEN;
433
434     res = CAGenerateToken(&token, tokenLength);
435     if ((CA_STATUS_OK != res) || (!token))
436     {
437         LOGE("token generate error!!");
438         // destroy remote endpoint
439         CADestroyRemoteEndpoint(endpoint);
440         free(group);
441         return;
442     }
443
444     LOGI("generated token %s", token);
445
446     CAInfo_t requestData = { 0 };
447     requestData.token = token;
448     requestData.tokenLength = tokenLength;
449     requestData.payload = "Temp Json Payload";
450     requestData.type = CA_MSG_NONCONFIRM;
451
452     CARequestInfo_t requestInfo = { 0 };
453     requestInfo.method = CA_GET;
454     requestInfo.info = requestData;
455
456     // send request to all
457     res = CASendRequestToAll(group, &requestInfo);
458     if (CA_STATUS_OK != res)
459     {
460         LOGE("Could not send request to all");
461         //destroy token
462         CADestroyToken(token);
463     }
464     else
465     {
466         CADestroyToken(g_lastRequestToken);
467         g_lastRequestToken = token;
468         g_lastRequestTokenLength = tokenLength;
469     }
470
471     // destroy remote endpoint
472     CADestroyRemoteEndpoint(endpoint);
473     free(group);
474
475 }
476
477 JNIEXPORT void JNICALL
478 Java_org_iotivity_service_RMInterface_RMSendResponse(JNIEnv *env, jobject obj,
479                                                      jint selectedNetwork,
480                                                      jint isSecured, jint msgType,
481                                                      jint responseValue)
482 {
483     LOGI("RMSendResponse");
484
485     LOGI("selectedNetwork - %d", selectedNetwork);
486
487     CAResult_t res = get_network_type(selectedNetwork);
488     if (CA_STATUS_OK != res)
489     {
490         LOGE("Not supported network type");
491         return;
492     }
493
494     if (NULL == g_clientEndpoint)
495     {
496         LOGE("No Request received");
497         return;
498     }
499
500     CAMessageType_t messageType = msgType;
501
502     CAInfo_t responseData = { 0 };
503     responseData.type = messageType;
504     responseData.messageId = g_clientMsgId;
505
506     CAResponseInfo_t responseInfo = { 0 };
507
508     if (msgType != CA_MSG_RESET)
509     {
510         responseData.token = g_clientToken;
511         responseData.tokenLength = g_clientTokenLength;
512         responseInfo.result = responseValue;
513
514         if (1 == isSecured)
515         {
516             uint32_t length = strlen(SECURE_INFO_DATA) + strlen(g_clientEndpoint->resourceUri) + 1;
517             responseData.payload = (CAPayload_t) malloc(length);
518             sprintf(responseData.payload, SECURE_INFO_DATA, g_clientEndpoint->resourceUri,
519                     g_localSecurePort);
520         }
521         else
522         {
523             uint32_t length = strlen(NORMAL_INFO_DATA) + strlen(g_clientEndpoint->resourceUri) + 1;
524             responseData.payload = (CAPayload_t) malloc(length);
525             sprintf(responseData.payload, NORMAL_INFO_DATA, g_clientEndpoint->resourceUri);
526         }
527     }
528     //msgType is RESET
529     else
530     {
531         responseInfo.result = CA_EMPTY;
532     }
533
534     responseInfo.info = responseData;
535
536     // send response
537     res = CASendResponse(g_clientEndpoint, &responseInfo);
538     if (CA_STATUS_OK != res)
539     {
540         LOGE("Could not send response");
541     }
542
543     // destroy token
544     CADestroyToken(g_clientToken);
545     g_clientToken = NULL;
546     g_clientTokenLength = 0;
547
548     // destroy remote endpoint
549     CADestroyRemoteEndpoint(g_clientEndpoint);
550     g_clientEndpoint = NULL;
551 }
552
553 JNIEXPORT void JNICALL
554 Java_org_iotivity_service_RMInterface_RMAdvertiseResource(JNIEnv *env, jobject obj, jstring uri)
555 {
556     LOGI("RMAdvertiseResource");
557
558     uint32_t optionNum = 2;
559
560     CAHeaderOption_t *headerOpt = (CAHeaderOption_t*) calloc(1,
561                                                              sizeof(CAHeaderOption_t) * optionNum);
562     if (NULL == headerOpt)
563     {
564         LOGE("Memory allocation failed!");
565         return;
566     }
567
568     char* tmpOptionData1 = "Hello";
569     headerOpt[0].optionID = 3000;
570     memcpy(headerOpt[0].optionData, tmpOptionData1, strlen(tmpOptionData1));
571     headerOpt[0].optionLength = (uint16_t) strlen(tmpOptionData1);
572
573     char* tmpOptionData2 = "World";
574     headerOpt[1].optionID = 3001;
575     memcpy(headerOpt[1].optionData, tmpOptionData2, strlen(tmpOptionData2));
576     headerOpt[1].optionLength = (uint16_t) strlen(tmpOptionData2);
577
578     // create token
579     CAToken_t token = NULL;
580     uint8_t tokenLength = CA_MAX_TOKEN_LEN;
581
582     CAResult_t res = CAGenerateToken(&token, tokenLength);
583     if ((CA_STATUS_OK != res) || (!token))
584     {
585         LOGE("token generate error!");
586         free(headerOpt);
587         return;
588     }
589
590     const char* strUri = (*env)->GetStringUTFChars(env, uri, NULL);
591
592     res = CAAdvertiseResource((const CAURI_t) strUri, token, tokenLength,
593                               headerOpt, (uint8_t) optionNum);
594     if (CA_STATUS_OK != res)
595     {
596         LOGE("Could not start advertise resource");
597         CADestroyToken(token);
598     }
599     else
600     {
601         CADestroyToken(g_lastRequestToken);
602         g_lastRequestToken = token;
603         g_lastRequestTokenLength = tokenLength;
604     }
605
606     free(headerOpt);
607
608     //ReleaseStringUTFChars for strUri
609     (*env)->ReleaseStringUTFChars(env, uri, strUri);
610 }
611
612 JNIEXPORT void JNICALL
613 Java_org_iotivity_service_RMInterface_RMSendNotification(JNIEnv *env, jobject obj, jstring uri,
614                                                          jstring payload, jint selectedNetwork,
615                                                          jint isSecured, jint msgType,
616                                                          jint responseValue)
617 {
618     LOGI("selectedNetwork - %d", selectedNetwork);
619
620     CAResult_t res = get_network_type(selectedNetwork);
621     if (CA_STATUS_OK != res)
622     {
623         LOGE("Not supported network type");
624         return;
625     }
626
627     const char* strUri = (*env)->GetStringUTFChars(env, uri, NULL);
628     LOGI("RMSendNotification - %s", strUri);
629
630     //create remote endpoint
631     CARemoteEndpoint_t* endpoint = NULL;
632     if (CA_STATUS_OK != CACreateRemoteEndpoint((const CAURI_t) strUri,
633                                                g_selectedNwType, &endpoint))
634     {
635         LOGE("Could not create remote end point");
636         return;
637
638         //ReleaseStringUTFChars for strUri
639         (*env)->ReleaseStringUTFChars(env, uri, strUri);
640     }
641
642     char resourceURI[RESOURCE_URI_LENGTH + 1] = { 0 };
643     get_resource_uri((const CAURI_t) strUri, resourceURI, RESOURCE_URI_LENGTH);
644
645     //ReleaseStringUTFChars for strUri
646     (*env)->ReleaseStringUTFChars(env, uri, strUri);
647
648     CAMessageType_t messageType = msgType;
649
650     // create token
651     CAToken_t token = NULL;
652     uint8_t tokenLength = CA_MAX_TOKEN_LEN;
653
654     res = CAGenerateToken(&token, tokenLength);
655     if ((CA_STATUS_OK != res) || (!token))
656     {
657         LOGE("token generate error!");
658         CADestroyRemoteEndpoint(endpoint);
659         return;
660     }
661
662     CAInfo_t responseData = { 0 };
663     responseData.token = token;
664     responseData.tokenLength = tokenLength;
665
666     if (1 == isSecured)
667     {
668         uint32_t length = sizeof(SECURE_INFO_DATA) + strlen(resourceURI);
669         responseData.payload = (CAPayload_t) malloc(length);
670         if (NULL == responseData.payload)
671         {
672             LOGE("Memory allocation failed!");
673             // destroy token
674             CADestroyToken(token);
675             // destroy remote endpoint
676             CADestroyRemoteEndpoint(endpoint);
677             return;
678         }
679         snprintf(responseData.payload, length, SECURE_INFO_DATA, resourceURI, g_localSecurePort);
680     }
681     else
682     {
683         uint32_t length = sizeof(NORMAL_INFO_DATA) + strlen(resourceURI);
684         responseData.payload = (CAPayload_t) malloc(length);
685         if (NULL == responseData.payload)
686         {
687             LOGE("Memory allocation failed!");
688             // destroy token
689             CADestroyToken(token);
690             // destroy remote endpoint
691             CADestroyRemoteEndpoint(endpoint);
692             return;
693         }
694         snprintf(responseData.payload, length, NORMAL_INFO_DATA, resourceURI);
695     }
696
697     responseData.type = messageType;
698
699     CAResponseInfo_t responseInfo = { 0 };
700     responseInfo.result = responseValue;
701     responseInfo.info = responseData;
702
703     // send notification
704     if (CA_STATUS_OK != CASendNotification(endpoint, &responseInfo))
705     {
706         LOGE("Could not send notification");
707     }
708
709     LOGI("Send Notification");
710
711     // destroy token
712     CADestroyToken(token);
713
714     // destroy remote endpoint
715     CADestroyRemoteEndpoint(endpoint);
716
717     free(responseData.payload);
718 }
719
720 JNIEXPORT void JNICALL
721 Java_org_iotivity_service_RMInterface_RMSelectNetwork(JNIEnv *env, jobject obj, jint networkType)
722 {
723     LOGI("RMSelectNetwork Type : %d", networkType);
724
725     if (CA_STATUS_OK != CASelectNetwork(networkType))
726     {
727         LOGE("Could not select network");
728     }
729 }
730
731 JNIEXPORT void JNICALL
732 Java_org_iotivity_service_RMInterface_RMUnSelectNetwork(JNIEnv *env, jobject obj, jint networkType)
733 {
734     LOGI("RMUnSelectNetwork Type : %d", networkType);
735
736     if (CA_STATUS_OK != CAUnSelectNetwork(networkType))
737     {
738         LOGE("Could not unselect network");
739     }
740 }
741
742 JNIEXPORT void JNICALL
743 Java_org_iotivity_service_RMInterface_RMGetNetworkInfomation(JNIEnv *env, jobject obj)
744 {
745     LOGI("RMGetNetworkInfomation");
746
747     CALocalConnectivity_t *tempInfo = NULL;
748     uint32_t tempSize = 0;
749
750     CAResult_t res = CAGetNetworkInformation(&tempInfo, &tempSize);
751     if (CA_STATUS_OK != res)
752     {
753         LOGE("Could not start get network information");
754         OICFree(tempInfo);
755         return;
756     }
757
758     LOGI("################## Network Information #######################");
759     callback("######## Network Information", "#######");
760     LOGI("Network info total size is %d", tempSize);
761
762     uint32_t index;
763     for (index = 0; index < tempSize; index++)
764     {
765         res = get_remote_address(tempInfo[index].type, tempInfo[index].addressInfo);
766         if (CA_STATUS_OK != res)
767         {
768             OICFree(tempInfo);
769             return;
770         }
771         if (NULL != g_responseListenerObject)
772         {
773             char networkInfo[NETWORK_INFO_LENGTH];
774             LOGI("Type: %d", tempInfo[index].type);
775             sprintf(networkInfo, "%d",tempInfo[index].type);
776             callback("Type :", networkInfo);
777             if (CA_IPV4 == tempInfo[index].type)
778             {
779                 LOGI("Port: %d", tempInfo[index].addressInfo.IP.port);
780                 sprintf(networkInfo, "%d",tempInfo[index].addressInfo.IP.port);
781                 callback("Port: ", networkInfo);
782             }
783             LOGI("Secured: %d", tempInfo[index].isSecured);
784             LOGI("Address: %s", g_remoteAddress);
785             callback("Address: ", g_remoteAddress);
786             free(g_remoteAddress);
787         }
788         if (true == tempInfo[index].isSecured)
789         {
790             g_localSecurePort = tempInfo[index].addressInfo.IP.port;
791         }
792     }
793
794     // free
795     OICFree(tempInfo);
796
797     LOGI("##############################################################");
798 }
799
800 JNIEXPORT void JNICALL
801 Java_org_iotivity_service_RMInterface_RMHandleRequestResponse(JNIEnv *env, jobject obj)
802 {
803     LOGI("RMHandleRequestResponse");
804
805     if (CA_STATUS_OK != CAHandleRequestResponse())
806     {
807         LOGE("Could not handle request and response");
808     }
809 }
810
811 void request_handler(const CARemoteEndpoint_t* object, const CARequestInfo_t* requestInfo)
812 {
813
814     if (!object)
815     {
816         LOGE("Remote endpoint is NULL!");
817         return;
818     }
819
820     if (!requestInfo)
821     {
822         LOGE("Request info is NULL!");
823         return;
824     }
825
826     if ((NULL != g_lastRequestToken) && (NULL != requestInfo->info.token) &&
827             (strncmp(g_lastRequestToken, requestInfo->info.token,
828                      requestInfo->info.tokenLength) == 0))
829     {
830         LOGI("token is same. received request of it's own. skip.. ");
831         return;
832     }
833
834     CAResult_t res = get_remote_address(object->transportType, object->addressInfo);
835     if (CA_STATUS_OK != res)
836     {
837         return;
838     }
839
840     LOGI("##########received request from remote device #############");
841     if (object->resourceUri)
842     {
843         LOGI("Uri: %s", object->resourceUri);
844     }
845     LOGI("Remote Address: %s", g_remoteAddress);
846     LOGI("Data: %s", requestInfo->info.payload);
847     LOGI("Token: %s", requestInfo->info.token);
848     LOGI("Code: %d", requestInfo->method);
849     LOGI("MessageType: %d", requestInfo->info.type);
850
851     if (NULL != g_responseListenerObject)
852     {
853         callback("received request from remote device", "#######");
854         char *cloneUri = NULL;
855         uint32_t len = 0;
856
857         if (NULL != object->resourceUri)
858         {
859             len = strlen(object->resourceUri);
860             cloneUri = (char *) malloc(sizeof(char) * (len + 1));
861
862             if (NULL == cloneUri)
863             {
864                 LOGE("cloneUri Out of memory");
865                 free(g_remoteAddress);
866                 return;
867             }
868
869             memcpy(cloneUri, object->resourceUri, len + 1);
870             callback("Uri: ", cloneUri);
871         }
872
873         len = strlen(g_remoteAddress);
874         char *cloneRemoteAddress = (char *) malloc(sizeof(char) * (len + 1));
875
876         if (NULL == cloneRemoteAddress)
877         {
878             LOGE("cloneRemoteAddress Out of memory");
879             free(g_remoteAddress);
880             free(cloneUri);
881             return;
882         }
883
884         memcpy(cloneRemoteAddress, g_remoteAddress, len + 1);
885
886         callback("Remote Address: ", cloneRemoteAddress);
887         free(cloneRemoteAddress);
888         free(g_remoteAddress);
889
890         //clone g_clientEndpoint
891         g_clientEndpoint = (CARemoteEndpoint_t *) malloc(sizeof(CARemoteEndpoint_t));
892         if (NULL == g_clientEndpoint)
893         {
894             LOGE("g_clientEndpoint Out of memory");
895             free(cloneUri);
896             return;
897         }
898         memcpy(g_clientEndpoint, object, sizeof(CARemoteEndpoint_t));
899
900         if (NULL != cloneUri)
901         {
902             len = strlen(cloneUri);
903             g_clientEndpoint->resourceUri = (char *) malloc(sizeof(char) * (len + 1));
904             if (NULL == g_clientEndpoint)
905             {
906                 LOGE("g_clientEndpoint->resourceUri Out of memory");
907                 free(g_clientEndpoint);
908                 free(cloneUri);
909                 return;
910             }
911             memcpy(g_clientEndpoint->resourceUri, cloneUri, len + 1);
912             free(cloneUri);
913         }
914         //clone g_clientToken
915         len = requestInfo->info.tokenLength;
916
917         g_clientToken = (char *) malloc(sizeof(char) * len);
918         if (NULL == g_clientToken)
919         {
920             LOGE("g_clientToken Out of memory");
921             free(g_clientEndpoint->resourceUri);
922             free(g_clientEndpoint);
923             return;
924         }
925
926         if (NULL != requestInfo->info.token)
927         {
928             memcpy(g_clientToken, requestInfo->info.token, len);
929             g_clientTokenLength = len;
930
931         }
932
933         //clone g_clientMsgId
934         g_clientMsgId = requestInfo->info.messageId;
935
936         if (NULL != requestInfo->info.payload)
937         {
938             len = strlen(requestInfo->info.payload);
939             char *clonePayload = (char *) malloc(sizeof(char) * (len + 1));
940
941             if (NULL == clonePayload)
942             {
943                 LOGE("clonePayload Out of memory");
944                 free(g_clientEndpoint->resourceUri);
945                 free(g_clientEndpoint);
946                 return;
947             }
948
949             memcpy(clonePayload, requestInfo->info.payload, len + 1);
950
951             callback("Data: ", clonePayload);
952             free(clonePayload);
953         }
954     }
955
956     if (requestInfo->info.options)
957     {
958         uint32_t len = requestInfo->info.numOptions;
959         uint32_t i;
960
961         LOGI("Option count: %d", requestInfo->info.numOptions);
962
963         for (i = 0; i < len; i++)
964         {
965             LOGI("Option %d", i + 1);
966             LOGI("ID : %d", requestInfo->info.options[i].optionID);
967             LOGI("Data[%d]: %s", requestInfo->info.options[i].optionLength,
968                  requestInfo->info.options[i].optionData);
969
970             if (NULL != g_responseListenerObject)
971             {
972                 char optionInfo[OPTION_INFO_LENGTH] = { 0, };
973                 sprintf(optionInfo, "Num[%d] - ID : %d, Option Length : %d", i + 1,
974                         requestInfo->info.options[i].optionID,
975                         requestInfo->info.options[i].optionLength);
976
977                 callback("Option info: ", optionInfo);
978
979                 if (0 != requestInfo->info.options[i].optionData)
980                 {
981                     uint32_t optionDataLen = strlen(requestInfo->info.options[i].optionData);
982                     char *cloneOptionData = (char *) malloc(sizeof(char) * (optionDataLen + 1));
983
984                     if (NULL == cloneOptionData)
985                     {
986                         LOGE("cloneOptionData Out of memory");
987                         free(g_clientEndpoint->resourceUri);
988                         free(g_clientEndpoint);
989                         return;
990                     }
991
992                     memcpy(cloneOptionData, requestInfo->info.options[i].optionData,
993                            optionDataLen + 1);
994
995                     callback("Option Data: ", cloneOptionData);
996                     free(cloneOptionData);
997                 }
998             }
999         }
1000     }
1001     LOGI("############################################################");
1002
1003     //Check if this has secure communication information
1004     if (requestInfo->info.payload && CA_IPV4 == object->transportType)
1005     {
1006         uint32_t securePort = get_secure_information(requestInfo->info.payload);
1007         if (0 < securePort) //Set the remote endpoint secure details and send response
1008         {
1009             LOGI("This is secure resource...");
1010             char *uri = NULL;
1011             uint32_t length = 0;
1012
1013             length = sizeof(SECURE_COAPS_PREFIX) - 1; //length of "coaps://"
1014             // length of "ipaddress:port"
1015             length += strlen(object->addressInfo.IP.ipAddress) + PORT_LENGTH;
1016             length += strlen(object->resourceUri) + 1;
1017
1018             uri = calloc(1, sizeof(char) * length);
1019             if (!uri)
1020             {
1021                 LOGE("Failed to create new uri");
1022                 free(uri);
1023                 return;
1024             }
1025             sprintf(uri, "%s%s:%d/%s", SECURE_COAPS_PREFIX, object->addressInfo.IP.ipAddress,
1026                     securePort, object->resourceUri);
1027
1028             CARemoteEndpoint_t *endpoint = NULL;
1029             if (CA_STATUS_OK != CACreateRemoteEndpoint(uri, object->transportType, &endpoint))
1030             {
1031                 LOGE("Failed to create duplicate of remote endpoint!");
1032                 free(uri);
1033                 return;
1034             }
1035             endpoint->isSecured = true;
1036             object = endpoint;
1037
1038             free(uri);
1039         }
1040     }
1041 }
1042
1043 void response_handler(const CARemoteEndpoint_t* object, const CAResponseInfo_t* responseInfo)
1044 {
1045
1046     CAResult_t res = get_remote_address(object->transportType, object->addressInfo);
1047     if (CA_STATUS_OK != res)
1048     {
1049         return;
1050     }
1051
1052     LOGI("##########Received response from remote device #############");
1053     LOGI("Uri: %s", object->resourceUri);
1054     LOGI("Remote Address: %s", g_remoteAddress);
1055     LOGI("response result: %d", responseInfo->result);
1056     LOGI("Data: %s", responseInfo->info.payload);
1057     LOGI("Token: %s", responseInfo->info.token);
1058     LOGI("MessageType: %d", responseInfo->info.type);
1059
1060     if (NULL != g_responseListenerObject)
1061     {
1062         uint32_t len = 0;
1063
1064         if (NULL != object->resourceUri)
1065         {
1066             len = strlen(object->resourceUri);
1067             char *cloneUri = (char *) malloc(sizeof(char) * (len + 1));
1068
1069             if (NULL == cloneUri)
1070             {
1071                 LOGE("cloneUri Out of memory");
1072                 free(g_remoteAddress);
1073                 return;
1074             }
1075
1076             memcpy(cloneUri, object->resourceUri, len + 1);
1077
1078             callback("Uri: ", cloneUri);
1079             free(cloneUri);
1080         }
1081
1082         len = strlen(g_remoteAddress);
1083         char *cloneRemoteAddress = (char *) malloc(sizeof(char) * (len + 1));
1084
1085         if (NULL == cloneRemoteAddress)
1086         {
1087             LOGE("cloneRemoteAddress Out of memory");
1088             free(g_remoteAddress);
1089             return;
1090         }
1091
1092         memcpy(cloneRemoteAddress, g_remoteAddress, len + 1);
1093
1094         callback("Remote Address: ", cloneRemoteAddress);
1095         free(cloneRemoteAddress);
1096         free(g_remoteAddress);
1097
1098         if (NULL != responseInfo->info.payload)
1099         {
1100             len = strlen(responseInfo->info.payload);
1101             char *clonePayload = (char *) malloc(sizeof(char) * (len + 1));
1102
1103             if (NULL == clonePayload)
1104             {
1105                 LOGE("clonePayload Out of memory");
1106                 return;
1107             }
1108
1109             memcpy(clonePayload, responseInfo->info.payload, len + 1);
1110
1111             callback("Data: ", clonePayload);
1112             free(clonePayload);
1113         }
1114     }
1115
1116     if (responseInfo->info.options)
1117     {
1118         uint32_t len = responseInfo->info.numOptions;
1119         uint32_t i;
1120         for (i = 0; i < len; i++)
1121         {
1122             LOGI("Option %d", i + 1);
1123             LOGI("ID : %d", responseInfo->info.options[i].optionID);
1124             LOGI("Data[%d]: %s", responseInfo->info.options[i].optionLength,
1125                  responseInfo->info.options[i].optionData);
1126
1127             if (NULL != g_responseListenerObject)
1128             {
1129                 char optionInfo[OPTION_INFO_LENGTH] = { 0, };
1130                 sprintf(optionInfo, "Num[%d] - ID : %d, Option Length : %d", i + 1,
1131                         responseInfo->info.options[i].optionID,
1132                         responseInfo->info.options[i].optionLength);
1133
1134                 callback("Option info: ", optionInfo);
1135
1136                 if (0 != responseInfo->info.options[i].optionData)
1137                 {
1138                     uint32_t optionDataLen = strlen(responseInfo->info.options[i].optionData);
1139                     char *cloneOptionData = (char *) malloc(sizeof(char) * (optionDataLen + 1));
1140
1141                     if (NULL == cloneOptionData)
1142                     {
1143                         LOGE("cloneOptionData Out of memory");
1144                         return;
1145                     }
1146                     memcpy(cloneOptionData, responseInfo->info.options[i].optionData,
1147                            optionDataLen + 1);
1148                     callback("Option Data: ", cloneOptionData);
1149                     free(cloneOptionData);
1150                 }
1151             }
1152         }
1153     }
1154     LOGI("############################################################");
1155
1156     //Check if this has secure communication information
1157     if (responseInfo->info.payload && CA_IPV4 == object->transportType)
1158     {
1159         uint32_t securePort = get_secure_information(responseInfo->info.payload);
1160         if (0 < securePort) //Set the remote endpoint secure details and send response
1161         {
1162             LOGI("This is secure resource...");
1163         }
1164     }
1165 }
1166
1167 void get_resource_uri(const char *URI, char *resourceURI, uint32_t length)
1168 {
1169     const char *startPos = URI;
1170     const char *temp = NULL;
1171     if (NULL != (temp = strstr(URI, "://")))
1172     {
1173         startPos = strchr(temp + 3, '/');
1174         if (!startPos)
1175         {
1176             LOGE("Resource URI is missing");
1177             return;
1178         }
1179     }
1180
1181     const char *endPos = strchr(startPos, '?');
1182     if (!endPos)
1183     {
1184         endPos = URI + strlen(URI);
1185     }
1186     --endPos;
1187
1188     if (endPos - startPos <= length)
1189     {
1190         memcpy(resourceURI, startPos + 1, endPos - startPos);
1191     }
1192
1193     LOGI("URI: %s, ResourceURI: %s", URI, resourceURI);
1194 }
1195
1196 uint32_t get_secure_information(CAPayload_t payLoad)
1197 {
1198     LOGI("entering get_secure_information");
1199
1200     if (!payLoad)
1201     {
1202         LOGE("Payload is NULL");
1203         return -1;
1204     }
1205
1206     const char *subString = NULL;
1207     if (NULL == (subString = strstr(payLoad, "\"sec\":1")))
1208     {
1209         LOGE("This is not secure resource");
1210         return -1;
1211     }
1212
1213     if (NULL == (subString = strstr(payLoad, "\"port\":")))
1214     {
1215         LOGE("This secure resource does not have port information");
1216         return -1;
1217     }
1218
1219     const char *startPos = strstr(subString, ":");
1220     if (!startPos)
1221     {
1222         LOGE("Parsing failed !");
1223         return -1;
1224     }
1225
1226     const char *endPos = strstr(startPos, "}");
1227     if (!endPos)
1228     {
1229         LOGE("Parsing failed !");
1230         return -1;
1231     }
1232
1233     char portStr[6] = { 0 };
1234     memcpy(portStr, startPos + 1, (endPos - 1) - startPos);
1235
1236     LOGI("secured port is: %s", portStr);
1237     return atoi(portStr);
1238 }
1239
1240 CAResult_t get_network_type(uint32_t selectedNetwork)
1241 {
1242
1243     uint32_t number = selectedNetwork;
1244
1245     if (!(number & 0xf))
1246     {
1247         return CA_NOT_SUPPORTED;
1248     }
1249     if (number & CA_IPV4)
1250     {
1251         g_selectedNwType = CA_IPV4;
1252         return CA_STATUS_OK;
1253     }
1254     if (number & CA_EDR)
1255     {
1256         g_selectedNwType = CA_EDR;
1257         return CA_STATUS_OK;
1258     }
1259     if (number & CA_LE)
1260     {
1261         g_selectedNwType = CA_LE;
1262         return CA_STATUS_OK;
1263     }
1264
1265     return CA_NOT_SUPPORTED;
1266 }
1267
1268 void callback(char *subject, char *receivedData)
1269 {
1270     JNIEnv* env = NULL;
1271     uint32_t status = (*g_jvm)->GetEnv(g_jvm, (void **) &env, JNI_VERSION_1_6);
1272     uint32_t res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
1273
1274     jclass cls = (*env)->GetObjectClass(env, g_responseListenerObject);
1275     jmethodID mid = (*env)->GetMethodID(env, cls, "OnResponseReceived",
1276                                         "(Ljava/lang/String;Ljava/lang/String;)V");
1277
1278     jstring jsubject = (*env)->NewStringUTF(env, (char*) subject);
1279     jstring jreceivedData = (*env)->NewStringUTF(env, (char*) receivedData);
1280     (*env)->CallVoidMethod(env, g_responseListenerObject, mid, jsubject, jreceivedData);
1281
1282 }
1283
1284 CAResult_t get_remote_address(CATransportType_t transportType, CAAddress_t addressInfo)
1285 {
1286
1287     uint32_t len = 0;
1288     if (CA_IPV4 == transportType)
1289     {
1290         len = strlen(addressInfo.IP.ipAddress);
1291         g_remoteAddress = (char *) malloc(sizeof(char) * (len + 1));
1292
1293         if (NULL == g_remoteAddress)
1294         {
1295             LOGE("g_remoteAddress Out of memory");
1296             return CA_MEMORY_ALLOC_FAILED;
1297         }
1298
1299         memcpy(g_remoteAddress, addressInfo.IP.ipAddress, len + 1);
1300     }
1301
1302     else if (CA_EDR == transportType)
1303     {
1304         len = strlen(addressInfo.BT.btMacAddress);
1305         g_remoteAddress = (char *) malloc(sizeof(char) * (len + 1));
1306
1307         if (NULL == g_remoteAddress)
1308         {
1309             LOGE("g_remoteAddress Out of memory");
1310             return CA_MEMORY_ALLOC_FAILED;
1311         }
1312
1313         memcpy(g_remoteAddress, addressInfo.BT.btMacAddress, len + 1);
1314     }
1315
1316     else if (CA_LE == transportType)
1317     {
1318         len = strlen(addressInfo.LE.leMacAddress);
1319         g_remoteAddress = (char *) malloc(sizeof(char) * (len + 1));
1320
1321         if (NULL == g_remoteAddress)
1322         {
1323             LOGE("g_remoteAddress Out of memory");
1324             return CA_MEMORY_ALLOC_FAILED;
1325         }
1326
1327         memcpy(g_remoteAddress, addressInfo.LE.leMacAddress, len + 1);
1328     }
1329
1330     return CA_STATUS_OK;
1331 }