X-Git-Url: http://review.tizen.org/git/?a=blobdiff_plain;f=resource%2Fcsdk%2Fconnectivity%2Fsamples%2Fandroid%2Fcasample%2FsampleService%2Fsrc%2Fmain%2Fjni%2FResourceModel.c;h=56f1ba6eab85b77937939de2e1196d9c8e7072be;hb=e659ed970cb179eab4aa8bbe606b8fefab17bb91;hp=9f89c262497441e87415d711b3bc1242d99b673a;hpb=c44033c3918fdbcf8089b40444eac46187994071;p=platform%2Fupstream%2Fiotivity.git diff --git a/resource/csdk/connectivity/samples/android/casample/sampleService/src/main/jni/ResourceModel.c b/resource/csdk/connectivity/samples/android/casample/sampleService/src/main/jni/ResourceModel.c index 9f89c26..56f1ba6 100644 --- a/resource/csdk/connectivity/samples/android/casample/sampleService/src/main/jni/ResourceModel.c +++ b/resource/csdk/connectivity/samples/android/casample/sampleService/src/main/jni/ResourceModel.c @@ -4,9 +4,12 @@ #include #include #include +#include #include "cainterface.h" #include "cacommon.h" +#include "caadapterutils.h" +#include "oic_string.h" #include "org_iotivity_ca_service_RMInterface.h" @@ -14,21 +17,20 @@ #define LOGI(...) __android_log_print(ANDROID_LOG_INFO, LOG_TAG, __VA_ARGS__) #define LOGE(...) __android_log_print(ANDROID_LOG_ERROR, LOG_TAG, __VA_ARGS__) -/** - * @def RS_IDENTITY - * @brief - */ -#define IDENTITY ("1111111111111111") -/* @def RS_CLIENT_PSK - * @brief - */ -#define RS_CLIENT_PSK ("AAAAAAAAAAAAAAAA") +// Iotivity Device Identity. +const unsigned char IDENTITY[] = ("1111111111111111"); + +// PSK between this device and peer device. +const unsigned char RS_CLIENT_PSK[] = ("AAAAAAAAAAAAAAAA"); #define PORT_LENGTH 5 #define SECURE_DEFAULT_PORT 5684 #define RESOURCE_URI_LENGTH 14 #define OPTION_INFO_LENGTH 1024 #define NETWORK_INFO_LENGTH 1024 +#define BIG_PAYLOAD_LENGTH 1024 +#define RECEIVED_FILE_NAME_PREFIX_LENGTH 7 +#define RECEIVED_FILE_NAME_LENGTH 14 typedef struct { @@ -36,15 +38,20 @@ typedef struct uint16_t port; } addressSet_t; -void request_handler(const CAEndpoint_t* object, const CARequestInfo_t* requestInfo); -void response_handler(const CAEndpoint_t* object, const CAResponseInfo_t* responseInfo); -void error_handler(const CAEndpoint_t *object, const CAErrorInfo_t* errorInfo); -void get_resource_uri(const char *URI, char *resourceURI, uint32_t length); -uint32_t get_secure_information(CAPayload_t payLoad); -CAResult_t get_network_type(uint32_t selectedNetwork); -void callback(char *subject, char *receivedData); -CAResult_t get_remote_address(CATransportAdapter_t transportType, const char *address); -void parsing_coap_uri(const char* uri, addressSet_t* address, CATransportFlags_t *flags); +static void request_handler(const CAEndpoint_t* object, const CARequestInfo_t* requestInfo); +static void response_handler(const CAEndpoint_t* object, const CAResponseInfo_t* responseInfo); +static void error_handler(const CAEndpoint_t *object, const CAErrorInfo_t* errorInfo); +static void get_resource_uri(const char *URI, char *resourceURI, int32_t length); +static uint32_t get_secure_information(CAPayload_t payLoad); +static CAResult_t get_network_type(uint32_t selectedNetwork, CATransportFlags_t *flags); +static void callback(char *subject, char *receivedData); +static CAResult_t get_remote_address(const char *address); +static void parsing_coap_uri(const char* uri, addressSet_t* address, CATransportFlags_t *flags); +static void delete_global_references(JNIEnv *env, jobject obj); +static int get_address_set(const char *pAddress, addressSet_t* outAddress); +bool read_file(const char* name, char** bytes, size_t* length); +uint32_t gettodaydate(); +void saveFile(const char *payload, size_t payloadSize); uint16_t g_localSecurePort = SECURE_DEFAULT_PORT; CATransportAdapter_t g_selectedNwType = CA_ADAPTER_IP; @@ -53,8 +60,13 @@ static uint8_t g_lastRequestTokenLength = 0; static const char COAP_PREFIX[] = "coap://"; static const char COAPS_PREFIX[] = "coaps://"; +static const char COAP_TCP_PREFIX[] = "coap+tcp://"; + static const uint16_t COAP_PREFIX_LEN = sizeof(COAP_PREFIX) - 1; static const uint16_t COAPS_PREFIX_LEN = sizeof(COAPS_PREFIX) - 1; +static const uint16_t COAP_TCP_PREFIX_LEN = sizeof(COAP_TCP_PREFIX) - 1; + +static const char RECEIVED_FILE_PATH[] = "/storage/emulated/0/Download/%d%s.txt"; static const char SECURE_INFO_DATA[] = "{\"oc\":[{\"href\":\"%s\",\"prop\":{\"rt\":[\"core.led\"]," @@ -81,89 +93,77 @@ Java_org_iotivity_ca_service_RMInterface_setNativeResponseListener(JNIEnv *env, jobject listener) { LOGI("setNativeResponseListener"); - g_responseListenerObject = (*env)->NewGlobalRef(env, obj); -} - -#ifdef __WITH_DTLS__ -static CADtlsPskCredsBlob_t *pskCredsBlob = NULL; - -void clearDtlsCredentialInfo() -{ - LOGI("clearDtlsCredentialInfo IN"); - if (pskCredsBlob) + if (!env || !obj || !listener) { - // Initialize sensitive data to zeroes before freeing. - if (NULL != pskCredsBlob->creds) - { - memset(pskCredsBlob->creds, 0, sizeof(OCDtlsPskCreds)*(pskCredsBlob->num)); - free(pskCredsBlob->creds); - } - - memset(pskCredsBlob, 0, sizeof(CADtlsPskCredsBlob_t)); - free(pskCredsBlob); - pskCredsBlob = NULL; + LOGI("Invalid input parameter"); + return; } - LOGI("clearDtlsCredentialInfo OUT"); + + g_responseListenerObject = (*env)->NewGlobalRef(env, listener); } +#ifdef __WITH_DTLS__ // Internal API. Invoked by OC stack to retrieve credentials from this module -void CAGetDtlsPskCredentials(CADtlsPskCredsBlob_t **credInfo) +int32_t CAGetDtlsPskCredentials( CADtlsPskCredType_t type, + const unsigned char *desc, size_t desc_len, + unsigned char *result, size_t result_length) { LOGI("CAGetDtlsPskCredentials IN"); - *credInfo = (CADtlsPskCredsBlob_t *) malloc(sizeof(CADtlsPskCredsBlob_t)); - if (NULL == *credInfo) + + int32_t ret = -1; + + if (NULL == result) { - LOGE("Failed to allocate credential blob."); - return; + return ret; } - int16_t credLen = sizeof(OCDtlsPskCreds) * (pskCredsBlob->num); - (*credInfo)->creds = (OCDtlsPskCreds *) malloc(credLen); - if (NULL == (*credInfo)->creds) + switch (type) { - LOGE("Failed to allocate crentials."); - free(*credInfo); - *credInfo = NULL; - return; - } + case CA_DTLS_PSK_HINT: + case CA_DTLS_PSK_IDENTITY: - memcpy((*credInfo)->identity, pskCredsBlob->identity, DTLS_PSK_ID_LEN); - (*credInfo)->num = pskCredsBlob->num; - memcpy((*credInfo)->creds, pskCredsBlob->creds, credLen); + if (result_length < sizeof(IDENTITY)) + { + LOGE("ERROR : Wrong value for result for storing IDENTITY"); + return ret; + } - LOGI("CAGetDtlsPskCredentials OUT"); -} + memcpy(result, IDENTITY, sizeof(IDENTITY)); + ret = sizeof(IDENTITY); + break; -CAResult_t SetCredentials() -{ - LOGI("SetCredentials IN"); - pskCredsBlob = (CADtlsPskCredsBlob_t *)malloc(sizeof(CADtlsPskCredsBlob_t)); - if (NULL == pskCredsBlob) - { - LOGE("Memory allocation failed!"); - return CA_MEMORY_ALLOC_FAILED; - } - memcpy(pskCredsBlob->identity, IDENTITY, DTLS_PSK_ID_LEN); + case CA_DTLS_PSK_KEY: - pskCredsBlob->num = 1; + if ((desc_len == sizeof(IDENTITY)) && + memcmp(desc, IDENTITY, sizeof(IDENTITY)) == 0) + { + if (result_length < sizeof(RS_CLIENT_PSK)) + { + LOGE("ERROR : Wrong value for result for storing RS_CLIENT_PSK"); + return ret; + } - pskCredsBlob->creds = (OCDtlsPskCreds *)malloc(sizeof(OCDtlsPskCreds) *(pskCredsBlob->num)); - if (NULL == pskCredsBlob->creds) - { - LOGE("Memory allocation failed!"); - return CA_MEMORY_ALLOC_FAILED; + memcpy(result, RS_CLIENT_PSK, sizeof(RS_CLIENT_PSK)); + ret = sizeof(RS_CLIENT_PSK); + } + break; + + default: + + LOGE("Wrong value passed for PSK_CRED_TYPE."); + ret = -1; } - memcpy(pskCredsBlob->creds[0].id, IDENTITY, DTLS_PSK_ID_LEN); - memcpy(pskCredsBlob->creds[0].psk, RS_CLIENT_PSK, DTLS_PSK_PSK_LEN); - LOGI("SetCredentials OUT"); - return CA_STATUS_OK; + LOGI("CAGetDtlsPskCredentials OUT\n"); + return ret; } + #endif JNIEXPORT jint JNI_OnLoad(JavaVM *jvm, void *reserved) { LOGI("JNI_OnLoad"); + (void)reserved; JNIEnv* env; if (JNI_OK != (*jvm)->GetEnv(jvm, (void**) &env, JNI_VERSION_1_6)) @@ -180,6 +180,7 @@ JNIEXPORT jint JNI_OnLoad(JavaVM *jvm, void *reserved) void JNI_OnUnload(JavaVM *jvm, void *reserved) { LOGI("JNI_OnUnload"); + (void)reserved; JNIEnv* env; if (JNI_OK != (*jvm)->GetEnv(jvm, (void**) &env, JNI_VERSION_1_6)) @@ -191,12 +192,19 @@ void JNI_OnUnload(JavaVM *jvm, void *reserved) } JNIEXPORT void JNICALL -Java_org_iotivity_ca_service_RMInterface_RMInitialize(JNIEnv *env, jobject obj, jobject context) +Java_org_iotivity_ca_service_RMInterface_RMInitialize(JNIEnv *env, jobject obj, jobject context, + jobject activity) { LOGI("RMInitialize"); + if (!env || !obj || !context || !activity) + { + LOGI("Invalid input parameter"); + return; + } //Currently set context for Android Platform CANativeJNISetContext(env, context); + CANativeSetActivity(env, activity); CAResult_t res = CAInitialize(); @@ -206,12 +214,6 @@ Java_org_iotivity_ca_service_RMInterface_RMInitialize(JNIEnv *env, jobject obj, } #ifdef __WITH_DTLS__ - if (CA_STATUS_OK != SetCredentials()) - { - LOGE("SetCredentials failed"); - return; - } - res = CARegisterDTLSCredentialsHandler(CAGetDtlsPskCredentials); if(CA_STATUS_OK != res) { @@ -225,14 +227,26 @@ JNIEXPORT void JNICALL Java_org_iotivity_ca_service_RMInterface_RMTerminate(JNIEnv *env, jobject obj) { LOGI("RMTerminate"); + if (!env || !obj) + { + LOGI("Invalid input parameter"); + return; + } + CADestroyToken(g_lastRequestToken); CATerminate(); + delete_global_references(env, obj); } JNIEXPORT void JNICALL Java_org_iotivity_ca_service_RMInterface_RMStartListeningServer(JNIEnv *env, jobject obj) { LOGI("RMStartListeningServer"); + if (!env || !obj) + { + LOGI("Invalid input parameter"); + return; + } if (CA_STATUS_OK != CAStartListeningServer()) { @@ -244,6 +258,11 @@ JNIEXPORT void JNICALL Java_org_iotivity_ca_service_RMInterface_RMStartDiscoveryServer(JNIEnv *env, jobject obj) { LOGI("RMStartDiscoveryServer"); + if (!env || !obj) + { + LOGI("Invalid input parameter"); + return; + } if (CA_STATUS_OK != CAStartDiscoveryServer()) { @@ -255,6 +274,11 @@ JNIEXPORT void JNICALL Java_org_iotivity_ca_service_RMInterface_RMRegisterHandler(JNIEnv *env, jobject obj) { LOGI("RMRegisterHandler"); + if(!env || !obj) + { + LOGI("Invalid input parameter"); + return; + } CARegisterHandler(request_handler, response_handler, error_handler); } @@ -262,10 +286,24 @@ Java_org_iotivity_ca_service_RMInterface_RMRegisterHandler(JNIEnv *env, jobject JNIEXPORT void JNICALL Java_org_iotivity_ca_service_RMInterface_RMSendRequest(JNIEnv *env, jobject obj, jstring uri, jstring payload, jint selectedNetwork, - jint isSecured, jint msgType) + jint isSecured, jint msgType, + jboolean isBigData) { LOGI("selectedNetwork - %d", selectedNetwork); - CAResult_t res = get_network_type(selectedNetwork); + if (!env || !obj) + { + LOGI("Invalid input parameter"); + return; + } + + if (!uri) + { + LOGE("Invalid input parameter : uri"); + return; + } + + CATransportFlags_t flags = CA_DEFAULT_FLAGS; + CAResult_t res = get_network_type(selectedNetwork, &flags); if (CA_STATUS_OK != res) { return; @@ -274,13 +312,12 @@ Java_org_iotivity_ca_service_RMInterface_RMSendRequest(JNIEnv *env, jobject obj, const char* strUri = (*env)->GetStringUTFChars(env, uri, NULL); LOGI("RMSendRequest - %s", strUri); - CATransportFlags_t flags; - addressSet_t address = {}; + addressSet_t address = {{0}, 0}; parsing_coap_uri(strUri, &address, &flags); //create remote endpoint CAEndpoint_t* endpoint = NULL; - res = CACreateEndpoint(flags, g_selectedNwType, (const char*)address.ipAddress, + res = CACreateEndpoint(flags, g_selectedNwType, (const char*)(address.ipAddress), address.port, &endpoint); if (CA_STATUS_OK != res) { @@ -314,37 +351,77 @@ Java_org_iotivity_ca_service_RMInterface_RMSendRequest(JNIEnv *env, jobject obj, requestData.token = token; requestData.tokenLength = tokenLength; - if (1 == isSecured) + size_t payloadLength = 0; + if (isBigData) { - uint32_t length = sizeof(SECURE_INFO_DATA) + strlen(resourceURI); - requestData.payload = (CAPayload_t) malloc(length); - if (NULL == requestData.payload) + const char* path = NULL; + if (payload) { - LOGE("Memory allocation failed!"); - // destroy token - CADestroyToken(token); - // destroy remote endpoint - CADestroyEndpoint(endpoint); - return; + path = (*env)->GetStringUTFChars(env, payload, NULL); + if(path) + { + char* bigData = NULL; + bool result = read_file(path, &bigData, &payloadLength); + if (!result) + { + LOGE("read has failed"); + (*env)->ReleaseStringUTFChars(env, payload, path); + CADestroyToken(token); + CADestroyEndpoint(endpoint); + return; + } + (*env)->ReleaseStringUTFChars(env, payload, path); + + requestData.payload = (CAPayload_t) malloc(payloadLength); + if (NULL == requestData.payload) + { + LOGE("Memory allocation failed!"); + // destroy token + CADestroyToken(token); + // destroy remote endpoint + CADestroyEndpoint(endpoint); + return; + } + memcpy(requestData.payload, bigData, payloadLength); + requestData.payloadSize = payloadLength; + } } - snprintf(requestData.payload, length, SECURE_INFO_DATA, resourceURI, g_localSecurePort); - requestData.payloadSize = length; } else { - uint32_t length = sizeof(NORMAL_INFO_DATA) + strlen(resourceURI); - requestData.payload = (CAPayload_t) malloc(length); - if (NULL == requestData.payload) + if (isSecured) { - LOGE("Memory allocation failed!"); - // destroy token - CADestroyToken(token); - // destroy remote endpoint - CADestroyEndpoint(endpoint); - return; + payloadLength = sizeof(SECURE_INFO_DATA) + strlen(resourceURI); + requestData.payload = (CAPayload_t) malloc(payloadLength); + if (NULL == requestData.payload) + { + LOGE("Memory allocation failed!"); + // destroy token + CADestroyToken(token); + // destroy remote endpoint + CADestroyEndpoint(endpoint); + return; + } + snprintf((char *) requestData.payload, payloadLength, SECURE_INFO_DATA, + resourceURI, g_localSecurePort); + requestData.payloadSize = payloadLength; + } + else + { + payloadLength = sizeof(NORMAL_INFO_DATA) + strlen(resourceURI); + requestData.payload = (CAPayload_t) malloc(payloadLength); + if (NULL == requestData.payload) + { + LOGE("Memory allocation failed!"); + // destroy token + CADestroyToken(token); + // destroy remote endpoint + CADestroyEndpoint(endpoint); + return; + } + snprintf((char *) requestData.payload, payloadLength, NORMAL_INFO_DATA, resourceURI); + requestData.payloadSize = payloadLength; } - snprintf(requestData.payload, length, NORMAL_INFO_DATA, resourceURI); - requestData.payloadSize = length; } requestData.type = messageType; @@ -380,6 +457,7 @@ Java_org_iotivity_ca_service_RMInterface_RMSendRequest(JNIEnv *env, jobject obj, free(requestData.payload); free(requestData.resourceUri); + LOGI("send request success"); } JNIEXPORT void JNICALL @@ -387,15 +465,23 @@ Java_org_iotivity_ca_service_RMInterface_RMSendReqestToAll(JNIEnv *env, jobject jint selectedNetwork) { LOGI("selectedNetwork - %d", selectedNetwork); - CAResult_t res = get_network_type(selectedNetwork); + if (!env || !obj) + { + LOGI("Invalid input parameter"); + return; + } + + CATransportFlags_t flags = CA_DEFAULT_FLAGS; + CAResult_t res = get_network_type(selectedNetwork, &flags); if (CA_STATUS_OK != res) { + LOGE("Not supported network type"); return; } // create remote endpoint CAEndpoint_t *endpoint = NULL; - res = CACreateEndpoint(CA_IPV4, g_selectedNwType, NULL, 0, &endpoint); + res = CACreateEndpoint(flags, g_selectedNwType, NULL, 0, &endpoint); if (CA_STATUS_OK != res) { @@ -489,10 +575,16 @@ Java_org_iotivity_ca_service_RMInterface_RMSendResponse(JNIEnv *env, jobject obj jint responseValue) { LOGI("RMSendResponse"); + if (!env || !obj) + { + LOGI("Invalid input parameter"); + return; + } LOGI("selectedNetwork - %d", selectedNetwork); - CAResult_t res = get_network_type(selectedNetwork); + CATransportFlags_t flags = CA_DEFAULT_FLAGS; + CAResult_t res = get_network_type(selectedNetwork, &flags); if (CA_STATUS_OK != res) { LOGE("Not supported network type"); @@ -514,7 +606,13 @@ Java_org_iotivity_ca_service_RMInterface_RMSendResponse(JNIEnv *env, jobject obj CAResponseInfo_t responseInfo = { 0 }; - if (msgType != CA_MSG_RESET) + if (CA_MSG_RESET == msgType || + (CA_MSG_ACKNOWLEDGE == msgType && CA_EMPTY == responseValue)) + { + printf("RESET or ACK/EMPTY. there will be not payload/option\n"); + responseInfo.result = CA_EMPTY; + } + else { responseData.token = g_clientToken; responseData.tokenLength = g_clientTokenLength; @@ -524,23 +622,18 @@ Java_org_iotivity_ca_service_RMInterface_RMSendResponse(JNIEnv *env, jobject obj { uint32_t length = strlen(SECURE_INFO_DATA) + strlen(g_resourceUri) + 1; responseData.payload = (CAPayload_t) malloc(length); - sprintf(responseData.payload, SECURE_INFO_DATA, g_resourceUri, - g_localSecurePort); + snprintf((char *) responseData.payload, length, SECURE_INFO_DATA, + g_resourceUri, g_localSecurePort); responseData.payloadSize = length; } else { uint32_t length = strlen(NORMAL_INFO_DATA) + strlen(g_resourceUri) + 1; responseData.payload = (CAPayload_t) malloc(length); - sprintf(responseData.payload, NORMAL_INFO_DATA, g_resourceUri); + snprintf((char *) responseData.payload, length, NORMAL_INFO_DATA, g_resourceUri); responseData.payloadSize = length; } } - //msgType is RESET - else - { - responseInfo.result = CA_EMPTY; - } responseInfo.info = responseData; @@ -559,17 +652,34 @@ Java_org_iotivity_ca_service_RMInterface_RMSendResponse(JNIEnv *env, jobject obj // destroy remote endpoint CADestroyEndpoint(g_clientEndpoint); g_clientEndpoint = NULL; + free(responseData.payload); } JNIEXPORT void JNICALL Java_org_iotivity_ca_service_RMInterface_RMSendNotification(JNIEnv *env, jobject obj, jstring uri, jstring payload, jint selectedNetwork, - jint isSecured, jint msgType, - jint responseValue) + jint isSecured, jint msgType) { LOGI("selectedNetwork - %d", selectedNetwork); + if (!env || !obj) + { + LOGI("Invalid input parameter"); + return; + } - CAResult_t res = get_network_type(selectedNetwork); + if (!payload) + { + LOGE("payload is NULL"); + } + + if (!uri) + { + LOGE("Invalid input parameter : uri"); + return; + } + + CATransportFlags_t flags = CA_DEFAULT_FLAGS; + CAResult_t res = get_network_type(selectedNetwork, &flags); if (CA_STATUS_OK != res) { LOGE("Not supported network type"); @@ -579,8 +689,7 @@ Java_org_iotivity_ca_service_RMInterface_RMSendNotification(JNIEnv *env, jobject const char* strUri = (*env)->GetStringUTFChars(env, uri, NULL); LOGI("RMSendNotification - %s", strUri); - CATransportFlags_t flags; - addressSet_t address = {}; + addressSet_t address = {{0}, 0}; parsing_coap_uri(strUri, &address, &flags); //create remote endpoint @@ -615,11 +724,11 @@ Java_org_iotivity_ca_service_RMInterface_RMSendNotification(JNIEnv *env, jobject return; } - CAInfo_t responseData = { 0 }; - responseData.token = token; - responseData.tokenLength = tokenLength; - responseData.resourceUri = (CAURI_t) malloc(sizeof(resourceURI)); - if (NULL == responseData.resourceUri) + CAInfo_t requestData = { 0 }; + requestData.token = token; + requestData.tokenLength = tokenLength; + requestData.resourceUri = (CAURI_t) malloc(sizeof(resourceURI)); + if (NULL == requestData.resourceUri) { LOGE("Memory allocation failed!"); // destroy token @@ -628,13 +737,13 @@ Java_org_iotivity_ca_service_RMInterface_RMSendNotification(JNIEnv *env, jobject CADestroyEndpoint(endpoint); return; } - memcpy(responseData.resourceUri, resourceURI, sizeof(resourceURI)); + memcpy(requestData.resourceUri, resourceURI, sizeof(resourceURI)); if (1 == isSecured) { uint32_t length = sizeof(SECURE_INFO_DATA) + strlen(resourceURI); - responseData.payload = (CAPayload_t) malloc(length); - if (NULL == responseData.payload) + requestData.payload = (CAPayload_t) malloc(length); + if (NULL == requestData.payload) { LOGE("Memory allocation failed!"); // destroy token @@ -642,16 +751,18 @@ Java_org_iotivity_ca_service_RMInterface_RMSendNotification(JNIEnv *env, jobject // destroy remote endpoint CADestroyEndpoint(endpoint); - free(responseData.resourceUri); + free(requestData.resourceUri); return; } - snprintf(responseData.payload, length, SECURE_INFO_DATA, resourceURI, g_localSecurePort); + snprintf((char *) requestData.payload, length, SECURE_INFO_DATA, + resourceURI, g_localSecurePort); + requestData.payloadSize = length; } else { uint32_t length = sizeof(NORMAL_INFO_DATA) + strlen(resourceURI); - responseData.payload = (CAPayload_t) malloc(length); - if (NULL == responseData.payload) + requestData.payload = (CAPayload_t) malloc(length); + if (NULL == requestData.payload) { LOGE("Memory allocation failed!"); // destroy token @@ -659,20 +770,21 @@ Java_org_iotivity_ca_service_RMInterface_RMSendNotification(JNIEnv *env, jobject // destroy remote endpoint CADestroyEndpoint(endpoint); - free(responseData.resourceUri); + free(requestData.resourceUri); return; } - snprintf(responseData.payload, length, NORMAL_INFO_DATA, resourceURI); + snprintf((char *) requestData.payload, length, NORMAL_INFO_DATA, resourceURI); + requestData.payloadSize = length; } - responseData.type = messageType; + requestData.type = messageType; - CAResponseInfo_t responseInfo = { 0 }; - responseInfo.result = responseValue; - responseInfo.info = responseData; + CARequestInfo_t requestInfo = { 0 }; + requestInfo.method = CA_GET; + requestInfo.info = requestData; // send notification - if (CA_STATUS_OK != CASendNotification(endpoint, &responseInfo)) + if (CA_STATUS_OK != CASendRequest(endpoint, &requestInfo)) { LOGE("Could not send notification"); } @@ -685,8 +797,8 @@ Java_org_iotivity_ca_service_RMInterface_RMSendNotification(JNIEnv *env, jobject // destroy remote endpoint CADestroyEndpoint(endpoint); - free(responseData.payload); - free(responseData.resourceUri); + free(requestData.payload); + free(requestData.resourceUri); } JNIEXPORT void JNICALL @@ -694,6 +806,11 @@ Java_org_iotivity_ca_service_RMInterface_RMSelectNetwork(JNIEnv *env, jobject ob jint networkType) { LOGI("RMSelectNetwork Type : %d", networkType); + if (!env || !obj) + { + LOGI("Invalid input parameter"); + return; + } if (CA_STATUS_OK != CASelectNetwork(networkType)) { @@ -706,6 +823,11 @@ Java_org_iotivity_ca_service_RMInterface_RMUnSelectNetwork(JNIEnv *env, jobject jint networkType) { LOGI("RMUnSelectNetwork Type : %d", networkType); + if (!env || !obj) + { + LOGI("Invalid input parameter"); + return; + } if (CA_STATUS_OK != CAUnSelectNetwork(networkType)) { @@ -717,6 +839,11 @@ JNIEXPORT void JNICALL Java_org_iotivity_ca_service_RMInterface_RMGetNetworkInfomation(JNIEnv *env, jobject obj) { LOGI("RMGetNetworkInfomation"); + if (!env || !obj) + { + LOGI("Invalid input parameter"); + return; + } CAEndpoint_t *tempInfo = NULL; uint32_t tempSize = 0; @@ -736,7 +863,7 @@ Java_org_iotivity_ca_service_RMInterface_RMGetNetworkInfomation(JNIEnv *env, job uint32_t index; for (index = 0; index < tempSize; index++) { - res = get_remote_address(tempInfo[index].adapter, tempInfo[index].addr); + res = get_remote_address(tempInfo[index].addr); if (CA_STATUS_OK != res) { free(tempInfo); @@ -746,12 +873,12 @@ Java_org_iotivity_ca_service_RMInterface_RMGetNetworkInfomation(JNIEnv *env, job { char networkInfo[NETWORK_INFO_LENGTH]; LOGI("Type: %d", tempInfo[index].adapter); - sprintf(networkInfo, "%d",tempInfo[index].adapter); + snprintf(networkInfo, NETWORK_INFO_LENGTH, "%d",tempInfo[index].adapter); callback("Type :", networkInfo); if (CA_ADAPTER_IP == tempInfo[index].adapter) { LOGI("Port: %d", tempInfo[index].port); - sprintf(networkInfo, "%d",tempInfo[index].port); + snprintf(networkInfo, NETWORK_INFO_LENGTH, "%d",tempInfo[index].port); callback("Port: ", networkInfo); } LOGI("Secured: %d", (tempInfo[index].flags & CA_SECURE)); @@ -775,6 +902,11 @@ JNIEXPORT void JNICALL Java_org_iotivity_ca_service_RMInterface_RMHandleRequestResponse(JNIEnv *env, jobject obj) { LOGI("RMHandleRequestResponse"); + if(!env || !obj) + { + LOGI("Invalid input parameter"); + return; + } if (CA_STATUS_OK != CAHandleRequestResponse()) { @@ -805,7 +937,7 @@ void request_handler(const CAEndpoint_t* object, const CARequestInfo_t* requestI return; } - CAResult_t res = get_remote_address(object->adapter, object->addr); + CAResult_t res = get_remote_address(object->addr); if (CA_STATUS_OK != res) { return; @@ -859,7 +991,7 @@ void request_handler(const CAEndpoint_t* object, const CARequestInfo_t* requestI free(g_remoteAddress); char portInfo[PORT_LENGTH] = { 0, }; - sprintf(portInfo, "%d", object->port); + snprintf(portInfo, PORT_LENGTH, "%d", object->port); callback("Remote Port: ", portInfo); //clone g_clientEndpoint @@ -921,7 +1053,14 @@ void request_handler(const CAEndpoint_t* object, const CARequestInfo_t* requestI memcpy(clonePayload, requestInfo->info.payload, len); clonePayload[len] = '\0'; - callback("Data: ", clonePayload); + if (len > BIG_PAYLOAD_LENGTH) + { + saveFile(clonePayload, len); + } + else + { + callback("Data: ", clonePayload); + } free(clonePayload); } } @@ -943,9 +1082,10 @@ void request_handler(const CAEndpoint_t* object, const CARequestInfo_t* requestI if (NULL != g_responseListenerObject) { char optionInfo[OPTION_INFO_LENGTH] = { 0, }; - sprintf(optionInfo, "Num[%d] - ID : %d, Option Length : %d", i + 1, - requestInfo->info.options[i].optionID, - requestInfo->info.options[i].optionLength); + snprintf(optionInfo, OPTION_INFO_LENGTH, + "Num[%d] - ID : %d, Option Length : %d", i + 1, + requestInfo->info.options[i].optionID, + requestInfo->info.options[i].optionLength); callback("Option info: ", optionInfo); @@ -990,8 +1130,13 @@ void request_handler(const CAEndpoint_t* object, const CARequestInfo_t* requestI void response_handler(const CAEndpoint_t* object, const CAResponseInfo_t* responseInfo) { + if (!object || !responseInfo) + { + LOGE("Invalid input parameter"); + return; + } - CAResult_t res = get_remote_address(object->adapter, object->addr); + CAResult_t res = get_remote_address(object->addr); if (CA_STATUS_OK != res) { return; @@ -1045,7 +1190,7 @@ void response_handler(const CAEndpoint_t* object, const CAResponseInfo_t* respon free(g_remoteAddress); char portInfo[PORT_LENGTH] = { 0, }; - sprintf(portInfo, "%d", object->port); + snprintf(portInfo, PORT_LENGTH, "%d", object->port); callback("Remote Port: ", portInfo); if (NULL != responseInfo->info.payload && responseInfo->info.payloadSize) @@ -1061,7 +1206,14 @@ void response_handler(const CAEndpoint_t* object, const CAResponseInfo_t* respon memcpy(clonePayload, responseInfo->info.payload, len); clonePayload[len] = '\0'; - callback("Data: ", clonePayload); + if (len > BIG_PAYLOAD_LENGTH) + { + saveFile(clonePayload, len); + } + else + { + callback("Data: ", clonePayload); + } free(clonePayload); } } @@ -1080,9 +1232,10 @@ void response_handler(const CAEndpoint_t* object, const CAResponseInfo_t* respon if (NULL != g_responseListenerObject) { char optionInfo[OPTION_INFO_LENGTH] = { 0, }; - sprintf(optionInfo, "Num[%d] - ID : %d, Option Length : %d", i + 1, - responseInfo->info.options[i].optionID, - responseInfo->info.options[i].optionLength); + snprintf(optionInfo, OPTION_INFO_LENGTH, + "Num[%d] - ID : %d, Option Length : %d", i + 1, + responseInfo->info.options[i].optionID, + responseInfo->info.options[i].optionLength); callback("Option info: ", optionInfo); @@ -1115,9 +1268,15 @@ void response_handler(const CAEndpoint_t* object, const CAResponseInfo_t* respon void error_handler(const CAEndpoint_t *rep, const CAErrorInfo_t* errorInfo) { - printf("+++++++++++++++++++++++++++++++++++ErrorInfo+++++++++++++++++++++++++++++++++++"); + LOGI("+++++++++++++++++++++++++++++++++++ErrorInfo+++++++++++++++++++++++++++++++++++"); - if(errorInfo) + if (rep) + { + LOGI("Error Handler, Adapter Type : %d", rep->adapter); + LOGI("Error Handler, Adapter Type : %s", rep->addr); + } + + if (errorInfo) { const CAInfo_t *info = &errorInfo->info; LOGI("Error Handler, ErrorInfo :"); @@ -1154,7 +1313,7 @@ void error_handler(const CAEndpoint_t *rep, const CAErrorInfo_t* errorInfo) return; } -void get_resource_uri(const char *URI, char *resourceURI, uint32_t length) +void get_resource_uri(const char *URI, char *resourceURI, int32_t length) { const char *startPos = URI; const char *temp = strstr(URI, "://"); @@ -1194,13 +1353,13 @@ uint32_t get_secure_information(CAPayload_t payLoad) } const char *subString = NULL; - if (NULL == (subString = strstr(payLoad, "\"sec\":1"))) + if (NULL == (subString = strstr((const char *) payLoad, "\"sec\":1"))) { LOGE("This is not secure resource"); return -1; } - if (NULL == (subString = strstr(payLoad, "\"port\":"))) + if (NULL == (subString = strstr((const char *) payLoad, "\"port\":"))) { LOGE("This secure resource does not have port information"); return -1; @@ -1227,51 +1386,112 @@ uint32_t get_secure_information(CAPayload_t payLoad) return atoi(portStr); } -CAResult_t get_network_type(uint32_t selectedNetwork) +CAResult_t get_network_type(uint32_t selectedNetwork, CATransportFlags_t *flags) { uint32_t number = selectedNetwork; - if (!(number & 0xf)) + if (!(number & CA_ALL_ADAPTERS)) { + LOGE("get_network_type Out of range"); return CA_NOT_SUPPORTED; } - if (number & CA_ADAPTER_IP) + if ((number & CA_ADAPTER_IP) == CA_ADAPTER_IP) { + *flags = CA_IPV4; g_selectedNwType = CA_ADAPTER_IP; return CA_STATUS_OK; } - if (number & CA_ADAPTER_RFCOMM_BTEDR) + if ((number & CA_ADAPTER_RFCOMM_BTEDR) == CA_ADAPTER_RFCOMM_BTEDR) { g_selectedNwType = CA_ADAPTER_RFCOMM_BTEDR; return CA_STATUS_OK; } - if (number & CA_ADAPTER_GATT_BTLE) + if ((number & CA_ADAPTER_GATT_BTLE) == CA_ADAPTER_GATT_BTLE) { g_selectedNwType = CA_ADAPTER_GATT_BTLE; return CA_STATUS_OK; } + if ((number & CA_ADAPTER_TCP) == CA_ADAPTER_TCP) + { + g_selectedNwType = CA_ADAPTER_TCP; + return CA_STATUS_OK; + } + if ((number & CA_ADAPTER_NFC) == CA_ADAPTER_NFC) + { + g_selectedNwType = CA_ADAPTER_NFC; + return CA_STATUS_OK; + } - return CA_NOT_SUPPORTED; + LOGE("Invalid transport"); + return CA_NOT_SUPPORTED; } void callback(char *subject, char *receivedData) { - JNIEnv* env = NULL; - uint32_t status = (*g_jvm)->GetEnv(g_jvm, (void **) &env, JNI_VERSION_1_6); - uint32_t res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL); + bool isAttached = false; + JNIEnv* env; + + if (!g_responseListenerObject) + { + LOGE("g_responseListenerObject is NULL, cannot have callback"); + return; + } + + jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6); + if (JNI_OK != res) + { + LOGI("Could not get JNIEnv pointer"); + res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL); + + if (JNI_OK != res) + { + LOGE("AttachCurrentThread has failed"); + return; + } + isAttached = true; + } jclass cls = (*env)->GetObjectClass(env, g_responseListenerObject); + if (!cls) + { + LOGE("could not get class"); + goto detach_thread; + } + jmethodID mid = (*env)->GetMethodID(env, cls, "OnResponseReceived", "(Ljava/lang/String;Ljava/lang/String;)V"); + if (!mid) + { + LOGE("could not get Method ID"); + goto detach_thread; + } jstring jsubject = (*env)->NewStringUTF(env, (char*) subject); + if (!jsubject) + { + LOGE("NewStringUTF failed"); + goto detach_thread; + } + jstring jreceivedData = (*env)->NewStringUTF(env, (char*) receivedData); + if (!jreceivedData) + { + LOGE("NewStringUTF failed"); + goto detach_thread; + } + (*env)->CallVoidMethod(env, g_responseListenerObject, mid, jsubject, jreceivedData); +detach_thread : + if (isAttached) + { + (*g_jvm)->DetachCurrentThread(g_jvm); + LOGI("DetachCurrentThread"); + } } -CAResult_t get_remote_address(CATransportAdapter_t transportType, const char *address) +CAResult_t get_remote_address(const char *address) { uint32_t len = strlen(address); @@ -1309,11 +1529,16 @@ void parsing_coap_uri(const char* uri, addressSet_t* address, CATransportFlags_t { LOGI("uri has '%s' prefix", COAP_PREFIX); startIndex = COAP_PREFIX_LEN; + } + else if (strncmp(COAP_TCP_PREFIX, uri, COAP_TCP_PREFIX_LEN) == 0) + { + LOGI("uri has '%s' prefix\n", COAP_TCP_PREFIX); + startIndex = COAP_TCP_PREFIX_LEN; *flags = CA_IPV4; } // #2. copy uri for parse - int32_t len = strlen(uri) - startIndex; + size_t len = strlen(uri) - startIndex; if (len <= 0) { @@ -1328,33 +1553,27 @@ void parsing_coap_uri(const char* uri, addressSet_t* address, CATransportFlags_t return; } - memcpy(cloneUri, &uri[startIndex], sizeof(char) * len); - cloneUri[len] = '\0'; + OICStrcpy(cloneUri, len+1, &uri[startIndex]); - char *pAddress = cloneUri; - char *pResourceUri = NULL; + char *pstr = NULL; + //filter out the resource uri + char *pUrl = strtok_r(cloneUri, "/", &pstr); - int32_t i = 0; - for (i = 0; i < len; i++) + if (pUrl) { - if (cloneUri[i] == '/') + LOGI("pAddress : %s", pUrl); + int res = get_address_set(pUrl, address); + if (res == -1) { - // separate - cloneUri[i] = 0; - pResourceUri = &cloneUri[i + 1]; - break; + LOGE("address parse error"); + return; } } - LOGI("pAddress : %s", pAddress); - - int res = get_address_set(pAddress, address); - if (res == -1) + else { - LOGE("address parse error"); - - free(cloneUri); - return; + LOGE("strtok_r error, could not get the address"); } + return; } @@ -1366,12 +1585,11 @@ int get_address_set(const char *pAddress, addressSet_t* outAddress) return -1; } - int32_t len = strlen(pAddress); - int32_t isIp = 0; - int32_t ipLen = 0; + size_t len = strlen(pAddress); + int isIp = 0; + size_t ipLen = 0; - int32_t i = 0; - for (i = 0; i < len; i++) + for (size_t i = 0; i < len; i++) { if (pAddress[i] == '.') { @@ -1388,12 +1606,12 @@ int get_address_set(const char *pAddress, addressSet_t* outAddress) if (isIp) { - if(ipLen && ipLen < sizeof(outAddress->ipAddress)) + if(ipLen && (ipLen < sizeof(outAddress->ipAddress))) { strncpy(outAddress->ipAddress, pAddress, ipLen); outAddress->ipAddress[ipLen] = '\0'; } - else if (!ipLen && len < sizeof(outAddress->ipAddress)) + else if (!ipLen && (len < sizeof(outAddress->ipAddress))) { strncpy(outAddress->ipAddress, pAddress, len); outAddress->ipAddress[len] = '\0'; @@ -1417,3 +1635,131 @@ int get_address_set(const char *pAddress, addressSet_t* outAddress) return isIp; } + +void delete_global_references(JNIEnv *env, jobject obj) +{ + LOGI("delete_global_references"); + if (!env || !obj ) + { + LOGI("Invalid input parameter"); + return; + } + + CADeleteGlobalReferences(env); + (*env)->DeleteGlobalRef(env, g_responseListenerObject); +} + + +bool read_file(const char* name, char** bytes, size_t* length) +{ + if (NULL == name) + { + LOGE("parameter is null"); + return false; + } + + FILE* file; + char* buffer; + long fileLen; + + // Open file + file = fopen(name, "rt"); + if (!file) + { + fprintf(stderr, "Unable to open file %s", name); + return false; + } + + // Get file length + fseek(file, 0, SEEK_END); + fileLen = ftell(file); + if (-1 == fileLen) + { + fprintf(stderr, "Failed to read file length"); + fclose(file); + return false; + } + fseek(file, 0, SEEK_SET); + + LOGI("file size: %ld", fileLen); + + // Allocate memory + buffer = calloc(1, sizeof(char) * fileLen + 1); + if (!buffer) + { + fprintf(stderr, "Memory error!"); + fclose(file); + return false; + } + + // Read file contents into buffer + size_t ret = fread(buffer, fileLen, 1, file); + if (ret != 1) + { + printf("Failed to read data from file, %s\n", name); + fclose(file); + free(buffer); + return false; + } + + fclose(file); + + LOGI("file bytes: %s", buffer); + + *bytes = buffer; + *length = fileLen; + + return true; +} + +void saveFile(const char *payload, size_t payloadSize) +{ + // 1. get day + uint32_t day = gettodaydate(); + + // 2. get time + time_t current_time; + struct tm * time_info; + char timeString[RECEIVED_FILE_NAME_PREFIX_LENGTH]; + + time(¤t_time); + time_info = localtime(¤t_time); + + strftime(timeString, sizeof(timeString), "%H%M%S", time_info); + + uint32_t path_length = strlen(RECEIVED_FILE_PATH) + RECEIVED_FILE_NAME_LENGTH + 1; + char* path = calloc(1, sizeof(char) * path_length); + if (path != NULL) + { + snprintf(path, path_length, RECEIVED_FILE_PATH, day, timeString); + LOGI("received file path: %s", path); + + FILE *fp = fopen(path, "wt"); + fwrite(payload, 1, payloadSize, fp); + fclose(fp); + + callback("File Path: ", path); + } + else + { + LOGE("path Out of memory"); + } +} + +uint32_t gettodaydate() +{ + uint32_t ldate; + time_t clock; + struct tm *date; + + clock = time(0); + date = localtime(&clock); + ldate = date->tm_year * 100000; + ldate += (date->tm_mon + 1) * 1000; + ldate += date->tm_mday * 10; + ldate += date->tm_wday; + ldate += 190000000; + ldate /= 10; + + return(ldate); +}