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