2 #include <android/log.h>
8 #include <../../../../api/cainterface.h>
9 #include <../../../../api/cacommon.h>
10 #include "com_iotivity_service_RMInterface.h"
12 #define LOG_TAG "JNI_INTERFACE_SAMPLE"
13 #define LOGI(...) __android_log_print(ANDROID_LOG_INFO, LOG_TAG, __VA_ARGS__)
14 #define LOGE(...) __android_log_print(ANDROID_LOG_ERROR, LOG_TAG, __VA_ARGS__)
20 #define IDENTITY ("1111111111111111")
24 #define RS_CLIENT_PSK ("AAAAAAAAAAAAAAAA")
27 CABool_t gLocalUnicastPort;
28 CABool_t gLocalSecurePort;
30 void request_handler(const CARemoteEndpoint_t* object, const CARequestInfo_t* requestInfo);
31 void response_handler(const CARemoteEndpoint_t* object, const CAResponseInfo_t* responseInfo);
32 void send_response(const CARemoteEndpoint_t* endpoint, CAToken_t request_token);
33 void get_resource_uri(char *URI, char *resourceURI, int length);
34 int get_secure_information(CAPayload_t payLoad);
35 CAResult_t get_network_type(int selectedNetwork);
36 void callback(char *subject, char *receicedData);
38 CAConnectivityType_t gSelectedNwType;
39 static CAToken_t gLastRequestToken = NULL;
40 static const char *gSecureInfoData = "{\"oc\":[{\"href\":\"%s\",\"prop\":{\"rt\":[\"core.led\"],"
41 "\"if\":[\"oc.mi.def\"],\"obs\":1,\"sec\":1,\"port\":%d}}]}";
42 static const char *gNormalInfoData = "{\"oc\":[{\"href\":\"%s\",\"prop\":{\"rt\":[\"core.led\"],"
43 "\"if\":[\"oc.mi.def\"],\"obs\":1}}]}";
45 static jobject gResponseListenerObject = NULL;
49 JNIEXPORT void JNICALL Java_com_iotivity_service_RMInterface_setNativeResponseListener(JNIEnv *env, jobject obj, jobject listener){
50 LOGI("setNativeResponseListener");
51 gResponseListenerObject = (*env)->NewGlobalRef(env, obj);
55 static OCDtlsPskCredsBlob *pskCredsBlob = NULL;
57 void clearDtlsCredentialInfo()
59 printf("clearDtlsCredentialInfo IN\n");
62 // Initialize sensitive data to zeroes before freeing.
63 memset(pskCredsBlob->creds, 0, sizeof(OCDtlsPskCredsBlob)*(pskCredsBlob->num));
64 free(pskCredsBlob->creds);
66 memset(pskCredsBlob, 0, sizeof(OCDtlsPskCredsBlob));
70 printf("clearDtlsCredentialInfo OUT\n");
73 // Internal API. Invoked by OC stack to retrieve credentials from this module
74 void CAGetDtlsPskCredentials(OCDtlsPskCredsBlob **credInfo)
76 printf("CAGetDtlsPskCredentials IN\n");
78 *credInfo = pskCredsBlob;
80 printf("CAGetDtlsPskCredentials OUT\n");
83 int32_t SetCredentials()
85 printf("SetCredentials IN\n");
86 pskCredsBlob = (OCDtlsPskCredsBlob *)malloc(sizeof(OCDtlsPskCredsBlob));
88 memset(pskCredsBlob, 0x0, sizeof(OCDtlsPskCredsBlob));
89 memcpy(pskCredsBlob->rsIdentity, IDENTITY, DTLS_PSK_ID_LEN);
91 pskCredsBlob->num = 1;
93 pskCredsBlob->creds = (OCDtlsPskCredsBlob *)malloc(sizeof(OCDtlsPskCredsBlob) *(pskCredsBlob->num));
95 memcpy(pskCredsBlob->creds[0].clientIdentity, IDENTITY, DTLS_PSK_ID_LEN);
96 memcpy(pskCredsBlob->creds[0].rsClientPsk, RS_CLIENT_PSK, DTLS_PSK_PSK_LEN);
98 printf("SetCredentials OUT\n");
103 JNIEXPORT void JNICALL Java_com_iotivity_service_RMInterface_RMInitialize
104 (JNIEnv *env, jobject obj, jobject context)
106 LOGI("RMInitialize");
107 //Currently set context for WiFiCore
108 CAJniSetContext(context);
109 CALEServerJNISetContext(env, context);
110 CALEClientJNISetContext(env, context);
111 CALENetworkMonitorJNISetContext(env, context);
116 if (SetCredentials() == 0)
118 printf("SetCredentials failed\n");
121 res = CARegisterDTLSCredentialsHandler(CAGetDtlsPskCredentials);
122 if(res != CA_STATUS_OK)
124 printf("Set credential handler fail\n");
128 if(CA_STATUS_OK != CAInitialize())
130 LOGI("Could not Initialize");
134 JNIEXPORT void JNICALL Java_com_iotivity_service_RMInterface_RMTerminate(JNIEnv *env, jobject obj)
141 JNIEXPORT void JNICALL Java_com_iotivity_service_RMInterface_RMStartListeningServer(JNIEnv *env,
144 LOGI("RMStartListeningServer");
146 if(CA_STATUS_OK != CAStartListeningServer())
148 LOGI("Could not start Listening server");
152 JNIEXPORT void JNICALL Java_com_iotivity_service_RMInterface_RMStartDiscoveryServer(JNIEnv *env,
155 LOGI("RMStartDiscoveryServer");
157 if(CA_STATUS_OK != CAStartDiscoveryServer())
159 LOGI("Could not start discovery server");
163 JNIEXPORT void JNICALL Java_com_iotivity_service_RMInterface_RMRegisterHandler(JNIEnv *env,
166 LOGI("RMRegisterHandler");
168 CARegisterHandler(request_handler, response_handler);
171 JNIEXPORT void JNICALL Java_com_iotivity_service_RMInterface_RMFindResource(JNIEnv *env, jobject obj,
174 const char* strUri = (*env)->GetStringUTFChars(env, uri, NULL);
175 LOGI("RMFindResource - %s", strUri);
178 CAToken_t token = NULL;
179 CAResult_t res = CAGenerateToken(&token);
180 if (res != CA_STATUS_OK)
182 printf("token generate error!!\n");
186 LOGI("generated token %s\n", (token != NULL) ? token : "");
188 if(CA_STATUS_OK != CAFindResource((const CAURI_t)strUri, token))
190 LOGI("Could not find resource");
194 LOGI("find resource to %s URI", strUri);
195 gLastRequestToken = token;
199 JNIEXPORT void JNICALL Java_com_iotivity_service_RMInterface_RMSendRequest(JNIEnv *env, jobject obj,
200 jstring uri, jstring payload, jint selectedNetwork, jint isSecured, jint msgType)
202 const char* strUri = (*env)->GetStringUTFChars(env, uri, NULL);
203 LOGI("RMSendRequest - %s", strUri);
207 LOGI("selectedNetwork - %d", selectedNetwork);
208 res = get_network_type(selectedNetwork);
209 if (res != CA_STATUS_OK)
214 //create remote endpoint
215 CARemoteEndpoint_t* endpoint = NULL;
217 if(CA_STATUS_OK != CACreateRemoteEndpoint((const CAURI_t)strUri, gSelectedNwType, &endpoint))
219 LOGI("Could not create remote end point");
220 CADestroyRemoteEndpoint(endpoint);
224 CAMessageType_t messageType = msgType;
227 CAToken_t token = NULL;
228 res = CAGenerateToken(&token);
229 if (res != CA_STATUS_OK)
231 printf("token generate error!!\n");
235 char resourceURI[15] = {0};
237 get_resource_uri((const CAURI_t)strUri, resourceURI, 14);
239 CAInfo_t requestData;
240 memset(&requestData, 0, sizeof(CAInfo_t));
241 requestData.token = token;
243 const char* strPayload = (*env)->GetStringUTFChars(env, payload, NULL);
246 int length = strlen(gSecureInfoData) + strlen(resourceURI) + 1;
247 requestData.payload = (CAPayload_t) malloc(length);
248 sprintf(requestData.payload, gSecureInfoData, resourceURI, gLocalSecurePort);
252 int length = strlen(strPayload) + strlen(resourceURI) + 1;
253 requestData.payload = (CAPayload_t) malloc(length);
254 sprintf(requestData.payload, strPayload, resourceURI);
257 requestData.type = messageType;
259 CARequestInfo_t requestInfo;
260 memset(&requestInfo, 0, sizeof(CARequestInfo_t));
261 requestInfo.method = CA_GET;
262 requestInfo.info = requestData;
265 if(CA_STATUS_OK != CASendRequest(endpoint, &requestInfo))
267 LOGI("Could not send request");
273 CADestroyToken(token);
276 // destroy remote endpoint
277 if (endpoint != NULL)
279 CADestroyRemoteEndpoint(endpoint);
283 JNIEXPORT void JNICALL Java_com_iotivity_service_RMInterface_RMSendResponse(JNIEnv *env,
284 jobject obj, jstring uri, jstring payload, jint selectedNetwork, jint isSecured)
286 LOGI("RMSendResponse");
288 const char* strUri = (*env)->GetStringUTFChars(env, uri, NULL);
289 LOGI("RMSendResponse - %s", strUri);
293 LOGI("selectedNetwork - %d", selectedNetwork);
295 res = get_network_type(selectedNetwork);
296 if (res != CA_STATUS_OK)
298 LOGI("Not supported network type");
302 //create remote endpoint
303 CARemoteEndpoint_t* endpoint = NULL;
305 if(CA_STATUS_OK != CACreateRemoteEndpoint((const CAURI_t)strUri, gSelectedNwType, &endpoint))
307 LOGI("Could not create remote end point");
308 CADestroyRemoteEndpoint(endpoint);
312 CAMessageType_t messageType = CA_MSG_ACKNOWLEDGE;
315 CAToken_t token = NULL;
316 res = CAGenerateToken(&token);
317 if (res != CA_STATUS_OK)
319 LOGI("token generate error!");
323 char resourceURI[15] = {0};
325 get_resource_uri((const CAURI_t)strUri, resourceURI, 14);
327 CAInfo_t responseData;
328 memset(&responseData, 0, sizeof(CAInfo_t));
329 responseData.token = token;
331 const char* strPayload = (*env)->GetStringUTFChars(env, payload, NULL);
334 int length = strlen(gSecureInfoData) + strlen(resourceURI) + 1;
335 responseData.payload = (CAPayload_t) malloc(length);
336 sprintf(responseData.payload, gSecureInfoData, resourceURI, gLocalSecurePort);
340 int length = strlen(strPayload) + strlen(resourceURI) + 1;
341 responseData.payload = (CAPayload_t) malloc(length);
342 sprintf(responseData.payload, strPayload, resourceURI);
345 responseData.type = messageType;
347 CAResponseInfo_t responseInfo;
348 memset(&responseInfo, 0, sizeof(CAResponseInfo_t));
349 responseInfo.result = CA_SUCCESS;
350 responseInfo.info = responseData;
353 if(CA_STATUS_OK != CASendResponse(endpoint, &responseInfo))
355 LOGI("Could not send response");
358 LOGI("Send response");
363 CADestroyToken(token);
366 // destroy remote endpoint
367 if (endpoint != NULL)
369 CADestroyRemoteEndpoint(endpoint);
374 JNIEXPORT void JNICALL Java_com_iotivity_service_RMInterface_RMAdvertiseResource(JNIEnv *env,
375 jobject obj, jstring uri, jint selectedNetwork)
377 LOGI("RMAdvertiseResource");
379 const char* strUri = (*env)->GetStringUTFChars(env, uri, NULL);
383 CAHeaderOption_t *headerOpt;
384 headerOpt = (CAHeaderOption_t*) malloc(sizeof(CAHeaderOption_t) * optionNum);
385 if (NULL == headerOpt)
387 printf("Memory allocation failed!\n");
390 memset(headerOpt, 0, sizeof(CAHeaderOption_t) * optionNum);
392 char* tmpOptionData1 = "Hello";
393 headerOpt[0].optionID = 3000;
394 memcpy(headerOpt[0].optionData, tmpOptionData1, strlen(tmpOptionData1));
395 headerOpt[0].optionLength = (uint16_t) strlen(tmpOptionData1);
397 char* tmpOptionData2 = "World";
398 headerOpt[1].optionID = 3001;
399 memcpy(headerOpt[1].optionData, tmpOptionData2, strlen(tmpOptionData2));
400 headerOpt[1].optionLength = (uint16_t) strlen(tmpOptionData2);
403 CAToken_t token = NULL;
404 CAResult_t res = CAGenerateToken(&token);
405 if (res != CA_STATUS_OK)
407 LOGI("token generate error!");
411 CAAdvertiseResource((const CAURI_t)strUri, token, headerOpt, (uint8_t) optionNum);
416 JNIEXPORT void JNICALL Java_com_iotivity_service_RMInterface_RMSendNotification(JNIEnv *env,
417 jobject obj, jstring uri, jstring payload, jint selectedNetwork, jint isSecured)
419 const char* strUri = (*env)->GetStringUTFChars(env, uri, NULL);
420 LOGI("RMSendNotification - %s", strUri);
424 LOGI("selectedNetwork - %d", selectedNetwork);
426 res = get_network_type(selectedNetwork);
427 if (res != CA_STATUS_OK)
429 LOGI("Not supported network type");
433 //create remote endpoint
434 CARemoteEndpoint_t* endpoint = NULL;
436 if(CA_STATUS_OK != CACreateRemoteEndpoint((const CAURI_t)strUri, gSelectedNwType, &endpoint))
438 LOGI("Could not create remote end point");
439 CADestroyRemoteEndpoint(endpoint);
443 CAMessageType_t messageType = CA_MSG_NONCONFIRM;
446 CAToken_t token = NULL;
447 res = CAGenerateToken(&token);
448 if (res != CA_STATUS_OK)
450 LOGI("token generate error!");
454 char resourceURI[15] = {0};
456 get_resource_uri((const CAURI_t)strUri, resourceURI, 14);
458 CAInfo_t responseData;
459 memset(&responseData, 0, sizeof(CAInfo_t));
460 responseData.token = token;
462 const char* strPayload = (*env)->GetStringUTFChars(env, payload, NULL);
465 int length = strlen(gSecureInfoData) + strlen(resourceURI) + 1;
466 responseData.payload = (CAPayload_t) malloc(length);
467 sprintf(responseData.payload, gSecureInfoData, resourceURI, gLocalSecurePort);
471 int length = strlen(strPayload) + strlen(resourceURI) + 1;
472 responseData.payload = (CAPayload_t) malloc(length);
473 sprintf(responseData.payload, strPayload, resourceURI);
476 responseData.type = messageType;
478 CAResponseInfo_t responseInfo;
479 memset(&responseInfo, 0, sizeof(CAResponseInfo_t));
480 responseInfo.result = CA_SUCCESS;
481 responseInfo.info = responseData;
484 if(CA_STATUS_OK != CASendNotification(endpoint, &responseInfo))
486 LOGI("Could not send notification");
489 LOGI("Send Notification");
494 CADestroyToken(token);
497 // destroy remote endpoint
498 if (endpoint != NULL)
500 CADestroyRemoteEndpoint(endpoint);
504 JNIEXPORT void JNICALL Java_com_iotivity_service_RMInterface_RMSelectNetwork(JNIEnv *env, jobject obj,
507 LOGI("RMSelectNetwork Type : %d", networkType);
509 if(CA_STATUS_OK != CASelectNetwork(networkType))
511 LOGI("Could not select network");
515 JNIEXPORT void JNICALL Java_com_iotivity_service_RMInterface_RMHandleRequestResponse(JNIEnv *env,
518 LOGI("RMHandleRequestResponse");
520 if(CA_STATUS_OK != CAHandleRequestResponse())
522 LOGI("Could not handle request and response");
526 void request_handler(const CARemoteEndpoint_t* object, const CARequestInfo_t* requestInfo)
530 LOGI("Remote endpoint is NULL!");
536 LOGI("Request info is NULL!");
540 LOGI("##########received request from remote device #############\n");
541 LOGI("Uri: %s\n", object->resourceUri);
542 LOGI("Remote Address: %s\n", object->addressInfo.IP.ipAddress);
544 LOGI("Data: %s\n", requestInfo->info.payload);
546 if (NULL != gResponseListenerObject)
548 callback("received request from remote device", "#######");
549 callback("Uri: ", object->resourceUri);
551 callback("Remote Address: ", (char *) object->addressInfo.IP.ipAddress);
553 if(requestInfo->info.payload)
555 callback("Data: ", requestInfo->info.payload);
559 if (gLastRequestToken != NULL && requestInfo->info.token != NULL
560 && (strcmp((char *)gLastRequestToken, requestInfo->info.token) == 0))
562 LOGI("token is same. received request of it's own. skip.. \n");
566 if (requestInfo->info.options)
568 uint32_t len = requestInfo->info.numOptions;
570 for (i = 0; i < len; i++)
572 LOGI("Option %d\n", i + 1);
573 LOGI("ID : %d\n", requestInfo->info.options[i].optionID);
574 LOGI("Data[%d]: %s\n", requestInfo->info.options[i].optionLength,
575 requestInfo->info.options[i].optionData);
577 if (NULL != gResponseListenerObject)
580 sprintf(tmpbuf, "%d", i + 1);
581 callback("Option: ", tmpbuf);
583 sprintf(tmpbuf, "%d", requestInfo->info.options[i].optionID);
584 callback("ID: ", tmpbuf);
586 sprintf(tmpbuf, "Data:[%d]", requestInfo->info.options[i].optionLength);
587 callback("tmpbuf: ", requestInfo->info.options[i].optionData);
591 printf("############################################################\n");
593 //Check if this has secure communication information
594 if (requestInfo->info.payload)
596 int securePort = get_secure_information(requestInfo->info.payload);
597 if (0 < securePort) //Set the remote endpoint secure details and send response
599 LOGI("This is secure resource...\n");
603 length = 8; //length of "coaps://"
604 length += strlen(object->addressInfo.IP.ipAddress) + 5; // length of "ipaddress:port"
605 length += strlen(object->resourceUri) + 1;
607 uri = calloc(1,sizeof(char)*length);
610 printf("Failed to create new uri\n");
613 sprintf(uri,"coaps://%s:%d/%s",object->addressInfo.IP.ipAddress,
614 securePort, object->resourceUri);
616 CARemoteEndpoint_t *endpoint = NULL;
617 if (CA_STATUS_OK != CACreateRemoteEndpoint(uri, object->connectivityType, &endpoint))
619 LOGI("Failed to create duplicate of remote endpoint!\n");
622 endpoint->isSecured = CA_TRUE;
630 // send_response(object, (requestInfo != NULL) ? requestInfo->info.token : "");
634 void response_handler(const CARemoteEndpoint_t* object, const CAResponseInfo_t* responseInfo)
637 LOGI("##########Received response from remote device #############\n");
638 LOGI("Uri: %s\n", object->resourceUri);
639 LOGI("Remote Address: %s\n", object->addressInfo.IP.ipAddress);
640 LOGI("response result: %d\n", responseInfo->result);
641 LOGI("Data: %s\n", responseInfo->info.payload);
643 if (NULL != gResponseListenerObject)
645 callback("received response from remote device", "#######");
646 callback("Uri: ", object->resourceUri);
648 callback("Remote Address: ", (char *)object->addressInfo.IP.ipAddress);
650 if(responseInfo->info.payload)
652 callback("Data: ", responseInfo->info.payload);
656 if (responseInfo->info.options)
658 uint32_t len = responseInfo->info.numOptions;
660 for (i = 0; i < len; i++)
662 LOGI("Option %d\n", i + 1);
663 LOGI("ID : %d\n", responseInfo->info.options[i].optionID);
664 LOGI("Data[%d]: %s\n", responseInfo->info.options[i].optionLength,
665 responseInfo->info.options[i].optionData);
667 if (NULL != gResponseListenerObject)
670 sprintf(tmpbuf, "%d", i + 1);
671 callback("Option: ", tmpbuf);
673 sprintf(tmpbuf, "%d", responseInfo->info.options[i].optionID);
674 callback("ID: ", tmpbuf);
676 sprintf(tmpbuf, "Data:[%d]", responseInfo->info.options[i].optionLength);
677 callback("tmpbuf: ", responseInfo->info.options[i].optionData);
681 LOGI("############################################################\n");
684 //Check if this has secure communication information
685 if (responseInfo->info.payload)
687 int securePort = get_secure_information(responseInfo->info.payload);
688 if (0 < securePort) //Set the remote endpoint secure details and send response
690 LOGI("This is secure resource...\n");
695 void send_response(const CARemoteEndpoint_t* endpoint, CAToken_t request_token)
697 LOGI("send_response");
699 CAInfo_t responseData;
700 memset(&responseData, 0, sizeof(CAInfo_t));
701 responseData.token = request_token;
702 responseData.payload = "response payload";
704 CAResponseInfo_t responseInfo;
705 memset(&responseInfo, 0, sizeof(CAResponseInfo_t));
706 responseInfo.result = 203;
707 responseInfo.info = responseData;
710 CASendResponse(endpoint, &responseInfo);
713 void get_resource_uri(char *URI, char *resourceURI, int length)
715 char *startPos = URI;
717 if (NULL != (temp = strstr(URI, "://")))
719 startPos = strchr(temp + 3, '/');
722 printf("Resource URI is missing\n");
727 char *endPos = strchr(startPos, '?');
730 endPos = URI + strlen(URI);
734 if (endPos - startPos <= length)
735 memcpy(resourceURI, startPos + 1, endPos - startPos);
737 printf("URI: %s, ResourceURI:%s\n", URI, resourceURI);
740 int get_secure_information(CAPayload_t payLoad)
742 printf("entering get_secure_information\n");
746 printf("Payload is NULL\n");
750 char *subString = NULL;
751 if (NULL == (subString = strstr(payLoad, "\"sec\":1")))
753 printf("This is not secure resource\n");
757 if (NULL == (subString = strstr(payLoad, "\"port\":")))
759 printf("This secure resource does not have port information\n");
763 char *startPos = strstr(subString, ":");
766 printf("Parsing failed !\n");
770 char *endPos = strstr(startPos, "}");
773 printf("Parsing failed !\n");
777 char portStr[4] = {0};
778 memcpy(portStr, startPos + 1, (endPos-1) - startPos);
780 printf("secured port is: %s\n", portStr);
781 return atoi(portStr);
784 CAResult_t get_network_type(int selectedNetwork)
787 int number = selectedNetwork;
791 return CA_NOT_SUPPORTED;
793 if (number & CA_ETHERNET)
795 gSelectedNwType = CA_ETHERNET;
798 if (number & CA_WIFI)
800 gSelectedNwType = CA_WIFI;
805 gSelectedNwType = CA_EDR;
810 gSelectedNwType = CA_LE;
814 return CA_NOT_SUPPORTED;
817 void callback(char *subject, char *receicedData)
820 int status = (*g_jvm)->GetEnv(g_jvm, (void **) &env, JNI_VERSION_1_6);
821 int res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
823 jclass cls = (*env)->GetObjectClass(env, gResponseListenerObject);
824 jmethodID mid = (*env)->GetMethodID(env, cls, "OnResponseReceived", "(Ljava/lang/String;Ljava/lang/String;)V");
826 jstring jsubject = (*env)->NewStringUTF(env, (char*)subject);
827 jstring jreceivedData = (*env)->NewStringUTF(env, (char*)receicedData);
828 (*env)->CallVoidMethod(env, gResponseListenerObject, mid, jsubject, jreceivedData);