2 #include <android/log.h>
9 #include "cainterface.h"
11 #include "caadapterutils.h"
13 #include "org_iotivity_ca_service_RMInterface.h"
15 #define LOG_TAG "JNI_INTERFACE_SAMPLE"
16 #define LOGI(...) __android_log_print(ANDROID_LOG_INFO, LOG_TAG, __VA_ARGS__)
17 #define LOGE(...) __android_log_print(ANDROID_LOG_ERROR, LOG_TAG, __VA_ARGS__)
23 #define IDENTITY ("1111111111111111")
27 #define RS_CLIENT_PSK ("AAAAAAAAAAAAAAAA")
30 #define SECURE_DEFAULT_PORT 5684
31 #define RESOURCE_URI_LENGTH 14
32 #define OPTION_INFO_LENGTH 1024
33 #define NETWORK_INFO_LENGTH 1024
34 #define BIG_PAYLOAD_LENGTH 1024
35 #define RECEIVED_FILE_NAME_PREFIX_LENGTH 7
36 #define RECEIVED_FILE_NAME_LENGTH 14
40 char ipAddress[CA_IPADDR_SIZE];
44 static void request_handler(const CAEndpoint_t* object, const CARequestInfo_t* requestInfo);
45 static void response_handler(const CAEndpoint_t* object, const CAResponseInfo_t* responseInfo);
46 static void error_handler(const CAEndpoint_t *object, const CAErrorInfo_t* errorInfo);
47 static void get_resource_uri(const char *URI, char *resourceURI, int32_t length);
48 static uint32_t get_secure_information(CAPayload_t payLoad);
49 static CAResult_t get_network_type(uint32_t selectedNetwork);
50 static void callback(char *subject, char *receivedData);
51 static CAResult_t get_remote_address(const char *address);
52 static void parsing_coap_uri(const char* uri, addressSet_t* address, CATransportFlags_t *flags);
53 static void delete_global_references(JNIEnv *env, jobject obj);
54 static int get_address_set(const char *pAddress, addressSet_t* outAddress);
55 bool read_file(const char* name, char** bytes, size_t* length);
56 uint32_t gettodaydate();
57 void saveFile(const char *payload, size_t payloadSize);
59 uint16_t g_localSecurePort = SECURE_DEFAULT_PORT;
60 CATransportAdapter_t g_selectedNwType = CA_ADAPTER_IP;
61 static CAToken_t g_lastRequestToken = NULL;
62 static uint8_t g_lastRequestTokenLength = 0;
64 static const char COAP_PREFIX[] = "coap://";
65 static const char COAPS_PREFIX[] = "coaps://";
66 static const uint16_t COAP_PREFIX_LEN = sizeof(COAP_PREFIX) - 1;
67 static const uint16_t COAPS_PREFIX_LEN = sizeof(COAPS_PREFIX) - 1;
69 static const char RECEIVED_FILE_PATH[] = "/storage/emulated/0/Download/%d%s.txt";
71 static const char SECURE_INFO_DATA[]
72 = "{\"oc\":[{\"href\":\"%s\",\"prop\":{\"rt\":[\"core.led\"],"
73 "\"if\":[\"oic.if.baseline\"],\"obs\":1,\"sec\":1,\"port\":"
75 static const char NORMAL_INFO_DATA[]
76 = "{\"oc\":[{\"href\":\"%s\",\"prop\":{\"rt\":[\"core.led\"],"
77 "\"if\":[\"oic.if.baseline\"],\"obs\":1}}]}";
79 static jobject g_responseListenerObject = NULL;
82 static CAEndpoint_t *g_clientEndpoint = NULL;
83 static char *g_resourceUri = NULL;
84 static CAToken_t g_clientToken = NULL;
85 static uint8_t g_clientTokenLength = 0;
87 static uint16_t g_clientMsgId = 0;
88 static char *g_remoteAddress = NULL;
91 JNIEXPORT void JNICALL
92 Java_org_iotivity_ca_service_RMInterface_setNativeResponseListener(JNIEnv *env, jobject obj,
95 LOGI("setNativeResponseListener");
96 if (!env || !obj || !listener)
98 LOGI("Invalid input parameter");
102 g_responseListenerObject = (*env)->NewGlobalRef(env, listener);
106 static CADtlsPskCredsBlob_t *pskCredsBlob = NULL;
108 void clearDtlsCredentialInfo()
110 LOGI("clearDtlsCredentialInfo IN");
113 // Initialize sensitive data to zeroes before freeing.
114 if (NULL != pskCredsBlob->creds)
116 memset(pskCredsBlob->creds, 0, sizeof(OCDtlsPskCreds)*(pskCredsBlob->num));
117 free(pskCredsBlob->creds);
120 memset(pskCredsBlob, 0, sizeof(CADtlsPskCredsBlob_t));
124 LOGI("clearDtlsCredentialInfo OUT");
127 // Internal API. Invoked by OC stack to retrieve credentials from this module
128 void CAGetDtlsPskCredentials(CADtlsPskCredsBlob_t **credInfo)
130 LOGI("CAGetDtlsPskCredentials IN");
131 *credInfo = (CADtlsPskCredsBlob_t *) malloc(sizeof(CADtlsPskCredsBlob_t));
132 if (NULL == *credInfo)
134 LOGE("Failed to allocate credential blob.");
138 int16_t credLen = sizeof(OCDtlsPskCreds) * (pskCredsBlob->num);
139 (*credInfo)->creds = (OCDtlsPskCreds *) malloc(credLen);
140 if (NULL == (*credInfo)->creds)
142 LOGE("Failed to allocate crentials.");
148 memcpy((*credInfo)->identity, pskCredsBlob->identity, DTLS_PSK_ID_LEN);
149 (*credInfo)->num = pskCredsBlob->num;
150 memcpy((*credInfo)->creds, pskCredsBlob->creds, credLen);
152 LOGI("CAGetDtlsPskCredentials OUT");
155 CAResult_t SetCredentials()
157 LOGI("SetCredentials IN");
158 pskCredsBlob = (CADtlsPskCredsBlob_t *)malloc(sizeof(CADtlsPskCredsBlob_t));
159 if (NULL == pskCredsBlob)
161 LOGE("Memory allocation failed!");
162 return CA_MEMORY_ALLOC_FAILED;
164 memcpy(pskCredsBlob->identity, IDENTITY, DTLS_PSK_ID_LEN);
166 pskCredsBlob->num = 1;
168 pskCredsBlob->creds = (OCDtlsPskCreds *)malloc(sizeof(OCDtlsPskCreds) *(pskCredsBlob->num));
169 if (NULL == pskCredsBlob->creds)
171 LOGE("Memory allocation failed!");
172 return CA_MEMORY_ALLOC_FAILED;
174 memcpy(pskCredsBlob->creds[0].id, IDENTITY, DTLS_PSK_ID_LEN);
175 memcpy(pskCredsBlob->creds[0].psk, RS_CLIENT_PSK, DTLS_PSK_PSK_LEN);
177 LOGI("SetCredentials OUT");
182 JNIEXPORT jint JNI_OnLoad(JavaVM *jvm, void *reserved)
187 if (JNI_OK != (*jvm)->GetEnv(jvm, (void**) &env, JNI_VERSION_1_6))
191 g_jvm = jvm; /* cache the JavaVM pointer */
193 CANativeJNISetJavaVM(g_jvm);
195 return JNI_VERSION_1_6;
198 void JNI_OnUnload(JavaVM *jvm, void *reserved)
200 LOGI("JNI_OnUnload");
203 if (JNI_OK != (*jvm)->GetEnv(jvm, (void**) &env, JNI_VERSION_1_6))
211 JNIEXPORT void JNICALL
212 Java_org_iotivity_ca_service_RMInterface_RMInitialize(JNIEnv *env, jobject obj, jobject context)
214 LOGI("RMInitialize");
215 if (!env || !obj || !context)
217 LOGI("Invalid input parameter");
221 //Currently set context for Android Platform
222 CANativeJNISetContext(env, context);
224 CAResult_t res = CAInitialize();
226 if (CA_STATUS_OK != res)
228 LOGE("Could not Initialize");
232 if (CA_STATUS_OK != SetCredentials())
234 LOGE("SetCredentials failed");
238 res = CARegisterDTLSCredentialsHandler(CAGetDtlsPskCredentials);
239 if(CA_STATUS_OK != res)
241 LOGE("Set credential handler fail");
247 JNIEXPORT void JNICALL
248 Java_org_iotivity_ca_service_RMInterface_RMTerminate(JNIEnv *env, jobject obj)
253 LOGI("Invalid input parameter");
257 CADestroyToken(g_lastRequestToken);
259 delete_global_references(env, obj);
262 JNIEXPORT void JNICALL
263 Java_org_iotivity_ca_service_RMInterface_RMStartListeningServer(JNIEnv *env, jobject obj)
265 LOGI("RMStartListeningServer");
268 LOGI("Invalid input parameter");
272 if (CA_STATUS_OK != CAStartListeningServer())
274 LOGE("Could not start Listening server");
278 JNIEXPORT void JNICALL
279 Java_org_iotivity_ca_service_RMInterface_RMStartDiscoveryServer(JNIEnv *env, jobject obj)
281 LOGI("RMStartDiscoveryServer");
284 LOGI("Invalid input parameter");
288 if (CA_STATUS_OK != CAStartDiscoveryServer())
290 LOGE("Could not start discovery server");
294 JNIEXPORT void JNICALL
295 Java_org_iotivity_ca_service_RMInterface_RMRegisterHandler(JNIEnv *env, jobject obj)
297 LOGI("RMRegisterHandler");
300 LOGI("Invalid input parameter");
304 CARegisterHandler(request_handler, response_handler, error_handler);
307 JNIEXPORT void JNICALL
308 Java_org_iotivity_ca_service_RMInterface_RMSendRequest(JNIEnv *env, jobject obj, jstring uri,
309 jstring payload, jint selectedNetwork,
310 jint isSecured, jint msgType,
313 LOGI("selectedNetwork - %d", selectedNetwork);
316 LOGI("Invalid input parameter");
322 LOGE("Invalid input parameter : uri");
326 CAResult_t res = get_network_type(selectedNetwork);
327 if (CA_STATUS_OK != res)
332 const char* strUri = (*env)->GetStringUTFChars(env, uri, NULL);
333 LOGI("RMSendRequest - %s", strUri);
335 CATransportFlags_t flags;
336 addressSet_t address = {{0}, 0};
337 parsing_coap_uri(strUri, &address, &flags);
339 //create remote endpoint
340 CAEndpoint_t* endpoint = NULL;
341 res = CACreateEndpoint(flags, g_selectedNwType, (const char*)(address.ipAddress),
342 address.port, &endpoint);
343 if (CA_STATUS_OK != res)
345 LOGE("Could not create remote end point");
346 (*env)->ReleaseStringUTFChars(env, uri, strUri);
350 CAMessageType_t messageType = msgType;
353 CAToken_t token = NULL;
354 uint8_t tokenLength = CA_MAX_TOKEN_LEN;
356 res = CAGenerateToken(&token, tokenLength);
357 if ((CA_STATUS_OK != res) || (!token))
359 LOGE("token generate error!!");
360 // destroy remote endpoint
361 CADestroyEndpoint(endpoint);
362 (*env)->ReleaseStringUTFChars(env, uri, strUri);
366 char resourceURI[RESOURCE_URI_LENGTH + 1] = { 0 };
368 get_resource_uri((const CAURI_t) strUri, resourceURI, RESOURCE_URI_LENGTH);
369 (*env)->ReleaseStringUTFChars(env, uri, strUri);
371 CAInfo_t requestData = { 0 };
372 requestData.token = token;
373 requestData.tokenLength = tokenLength;
375 size_t payloadLength = 0;
378 const char* path = NULL;
381 path = (*env)->GetStringUTFChars(env, payload, NULL);
384 char* bigData = NULL;
385 bool result = read_file(path, &bigData, &payloadLength);
388 LOGE("read has failed");
389 (*env)->ReleaseStringUTFChars(env, payload, path);
392 (*env)->ReleaseStringUTFChars(env, payload, path);
394 requestData.payload = (CAPayload_t) malloc(payloadLength);
395 if (NULL == requestData.payload)
397 LOGE("Memory allocation failed!");
399 CADestroyToken(token);
400 // destroy remote endpoint
401 CADestroyEndpoint(endpoint);
404 memcpy(requestData.payload, bigData, payloadLength);
405 requestData.payloadSize = payloadLength;
413 payloadLength = sizeof(SECURE_INFO_DATA) + strlen(resourceURI);
414 requestData.payload = (CAPayload_t) malloc(payloadLength);
415 if (NULL == requestData.payload)
417 LOGE("Memory allocation failed!");
419 CADestroyToken(token);
420 // destroy remote endpoint
421 CADestroyEndpoint(endpoint);
424 snprintf((char *) requestData.payload, payloadLength, SECURE_INFO_DATA,
425 resourceURI, g_localSecurePort);
426 requestData.payloadSize = payloadLength;
430 payloadLength = sizeof(NORMAL_INFO_DATA) + strlen(resourceURI);
431 requestData.payload = (CAPayload_t) malloc(payloadLength);
432 if (NULL == requestData.payload)
434 LOGE("Memory allocation failed!");
436 CADestroyToken(token);
437 // destroy remote endpoint
438 CADestroyEndpoint(endpoint);
441 snprintf((char *) requestData.payload, payloadLength, NORMAL_INFO_DATA, resourceURI);
442 requestData.payloadSize = payloadLength;
446 requestData.type = messageType;
447 requestData.resourceUri = (CAURI_t) malloc(sizeof(resourceURI));
448 if (NULL == requestData.resourceUri)
450 LOGE("Memory allocation failed!");
452 CADestroyToken(token);
453 // destroy remote endpoint
454 CADestroyEndpoint(endpoint);
455 free(requestData.payload);
458 memcpy(requestData.resourceUri, resourceURI, sizeof(resourceURI));
460 CARequestInfo_t requestInfo = { 0 };
461 requestInfo.method = CA_GET;
462 requestInfo.isMulticast = false;
463 requestInfo.info = requestData;
466 if (CA_STATUS_OK != CASendRequest(endpoint, &requestInfo))
468 LOGE("Could not send request");
472 CADestroyToken(token);
474 // destroy remote endpoint
475 CADestroyEndpoint(endpoint);
477 free(requestData.payload);
478 free(requestData.resourceUri);
481 JNIEXPORT void JNICALL
482 Java_org_iotivity_ca_service_RMInterface_RMSendReqestToAll(JNIEnv *env, jobject obj, jstring uri,
483 jint selectedNetwork)
485 LOGI("selectedNetwork - %d", selectedNetwork);
488 LOGI("Invalid input parameter");
492 CAResult_t res = get_network_type(selectedNetwork);
493 if (CA_STATUS_OK != res)
498 // create remote endpoint
499 CAEndpoint_t *endpoint = NULL;
500 res = CACreateEndpoint(CA_IPV4, g_selectedNwType, NULL, 0, &endpoint);
502 if (CA_STATUS_OK != res)
504 LOGE("create remote endpoint error, error code: %d", res);
509 CAToken_t token = NULL;
510 uint8_t tokenLength = CA_MAX_TOKEN_LEN;
512 res = CAGenerateToken(&token, tokenLength);
513 if ((CA_STATUS_OK != res) || (!token))
515 LOGE("token generate error!!");
516 // destroy remote endpoint
517 CADestroyEndpoint(endpoint);
521 LOGI("generated token %s", token);
523 CAInfo_t requestData = { 0 };
524 requestData.token = token;
525 requestData.tokenLength = tokenLength;
526 requestData.payload = (CAPayload_t) "TempJsonPayload";
527 requestData.payloadSize = strlen((const char *) requestData.payload);
528 requestData.type = CA_MSG_NONCONFIRM;
530 const char* strUri = (*env)->GetStringUTFChars(env, uri, NULL);
531 LOGI("resourceUri - %s", strUri);
532 requestData.resourceUri = (CAURI_t)strUri;
534 uint8_t optionNum = 2;
535 CAHeaderOption_t *headerOpt = (CAHeaderOption_t*) calloc(1,
536 sizeof(CAHeaderOption_t) * optionNum);
537 if (NULL == headerOpt)
539 LOGE("Memory allocation failed");
540 // destroy remote endpoint
541 CADestroyEndpoint(endpoint);
545 char* FirstOptionData = "Hello";
546 headerOpt[0].optionID = 3000;
547 memcpy(headerOpt[0].optionData, FirstOptionData, strlen(FirstOptionData));
548 headerOpt[0].optionLength = (uint16_t) strlen(FirstOptionData);
550 char* SecondOptionData2 = "World";
551 headerOpt[1].optionID = 3001;
552 memcpy(headerOpt[1].optionData, SecondOptionData2, strlen(SecondOptionData2));
553 headerOpt[1].optionLength = (uint16_t) strlen(SecondOptionData2);
555 requestData.numOptions = optionNum;
556 requestData.options = headerOpt;
558 CARequestInfo_t requestInfo = { 0 };
559 requestInfo.method = CA_GET;
560 requestInfo.isMulticast = true;
561 requestInfo.info = requestData;
563 // send request to all
564 res = CASendRequest(endpoint, &requestInfo);
565 if (CA_STATUS_OK != res)
567 LOGE("Could not send request to all");
569 CADestroyToken(token);
573 CADestroyToken(g_lastRequestToken);
574 g_lastRequestToken = token;
575 g_lastRequestTokenLength = tokenLength;
578 //ReleaseStringUTFChars for strUri
579 (*env)->ReleaseStringUTFChars(env, uri, strUri);
583 // destroy remote endpoint
584 CADestroyEndpoint(endpoint);
587 JNIEXPORT void JNICALL
588 Java_org_iotivity_ca_service_RMInterface_RMSendResponse(JNIEnv *env, jobject obj,
589 jint selectedNetwork,
590 jint isSecured, jint msgType,
593 LOGI("RMSendResponse");
596 LOGI("Invalid input parameter");
600 LOGI("selectedNetwork - %d", selectedNetwork);
602 CAResult_t res = get_network_type(selectedNetwork);
603 if (CA_STATUS_OK != res)
605 LOGE("Not supported network type");
609 if (NULL == g_clientEndpoint)
611 LOGE("No Request received");
615 CAMessageType_t messageType = msgType;
617 CAInfo_t responseData = { 0 };
618 responseData.type = messageType;
619 responseData.messageId = g_clientMsgId;
620 responseData.resourceUri = (CAURI_t)g_resourceUri;
622 CAResponseInfo_t responseInfo = { 0 };
624 if (msgType != CA_MSG_RESET)
626 responseData.token = g_clientToken;
627 responseData.tokenLength = g_clientTokenLength;
628 responseInfo.result = responseValue;
632 uint32_t length = strlen(SECURE_INFO_DATA) + strlen(g_resourceUri) + 1;
633 responseData.payload = (CAPayload_t) malloc(length);
634 sprintf((char *) responseData.payload, SECURE_INFO_DATA, g_resourceUri,
636 responseData.payloadSize = length;
640 uint32_t length = strlen(NORMAL_INFO_DATA) + strlen(g_resourceUri) + 1;
641 responseData.payload = (CAPayload_t) malloc(length);
642 sprintf((char *) responseData.payload, NORMAL_INFO_DATA, g_resourceUri);
643 responseData.payloadSize = length;
649 responseInfo.result = CA_EMPTY;
652 responseInfo.info = responseData;
655 res = CASendResponse(g_clientEndpoint, &responseInfo);
656 if (CA_STATUS_OK != res)
658 LOGE("Could not send response");
662 CADestroyToken(g_clientToken);
663 g_clientToken = NULL;
664 g_clientTokenLength = 0;
666 // destroy remote endpoint
667 CADestroyEndpoint(g_clientEndpoint);
668 g_clientEndpoint = NULL;
671 JNIEXPORT void JNICALL
672 Java_org_iotivity_ca_service_RMInterface_RMSendNotification(JNIEnv *env, jobject obj, jstring uri,
673 jstring payload, jint selectedNetwork,
674 jint isSecured, jint msgType,
677 LOGI("selectedNetwork - %d", selectedNetwork);
680 LOGI("Invalid input parameter");
686 LOGE("payload is NULL");
691 LOGE("Invalid input parameter : uri");
695 CAResult_t res = get_network_type(selectedNetwork);
696 if (CA_STATUS_OK != res)
698 LOGE("Not supported network type");
702 const char* strUri = (*env)->GetStringUTFChars(env, uri, NULL);
703 LOGI("RMSendNotification - %s", strUri);
705 CATransportFlags_t flags;
706 addressSet_t address = {{0}, 0};
707 parsing_coap_uri(strUri, &address, &flags);
709 //create remote endpoint
710 CAEndpoint_t* endpoint = NULL;
711 if (CA_STATUS_OK != CACreateEndpoint(flags, g_selectedNwType,
712 (const char*)address.ipAddress,
713 address.port, &endpoint))
715 //ReleaseStringUTFChars for strUri
716 (*env)->ReleaseStringUTFChars(env, uri, strUri);
717 LOGE("Could not create remote end point");
721 char resourceURI[RESOURCE_URI_LENGTH + 1] = { 0 };
722 get_resource_uri(strUri, resourceURI, RESOURCE_URI_LENGTH);
724 //ReleaseStringUTFChars for strUri
725 (*env)->ReleaseStringUTFChars(env, uri, strUri);
727 CAMessageType_t messageType = msgType;
730 CAToken_t token = NULL;
731 uint8_t tokenLength = CA_MAX_TOKEN_LEN;
733 res = CAGenerateToken(&token, tokenLength);
734 if ((CA_STATUS_OK != res) || (!token))
736 LOGE("token generate error!");
737 CADestroyEndpoint(endpoint);
741 CAInfo_t responseData = { 0 };
742 responseData.token = token;
743 responseData.tokenLength = tokenLength;
744 responseData.resourceUri = (CAURI_t) malloc(sizeof(resourceURI));
745 if (NULL == responseData.resourceUri)
747 LOGE("Memory allocation failed!");
749 CADestroyToken(token);
750 // destroy remote endpoint
751 CADestroyEndpoint(endpoint);
754 memcpy(responseData.resourceUri, resourceURI, sizeof(resourceURI));
758 uint32_t length = sizeof(SECURE_INFO_DATA) + strlen(resourceURI);
759 responseData.payload = (CAPayload_t) malloc(length);
760 if (NULL == responseData.payload)
762 LOGE("Memory allocation failed!");
764 CADestroyToken(token);
765 // destroy remote endpoint
766 CADestroyEndpoint(endpoint);
768 free(responseData.resourceUri);
771 snprintf((char *) responseData.payload, length, SECURE_INFO_DATA, resourceURI, g_localSecurePort);
772 responseData.payloadSize = length;
776 uint32_t length = sizeof(NORMAL_INFO_DATA) + strlen(resourceURI);
777 responseData.payload = (CAPayload_t) malloc(length);
778 if (NULL == responseData.payload)
780 LOGE("Memory allocation failed!");
782 CADestroyToken(token);
783 // destroy remote endpoint
784 CADestroyEndpoint(endpoint);
786 free(responseData.resourceUri);
789 snprintf((char *) responseData.payload, length, NORMAL_INFO_DATA, resourceURI);
790 responseData.payloadSize = length;
793 responseData.type = messageType;
795 CAResponseInfo_t responseInfo = { 0 };
796 responseInfo.result = responseValue;
797 responseInfo.info = responseData;
800 if (CA_STATUS_OK != CASendNotification(endpoint, &responseInfo))
802 LOGE("Could not send notification");
805 LOGI("Send Notification");
808 CADestroyToken(token);
810 // destroy remote endpoint
811 CADestroyEndpoint(endpoint);
813 free(responseData.payload);
814 free(responseData.resourceUri);
817 JNIEXPORT void JNICALL
818 Java_org_iotivity_ca_service_RMInterface_RMSelectNetwork(JNIEnv *env, jobject obj,
821 LOGI("RMSelectNetwork Type : %d", networkType);
824 LOGI("Invalid input parameter");
828 if (CA_STATUS_OK != CASelectNetwork(networkType))
830 LOGE("Could not select network");
834 JNIEXPORT void JNICALL
835 Java_org_iotivity_ca_service_RMInterface_RMUnSelectNetwork(JNIEnv *env, jobject obj,
838 LOGI("RMUnSelectNetwork Type : %d", networkType);
841 LOGI("Invalid input parameter");
845 if (CA_STATUS_OK != CAUnSelectNetwork(networkType))
847 LOGE("Could not unselect network");
851 JNIEXPORT void JNICALL
852 Java_org_iotivity_ca_service_RMInterface_RMGetNetworkInfomation(JNIEnv *env, jobject obj)
854 LOGI("RMGetNetworkInfomation");
857 LOGI("Invalid input parameter");
861 CAEndpoint_t *tempInfo = NULL;
862 uint32_t tempSize = 0;
864 CAResult_t res = CAGetNetworkInformation(&tempInfo, &tempSize);
865 if (CA_STATUS_OK != res)
867 LOGE("Could not start get network information");
872 LOGI("################## Network Information #######################");
873 callback("######## Network Information", "#######");
874 LOGI("Network info total size is %d", tempSize);
877 for (index = 0; index < tempSize; index++)
879 res = get_remote_address(tempInfo[index].addr);
880 if (CA_STATUS_OK != res)
885 if (NULL != g_responseListenerObject)
887 char networkInfo[NETWORK_INFO_LENGTH];
888 LOGI("Type: %d", tempInfo[index].adapter);
889 sprintf(networkInfo, "%d",tempInfo[index].adapter);
890 callback("Type :", networkInfo);
891 if (CA_ADAPTER_IP == tempInfo[index].adapter)
893 LOGI("Port: %d", tempInfo[index].port);
894 sprintf(networkInfo, "%d",tempInfo[index].port);
895 callback("Port: ", networkInfo);
897 LOGI("Secured: %d", (tempInfo[index].flags & CA_SECURE));
898 LOGI("Address: %s", g_remoteAddress);
899 callback("Address: ", g_remoteAddress);
900 free(g_remoteAddress);
902 if (tempInfo[index].flags & CA_SECURE)
904 g_localSecurePort = tempInfo[index].port;
911 LOGI("##############################################################");
914 JNIEXPORT void JNICALL
915 Java_org_iotivity_ca_service_RMInterface_RMHandleRequestResponse(JNIEnv *env, jobject obj)
917 LOGI("RMHandleRequestResponse");
920 LOGI("Invalid input parameter");
924 if (CA_STATUS_OK != CAHandleRequestResponse())
926 LOGE("Could not handle request and response");
930 void request_handler(const CAEndpoint_t* object, const CARequestInfo_t* requestInfo)
935 LOGE("Remote endpoint is NULL!");
941 LOGE("Request info is NULL!");
945 if ((NULL != g_lastRequestToken) && (NULL != requestInfo->info.token) &&
946 (strncmp(g_lastRequestToken, requestInfo->info.token,
947 requestInfo->info.tokenLength) == 0))
949 LOGI("token is same. received request of it's own. skip.. ");
953 CAResult_t res = get_remote_address(object->addr);
954 if (CA_STATUS_OK != res)
959 LOGI("##########received request from remote device #############");
960 LOGI("Remote Address: %s", g_remoteAddress);
961 LOGI("Remote Port: %d", object->port);
962 LOGI("Uri: %s", requestInfo->info.resourceUri);
963 LOGI("Data: %s", requestInfo->info.payload);
964 LOGI("Token: %s", requestInfo->info.token);
965 LOGI("Code: %d", requestInfo->method);
966 LOGI("MessageType: %d", requestInfo->info.type);
968 if (NULL != g_responseListenerObject)
970 char *cloneUri = NULL;
973 if (NULL != requestInfo->info.resourceUri)
975 len = strlen(requestInfo->info.resourceUri);
976 cloneUri = (char *)malloc(sizeof(char) * (len + 1));
978 if (NULL == cloneUri)
980 LOGE("cloneUri Out of memory");
981 free(g_remoteAddress);
985 memcpy(cloneUri, requestInfo->info.resourceUri, len + 1);
986 callback("Uri: ", cloneUri);
989 len = strlen(g_remoteAddress);
990 char *cloneRemoteAddress = (char *) malloc(sizeof(char) * (len + 1));
992 if (NULL == cloneRemoteAddress)
994 LOGE("cloneRemoteAddress Out of memory");
995 free(g_remoteAddress);
1000 memcpy(cloneRemoteAddress, g_remoteAddress, len + 1);
1002 callback("Remote Address: ", cloneRemoteAddress);
1003 free(cloneRemoteAddress);
1004 free(g_remoteAddress);
1006 char portInfo[PORT_LENGTH] = { 0, };
1007 sprintf(portInfo, "%d", object->port);
1008 callback("Remote Port: ", portInfo);
1010 //clone g_clientEndpoint
1011 g_clientEndpoint = (CAEndpoint_t *) malloc(sizeof(CAEndpoint_t));
1012 if (NULL == g_clientEndpoint)
1014 LOGE("g_clientEndpoint Out of memory");
1018 memcpy(g_clientEndpoint, object, sizeof(CAEndpoint_t));
1020 if (NULL != cloneUri)
1022 len = strlen(cloneUri);
1023 g_resourceUri = (char *) malloc(sizeof(char) * (len + 1));
1024 if (NULL == g_resourceUri)
1026 LOGE("g_clientEndpoint->resourceUri Out of memory");
1027 free(g_clientEndpoint);
1031 memcpy(g_resourceUri, cloneUri, len + 1);
1034 //clone g_clientToken
1035 len = requestInfo->info.tokenLength;
1037 g_clientToken = (char *) malloc(sizeof(char) * len);
1038 if (NULL == g_clientToken)
1040 LOGE("g_clientToken Out of memory");
1041 free(g_clientEndpoint);
1045 if (NULL != requestInfo->info.token)
1047 memcpy(g_clientToken, requestInfo->info.token, len);
1048 g_clientTokenLength = len;
1052 //clone g_clientMsgId
1053 g_clientMsgId = requestInfo->info.messageId;
1055 if (NULL != requestInfo->info.payload && requestInfo->info.payloadSize > 0)
1057 len = requestInfo->info.payloadSize;
1058 char *clonePayload = (char *) malloc(len + 1);
1059 if (NULL == clonePayload)
1061 LOGE("clonePayload Out of memory");
1062 free(g_clientEndpoint);
1066 memcpy(clonePayload, requestInfo->info.payload, len);
1067 clonePayload[len] = '\0';
1069 if (len > BIG_PAYLOAD_LENGTH)
1071 saveFile(clonePayload, len);
1075 callback("Data: ", clonePayload);
1081 if (requestInfo->info.options)
1083 uint32_t len = requestInfo->info.numOptions;
1086 LOGI("Option count: %d", requestInfo->info.numOptions);
1088 for (i = 0; i < len; i++)
1090 LOGI("Option %d", i + 1);
1091 LOGI("ID : %d", requestInfo->info.options[i].optionID);
1092 LOGI("Data[%d]: %s", requestInfo->info.options[i].optionLength,
1093 requestInfo->info.options[i].optionData);
1095 if (NULL != g_responseListenerObject)
1097 char optionInfo[OPTION_INFO_LENGTH] = { 0, };
1098 sprintf(optionInfo, "Num[%d] - ID : %d, Option Length : %d", i + 1,
1099 requestInfo->info.options[i].optionID,
1100 requestInfo->info.options[i].optionLength);
1102 callback("Option info: ", optionInfo);
1104 size_t optionDataLen = strlen(requestInfo->info.options[i].optionData);
1105 char *cloneOptionData = (char *) malloc(sizeof(char) * (optionDataLen + 1));
1106 if (NULL == cloneOptionData)
1108 LOGE("cloneOptionData Out of memory");
1109 free(g_clientEndpoint);
1113 memcpy(cloneOptionData, requestInfo->info.options[i].optionData,
1116 callback("Option Data: ", cloneOptionData);
1117 free(cloneOptionData);
1121 LOGI("############################################################");
1123 //Check if this has secure communication information
1124 if (requestInfo->info.payload && CA_ADAPTER_IP == object->adapter)
1126 uint32_t securePort = get_secure_information(requestInfo->info.payload);
1127 if (0 < securePort) //Set the remote endpoint secure details and send response
1129 LOGI("This is secure resource...");
1131 CAEndpoint_t *endpoint = NULL;
1132 if (CA_STATUS_OK != CACreateEndpoint(CA_SECURE,
1133 object->adapter, object->addr, securePort, &endpoint))
1135 LOGE("Failed to create duplicate of remote endpoint!");
1143 void response_handler(const CAEndpoint_t* object, const CAResponseInfo_t* responseInfo)
1145 if (!object || !responseInfo)
1147 LOGE("Invalid input parameter");
1151 CAResult_t res = get_remote_address(object->addr);
1152 if (CA_STATUS_OK != res)
1157 LOGI("##########Received response from remote device #############");
1158 LOGI("Uri: %s", responseInfo->info.resourceUri);
1159 LOGI("Remote Address: %s", g_remoteAddress);
1160 LOGI("Remote Port: %d", object->port);
1161 LOGI("response result: %d", responseInfo->result);
1162 LOGI("Data: %s", responseInfo->info.payload);
1163 LOGI("Token: %s", responseInfo->info.token);
1164 LOGI("MessageType: %d", responseInfo->info.type);
1166 if (NULL != g_responseListenerObject)
1170 if (NULL != responseInfo->info.resourceUri)
1172 len = strlen(responseInfo->info.resourceUri);
1173 char *cloneUri = (char *) malloc(sizeof(char) * (len + 1));
1175 if (NULL == cloneUri)
1177 LOGE("cloneUri Out of memory");
1178 free(g_remoteAddress);
1182 memcpy(cloneUri, responseInfo->info.resourceUri, len + 1);
1184 callback("Uri: ", cloneUri);
1188 len = strlen(g_remoteAddress);
1189 char *cloneRemoteAddress = (char *) malloc(sizeof(char) * (len + 1));
1191 if (NULL == cloneRemoteAddress)
1193 LOGE("cloneRemoteAddress Out of memory");
1194 free(g_remoteAddress);
1198 memcpy(cloneRemoteAddress, g_remoteAddress, len + 1);
1200 callback("Remote Address: ", cloneRemoteAddress);
1201 free(cloneRemoteAddress);
1202 free(g_remoteAddress);
1204 char portInfo[PORT_LENGTH] = { 0, };
1205 sprintf(portInfo, "%d", object->port);
1206 callback("Remote Port: ", portInfo);
1208 if (NULL != responseInfo->info.payload && responseInfo->info.payloadSize)
1210 len = responseInfo->info.payloadSize;
1211 char *clonePayload = (char *) malloc(len + 1);
1212 if (NULL == clonePayload)
1214 LOGE("clonePayload Out of memory");
1218 memcpy(clonePayload, responseInfo->info.payload, len);
1219 clonePayload[len] = '\0';
1221 if (len > BIG_PAYLOAD_LENGTH)
1223 saveFile(clonePayload, len);
1227 callback("Data: ", clonePayload);
1233 if (responseInfo->info.options)
1235 uint32_t len = responseInfo->info.numOptions;
1237 for (i = 0; i < len; i++)
1239 LOGI("Option %d", i + 1);
1240 LOGI("ID : %d", responseInfo->info.options[i].optionID);
1241 LOGI("Data[%d]: %s", responseInfo->info.options[i].optionLength,
1242 responseInfo->info.options[i].optionData);
1244 if (NULL != g_responseListenerObject)
1246 char optionInfo[OPTION_INFO_LENGTH] = { 0, };
1247 sprintf(optionInfo, "Num[%d] - ID : %d, Option Length : %d", i + 1,
1248 responseInfo->info.options[i].optionID,
1249 responseInfo->info.options[i].optionLength);
1251 callback("Option info: ", optionInfo);
1253 size_t optionDataLen = strlen(responseInfo->info.options[i].optionData);
1254 char *cloneOptionData = (char *) malloc(sizeof(char) * (optionDataLen + 1));
1255 if (NULL == cloneOptionData)
1257 LOGE("cloneOptionData Out of memory");
1260 memcpy(cloneOptionData, responseInfo->info.options[i].optionData,
1262 callback("Option Data: ", cloneOptionData);
1263 free(cloneOptionData);
1267 LOGI("############################################################");
1269 //Check if this has secure communication information
1270 if (responseInfo->info.payload && CA_ADAPTER_IP == object->adapter)
1272 uint32_t securePort = get_secure_information(responseInfo->info.payload);
1273 if (0 < securePort) //Set the remote endpoint secure details and send response
1275 LOGI("This is secure resource...");
1280 void error_handler(const CAEndpoint_t *rep, const CAErrorInfo_t* errorInfo)
1282 LOGI("+++++++++++++++++++++++++++++++++++ErrorInfo+++++++++++++++++++++++++++++++++++");
1286 LOGI("Error Handler, Adapter Type : %d", rep->adapter);
1287 LOGI("Error Handler, Adapter Type : %s", rep->addr);
1292 const CAInfo_t *info = &errorInfo->info;
1293 LOGI("Error Handler, ErrorInfo :");
1294 LOGI("Error Handler result : %d", errorInfo->result);
1295 LOGI("Error Handler token : %s", info->token);
1296 LOGI("Error Handler messageId : %d", (uint16_t) info->messageId);
1297 LOGI("Error Handler resourceUri : %s", info->resourceUri);
1298 LOGI("Error Handler type : %d", info->type);
1299 LOGI("Error Handler payload : %s", info->payload);
1301 if(CA_ADAPTER_NOT_ENABLED == errorInfo->result)
1303 LOGE("CA_ADAPTER_NOT_ENABLED, enable the adapter");
1305 else if(CA_SEND_FAILED == errorInfo->result)
1307 LOGE("CA_SEND_FAILED, unable to send the message, check parameters");
1309 else if(CA_MEMORY_ALLOC_FAILED == errorInfo->result)
1311 LOGE("CA_MEMORY_ALLOC_FAILED, insufficient memory");
1313 else if(CA_SOCKET_OPERATION_FAILED == errorInfo->result)
1315 LOGE("CA_SOCKET_OPERATION_FAILED, socket operation failed");
1317 else if(CA_STATUS_FAILED == errorInfo->result)
1319 LOGE("CA_STATUS_FAILED, message could not be delivered, internal error");
1322 LOGI("++++++++++++++++++++++++++++++++End of ErrorInfo++++++++++++++++++++++++++++++++");
1327 void get_resource_uri(const char *URI, char *resourceURI, int32_t length)
1329 const char *startPos = URI;
1330 const char *temp = strstr(URI, "://");
1333 startPos = strchr(temp + 3, '/');
1336 LOGE("Resource URI is missing");
1341 const char *endPos = strchr(startPos, '?');
1344 endPos = URI + strlen(URI);
1348 if (endPos - startPos <= length)
1350 memcpy(resourceURI, startPos + 1, endPos - startPos);
1353 LOGI("URI: %s, ResourceURI: %s", URI, resourceURI);
1356 uint32_t get_secure_information(CAPayload_t payLoad)
1358 LOGI("entering get_secure_information");
1362 LOGE("Payload is NULL");
1366 const char *subString = NULL;
1367 if (NULL == (subString = strstr((const char *) payLoad, "\"sec\":1")))
1369 LOGE("This is not secure resource");
1373 if (NULL == (subString = strstr((const char *) payLoad, "\"port\":")))
1375 LOGE("This secure resource does not have port information");
1379 const char *startPos = strstr(subString, ":");
1382 LOGE("Parsing failed !");
1386 const char *endPos = strstr(startPos, "}");
1389 LOGE("Parsing failed !");
1393 char portStr[6] = { 0 };
1394 memcpy(portStr, startPos + 1, (endPos - 1) - startPos);
1396 LOGI("secured port is: %s", portStr);
1397 return atoi(portStr);
1400 CAResult_t get_network_type(uint32_t selectedNetwork)
1403 uint32_t number = selectedNetwork;
1405 if (!(number & 0xf))
1407 return CA_NOT_SUPPORTED;
1409 if (number & CA_ADAPTER_IP)
1411 g_selectedNwType = CA_ADAPTER_IP;
1412 return CA_STATUS_OK;
1414 if (number & CA_ADAPTER_RFCOMM_BTEDR)
1416 g_selectedNwType = CA_ADAPTER_RFCOMM_BTEDR;
1417 return CA_STATUS_OK;
1419 if (number & CA_ADAPTER_GATT_BTLE)
1421 g_selectedNwType = CA_ADAPTER_GATT_BTLE;
1422 return CA_STATUS_OK;
1425 return CA_NOT_SUPPORTED;
1428 void callback(char *subject, char *receivedData)
1430 bool isAttached = false;
1433 if (!g_responseListenerObject)
1435 LOGE("g_responseListenerObject is NULL, cannot have callback");
1439 jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
1442 LOGI("Could not get JNIEnv pointer");
1443 res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
1447 LOGE("AttachCurrentThread has failed");
1453 jclass cls = (*env)->GetObjectClass(env, g_responseListenerObject);
1456 LOGE("could not get class");
1460 jmethodID mid = (*env)->GetMethodID(env, cls, "OnResponseReceived",
1461 "(Ljava/lang/String;Ljava/lang/String;)V");
1464 LOGE("could not get Method ID");
1468 jstring jsubject = (*env)->NewStringUTF(env, (char*) subject);
1471 LOGE("NewStringUTF failed");
1475 jstring jreceivedData = (*env)->NewStringUTF(env, (char*) receivedData);
1478 LOGE("NewStringUTF failed");
1482 (*env)->CallVoidMethod(env, g_responseListenerObject, mid, jsubject, jreceivedData);
1487 (*g_jvm)->DetachCurrentThread(g_jvm);
1488 LOGI("DetachCurrentThread");
1492 CAResult_t get_remote_address(const char *address)
1494 uint32_t len = strlen(address);
1496 g_remoteAddress = (char *)malloc(sizeof (char) * (len + 1));
1497 if (NULL == g_remoteAddress)
1499 LOGE("g_remoteAddress Out of memory");
1500 return CA_MEMORY_ALLOC_FAILED;
1503 memcpy(g_remoteAddress, address, len + 1);
1505 return CA_STATUS_OK;
1509 void parsing_coap_uri(const char* uri, addressSet_t* address, CATransportFlags_t *flags)
1511 if (NULL == uri || NULL == address)
1513 LOGE("parameter is null");
1519 uint8_t startIndex = 0;
1520 if (strncmp(COAPS_PREFIX, uri, COAPS_PREFIX_LEN) == 0)
1522 LOGI("uri has '%s' prefix", COAPS_PREFIX);
1523 startIndex = COAPS_PREFIX_LEN;
1526 else if (strncmp(COAP_PREFIX, uri, COAP_PREFIX_LEN) == 0)
1528 LOGI("uri has '%s' prefix", COAP_PREFIX);
1529 startIndex = COAP_PREFIX_LEN;
1533 // #2. copy uri for parse
1534 size_t len = strlen(uri) - startIndex;
1538 LOGE("uri length is 0!");
1542 char *cloneUri = (char *) calloc(len + 1, sizeof(char));
1543 if (NULL == cloneUri)
1545 LOGE("Out of memory");
1549 OICStrcpy(cloneUri, len+1, &uri[startIndex]);
1552 //filter out the resource uri
1553 char *pUrl = strtok_r(cloneUri, "/", &pstr);
1557 LOGI("pAddress : %s", pUrl);
1558 int res = get_address_set(pUrl, address);
1561 LOGE("address parse error");
1568 LOGE("strtok_r error, could not get the address");
1574 int get_address_set(const char *pAddress, addressSet_t* outAddress)
1576 if (NULL == pAddress || NULL == outAddress)
1578 LOGE("parameter is null");
1582 size_t len = strlen(pAddress);
1586 for (size_t i = 0; i < len; i++)
1588 if (pAddress[i] == '.')
1593 // found port number start index
1594 if (isIp && pAddress[i] == ':')
1603 if(ipLen && (ipLen < sizeof(outAddress->ipAddress)))
1605 strncpy(outAddress->ipAddress, pAddress, ipLen);
1606 outAddress->ipAddress[ipLen] = '\0';
1608 else if (!ipLen && (len < sizeof(outAddress->ipAddress)))
1610 strncpy(outAddress->ipAddress, pAddress, len);
1611 outAddress->ipAddress[len] = '\0';
1615 LOGE("IP Address too long: %d", ipLen==0 ? len : ipLen);
1621 outAddress->port = atoi(pAddress + ipLen + 1);
1626 strncpy(outAddress->ipAddress, pAddress, len);
1627 outAddress->ipAddress[len] = '\0';
1633 void delete_global_references(JNIEnv *env, jobject obj)
1635 LOGI("delete_global_references");
1638 LOGI("Invalid input parameter");
1642 (*env)->DeleteGlobalRef(env, g_responseListenerObject);
1646 bool read_file(const char* name, char** bytes, size_t* length)
1650 LOGE("parameter is null");
1659 file = fopen(name, "rt");
1662 fprintf(stderr, "Unable to open file %s", name);
1667 fseek(file, 0, SEEK_END);
1668 fileLen = ftell(file);
1669 fseek(file, 0, SEEK_SET);
1671 LOGI("file size: %d", fileLen);
1674 buffer = calloc(1, sizeof(char) * fileLen + 1);
1677 fprintf(stderr, "Memory error!");
1682 // Read file contents into buffer
1683 fread(buffer, fileLen, 1, file);
1686 LOGI("file bytes: %s", buffer);
1694 void saveFile(const char *payload, size_t payloadSize)
1697 uint32_t day = gettodaydate();
1700 time_t current_time;
1701 struct tm * time_info;
1702 char timeString[RECEIVED_FILE_NAME_PREFIX_LENGTH];
1704 time(¤t_time);
1705 time_info = localtime(¤t_time);
1707 strftime(timeString, sizeof(timeString), "%H%M%S", time_info);
1709 uint32_t path_length = strlen(RECEIVED_FILE_PATH) + RECEIVED_FILE_NAME_LENGTH + 1;
1710 char* path = calloc(1, sizeof(char) * path_length);
1713 sprintf(path, RECEIVED_FILE_PATH, day, timeString);
1714 LOGI("received file path: %s", path);
1716 FILE *fp = fopen(path, "wt");
1717 fwrite(payload, 1, payloadSize, fp);
1720 callback("File Path: ", path);
1724 LOGE("path Out of memory");
1728 uint32_t gettodaydate()
1735 date = localtime(&clock);
1736 ldate = date->tm_year * 100000;
1737 ldate += (date->tm_mon + 1) * 1000;
1738 ldate += date->tm_mday * 10;
1739 ldate += date->tm_wday;