示例#1
0
void CABtAdapterLeDeviceDiscoveryStateChangedCb(int result,
        bt_adapter_le_device_discovery_state_e discoveryState,
        bt_adapter_le_device_discovery_info_s *discoveryInfo,
        void *userData)
{
    OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "IN");

    if (NULL  == discoveryInfo && BT_ADAPTER_LE_DEVICE_DISCOVERY_FOUND == discoveryState)
    {
        OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "discoveryInfo is NULL");
        return;
    }

    if (BT_ADAPTER_LE_DEVICE_DISCOVERY_FOUND != discoveryState)
    {
        OIC_LOG_V(DEBUG, TZ_BLE_CLIENT_TAG,
                  " LE Discovery state is [%s]",
          discoveryState == BT_ADAPTER_LE_DEVICE_DISCOVERY_STARTED ? "Started" : "Finished");
    }
    else
    {
        CAPrintDiscoveryInformation(discoveryInfo);

        if (discoveryInfo->service_uuid == NULL)
        {
            OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "NO UUIDS from device");
        }
        else
        {
            for (int32_t i = discoveryInfo->service_count - 1; i >= 0; i--)
            {
                OIC_LOG_V(DEBUG, TZ_BLE_CLIENT_TAG, "uuid[%d]: [%s]",
                          i, discoveryInfo->service_uuid[i]);
                CAResult_t res = CAVerifyOICServiceByUUID(discoveryInfo->service_uuid[i]);
                if (CA_STATUS_OK == res)
                {
                    char *addr = OICStrdup(discoveryInfo->remote_address);
                    VERIFY_NON_NULL_VOID(addr, TZ_BLE_CLIENT_TAG, "Malloc failed");

                    OIC_LOG_V(DEBUG, TZ_BLE_CLIENT_TAG,
                              "Trying to do Gatt connection to [%s]", addr);

                    ca_mutex_lock(g_bleClientThreadPoolMutex);
                    if (NULL == g_bleClientThreadPool)
                    {
                        OIC_LOG(ERROR, TZ_BLE_CLIENT_TAG, "g_bleClientThreadPool is NULL");
                        OICFree(addr);
                        ca_mutex_unlock(g_bleClientThreadPoolMutex);
                        return;
                    }

                    CAResult_t ret = ca_thread_pool_add_task(g_bleClientThreadPool,
                                                  CAGattConnectThread, addr);
                    if (CA_STATUS_OK != ret)
                    {
                        OIC_LOG_V(ERROR, TZ_BLE_CLIENT_TAG,
                                  "ca_thread_pool_add_task failed with ret [%d]", ret);
                        OICFree(addr);
                        ca_mutex_unlock(g_bleClientThreadPoolMutex);
                        return;
                    }
                    ca_mutex_unlock(g_bleClientThreadPoolMutex);
                    if (discoveryInfo->adv_data_len > 31 || discoveryInfo->scan_data_len > 31)
                    {
                        bt_adapter_le_stop_device_discovery();
                        return;
                    }
                    break;  // Found the OIC Service. No need to verify remaining services.
                }
            }
        }
    }
    OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "OUT");
}
示例#2
0
// It will be updated when android EDR support is added
void CAEDRClientDisconnectAll()
{
    OIC_LOG(DEBUG, TAG, "IN");

    OIC_LOG(DEBUG, TAG, "OUT");
}
示例#3
0
CAResult_t CAEDRInitialize()
{
    OIC_LOG(DEBUG, TAG, "CAEDRInitialize");

    CAEDRCoreJniInit();

    CAEDRJniInitContext();

    // init mutex
    CAResult_t result = CAEDRCreateMutex();
    if(CA_STATUS_OK != result)
    {
        OIC_LOG(ERROR, TAG, "CAEDRInitialize - Could not create mutex");
        return result;
    }

    bool isAttached = false;
    JNIEnv* env;
    jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
    if (JNI_OK != res)
    {
        OIC_LOG(DEBUG, TAG, "CAEDRInitialize - Could not get JNIEnv pointer");
        res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);

        if (JNI_OK != res)
        {
            OIC_LOG(ERROR, TAG, "AttachCurrentThread failed");
            return CA_STATUS_NOT_INITIALIZED;
        }
        isAttached = true;
    }
    jstring jni_address = CAEDRNativeGetLocalDeviceAddress(env);
    if (jni_address)
    {
        const char* localAddress = (*env)->GetStringUTFChars(env, jni_address, NULL);
        OIC_LOG_V(DEBUG, TAG, "My BT Address is %s", localAddress);
        (*env)->ReleaseStringUTFChars(env, jni_address, localAddress);
    }
    (*env)->DeleteLocalRef(env, jni_address);

    ca_mutex_lock(g_mutexStateList);
    CAEDRNativeCreateDeviceStateList();
    ca_mutex_unlock(g_mutexStateList);

    ca_mutex_lock(g_mutexObjectList);
    CAEDRNativeCreateDeviceSocketList();
    ca_mutex_unlock(g_mutexObjectList);

    if (isAttached)
    {
        (*g_jvm)->DetachCurrentThread(g_jvm);
    }

    if (g_context)
    {
        CAEDRCreateJNIInterfaceObject(g_context); /* create java CaEdrInterface instance*/
    }

    OIC_LOG(DEBUG, TAG, "OUT");

    return result;
}
示例#4
0
jobjectArray CAEDRNativeGetBondedDevices(JNIEnv *env)
{
    jclass jni_cid_BTAdapter = (*env)->FindClass(env, CLASSPATH_BT_ADPATER);
    if (!jni_cid_BTAdapter)
    {
        OIC_LOG(ERROR, TAG, "[EDR][Native] getBondedDevices: jni_cid_BTAdapter is null");
        return NULL;
    }

    jmethodID jni_mid_getDefaultAdapter = (*env)->GetStaticMethodID(env, jni_cid_BTAdapter,
                                                                    "getDefaultAdapter",
                                                                    METHODID_OBJECTNONPARAM);
    if (!jni_mid_getDefaultAdapter)
    {
        (*env)->DeleteLocalRef(env, jni_cid_BTAdapter);

        OIC_LOG(ERROR, TAG, "[EDR][Native] getBondedDevices: default adapter is null");
        return NULL;
    }

    jobject jni_obj_BTAdapter = (*env)->CallStaticObjectMethod(env, jni_cid_BTAdapter,
                                                               jni_mid_getDefaultAdapter);
    if (!jni_obj_BTAdapter)
    {
        (*env)->DeleteLocalRef(env, jni_cid_BTAdapter);

        OIC_LOG(ERROR, TAG, "[EDR][Native] getBondedDevices: bluetooth adapter is null");
        return NULL;
    }

    // Get a list of currently paired devices
    jmethodID jni_mid_getBondedDevices = (*env)->GetMethodID(env, jni_cid_BTAdapter,
                                                             "getBondedDevices",
                                                             "()Ljava/util/Set;");
    if (!jni_mid_getBondedDevices)
    {
        (*env)->DeleteLocalRef(env, jni_obj_BTAdapter);
        (*env)->DeleteLocalRef(env, jni_cid_BTAdapter);

        OIC_LOG(ERROR, TAG, "[EDR][Native] getBondedDevices: jni_mid_getBondedDevicesr is null");
        return NULL;
    }

    jobject jni_obj_setPairedDevices = (*env)->CallObjectMethod(env, jni_obj_BTAdapter,
                                                                jni_mid_getBondedDevices);
    if (!jni_obj_setPairedDevices)
    {
        (*env)->DeleteLocalRef(env, jni_obj_BTAdapter);
        (*env)->DeleteLocalRef(env, jni_cid_BTAdapter);

        OIC_LOG(ERROR, TAG, "[EDR][Native] getBondedDevices: jni_obj_setPairedDevices is null");
        return NULL;
    }

    // Convert the set to an object array
    // object[] array = Set<BluetoothDevice>.toArray();
    jclass jni_cid_Set = (*env)->FindClass(env, "java/util/Set");
    if (!jni_cid_Set)
    {
        (*env)->DeleteLocalRef(env, jni_obj_BTAdapter);
        (*env)->DeleteLocalRef(env, jni_cid_BTAdapter);
        (*env)->DeleteLocalRef(env, jni_obj_setPairedDevices);

        OIC_LOG(ERROR, TAG, "[EDR][Native] getBondedDevices: jni_cid_Set is null");
        return NULL;
    }
    jmethodID jni_mid_toArray = (*env)->GetMethodID(env, jni_cid_Set, "toArray",
                                                    "()[Ljava/lang/Object;");

    if (!jni_mid_toArray)
    {
        (*env)->DeleteLocalRef(env, jni_obj_BTAdapter);
        (*env)->DeleteLocalRef(env, jni_cid_BTAdapter);
        (*env)->DeleteLocalRef(env, jni_obj_setPairedDevices);

        OIC_LOG(ERROR, TAG, "[EDR][Native] getBondedDevices: jni_mid_toArray is null");
        return NULL;
    }

    jobjectArray jni_arrayPairedDevices = (jobjectArray)(
            (*env)->CallObjectMethod(env, jni_obj_setPairedDevices, jni_mid_toArray));
    if (!jni_arrayPairedDevices)
    {
        (*env)->DeleteLocalRef(env, jni_obj_BTAdapter);
        (*env)->DeleteLocalRef(env, jni_cid_BTAdapter);
        (*env)->DeleteLocalRef(env, jni_obj_setPairedDevices);

        OIC_LOG(ERROR, TAG, "[EDR][Native] getBondedDevices: jni_arrayPairedDevices is null");
        return NULL;
    }

    (*env)->DeleteLocalRef(env, jni_obj_BTAdapter);
    (*env)->DeleteLocalRef(env, jni_cid_BTAdapter);
    (*env)->DeleteLocalRef(env, jni_obj_setPairedDevices);

    return jni_arrayPairedDevices;
}
示例#5
0
void CAEDRClientTerminate()
{
    OIC_LOG(DEBUG, TAG, "IN");
    CAEDRTerminate();
    OIC_LOG(DEBUG, TAG, "OUT");
}
示例#6
0
CAResult_t CAStartLEGattClient()
{
    OIC_LOG(DEBUG, TAG, "IN");
    OIC_LOG(DEBUG, TAG, "OUT");
    return CA_STATUS_OK;
}
示例#7
0
void CATerminateLEGattClient()
{
    OIC_LOG(DEBUG, TAG, "IN");
    OIC_LOG(DEBUG, TAG, "OUT");
}
void CALESetAdapterStateCallback(CALEDeviceStateChangedCallback callback)
{
    OIC_LOG(DEBUG, TAG, "CALESetAdapterStateCallback");
    g_bleDeviceStateChangedCallback = callback;
}
示例#9
0
/*
* Function to unlink devices.
* This function will remove the credential & relationship between the two devices.
*
* @param[in] ctx Application context would be returned in result callback
* @param[in] pTargetDev1 first device information to be unlinked.
* @param[in] pTargetDev2 second device information to be unlinked.
* @param[in] resultCallback callback provided by API user, callback will be called when
*            device unlink is finished.
 * @return  OC_STACK_OK in case of success and other value otherwise.
*/
OCStackResult OCUnlinkDevices(void* ctx,
                              const OCProvisionDev_t* pTargetDev1,
                              const OCProvisionDev_t* pTargetDev2,
                              OCProvisionResultCB resultCallback)
{
    OIC_LOG(INFO, TAG, "IN OCUnlinkDevices");
    OCUuidList_t* idList = NULL;
    size_t numOfDev = 0;

    if (!pTargetDev1 || !pTargetDev2 || !pTargetDev1->doxm || !pTargetDev2->doxm)
    {
        OIC_LOG(ERROR, TAG, "OCUnlinkDevices : NULL parameters");
        return OC_STACK_INVALID_PARAM;
    }
    if (!resultCallback)
    {
        OIC_LOG(INFO, TAG, "OCUnlinkDevices : NULL Callback");
        return OC_STACK_INVALID_CALLBACK;
    }
    if (0 == memcmp(&pTargetDev1->doxm->deviceID, &pTargetDev2->doxm->deviceID, sizeof(OicUuid_t)))
    {
        OIC_LOG(INFO, TAG, "OCUnlinkDevices : Same device ID");
        return OC_STACK_INVALID_PARAM;
    }

    // Get linked devices with the first device.
    OCStackResult res = PDMGetLinkedDevices(&(pTargetDev1->doxm->deviceID), &idList, &numOfDev);
    if (OC_STACK_OK != res)
    {
        OIC_LOG(ERROR, TAG, "OCUnlinkDevices : PDMgetOwnedDevices failed");
        goto error;
    }
    if (1 > numOfDev)
    {
        OIC_LOG(DEBUG, TAG, "OCUnlinkDevices : Can not find linked devices");
        res = OC_STACK_INVALID_PARAM; // Input devices are not linked, No request is made
        goto error;
    }

    // Check the linked devices contains the second device. If yes send credential DELETE request.
    OCUuidList_t* curDev = idList;
    while (NULL != curDev)
    {
        if (memcmp(pTargetDev2->doxm->deviceID.id, curDev->dev.id, sizeof(curDev->dev.id)) == 0)
        {
            res = SRPUnlinkDevices(ctx, pTargetDev1, pTargetDev2, resultCallback);
            if (OC_STACK_OK != res)
            {
                OIC_LOG(ERROR, TAG, "OCUnlinkDevices : Failed to unlink devices.");
            }
            goto error;
        }
        curDev = curDev->next;
    }
    OIC_LOG(DEBUG, TAG, "No matched pair found from provisioning database");
    res = OC_STACK_INVALID_PARAM; // Input devices are not linked, No request is made

error:
    OIC_LOG(INFO, TAG, "OUT OCUnlinkDevices");

    PDMDestoryOicUuidLinkList(idList);
    return res;
}
//getting context
void CALENetworkMonitorJNISetContext()
{
    OIC_LOG(DEBUG, TAG, "CALENetworkMonitorJNISetContext - it is not supported");
}
//getting jvm
void CALENetworkMonitorJniInit()
{
    OIC_LOG(DEBUG, TAG, "CALENetworkMonitorJniInit");
    g_jvm = CANativeJNIGetJavaVM();
}
JNIEXPORT void JNICALL
Java_org_iotivity_ca_CaLeClientInterface_caLeStateChangedCallback(JNIEnv *env, jobject obj,
                                                                   jint status)
{
    VERIFY_NON_NULL_VOID(env, TAG, "env is null");
    VERIFY_NON_NULL_VOID(obj, TAG, "obj is null");

    OIC_LOG_V(DEBUG, TAG, "CaLeClientInterface - Network State Changed : status(%d)", status);

    if (!g_bleDeviceStateChangedCallback)
    {
        OIC_LOG(ERROR, TAG, "gNetworkChangeCb is null");
        return;
    }

    jint state_on = CALEGetConstantsValue(env, CLASSPATH_BT_ADAPTER, "STATE_ON");
    jint state_off = CALEGetConstantsValue(env, CLASSPATH_BT_ADAPTER, "STATE_OFF");
    jint state_turning_off = CALEGetConstantsValue(env, CLASSPATH_BT_ADAPTER, "STATE_TURNING_OFF");

    if (state_on == status) // STATE_ON:12
    {
        CANetworkStatus_t newStatus = CA_INTERFACE_UP;
        CALEClientCreateDeviceList();
        CALEServerCreateCachedDeviceList();

        g_bleDeviceStateChangedCallback(newStatus);
    }
    else if (state_turning_off == status) // BT_STATE_TURNING_OFF:13
    {
        // gatt Device list will be removed.
        // so it is need to create list again when adapter is enabled.
        CAStopLEGattClient();
    }
    else if (state_off == status) // STATE_OFF:10
    {
        CALEClientStopMulticastServer();

        // remove obj for client
        CAResult_t res = CALEClientRemoveAllGattObjs(env);
        if (CA_STATUS_OK != res)
        {
            OIC_LOG(ERROR, TAG, "CALEClientRemoveAllGattObjs has failed");
        }

        res = CALEClientResetDeviceStateForAll();
        if (CA_STATUS_OK != res)
        {
            OIC_LOG(ERROR, TAG, "CALEClientResetDeviceStateForAll has failed");
        }

        // remove obj for server
        res = CALEServerRemoveAllDevices(env);
        if (CA_STATUS_OK != res)
        {
            OIC_LOG(ERROR, TAG, "CALEServerRemoveAllDevices has failed");
        }

        CALEClientSetScanFlag(false);

        CANetworkStatus_t newStatus = CA_INTERFACE_DOWN;
        g_bleDeviceStateChangedCallback(newStatus);
    }
}
CAResult_t CAUnSetLEAdapterStateChangedCb()
{
    OIC_LOG(DEBUG, TAG, "it is not required in this platform");
    return CA_STATUS_OK;
}
示例#14
0
CAResult_t CAInitGattClientMutexVariables()
{
    OIC_LOG(DEBUG,  TZ_BLE_CLIENT_TAG, "IN");
    if (NULL == g_bleClientStateMutex)
    {
        g_bleClientStateMutex = ca_mutex_new();
        if (NULL == g_bleClientStateMutex)
        {
            OIC_LOG(ERROR, TZ_BLE_CLIENT_TAG, "ca_mutex_new failed");
            return CA_STATUS_FAILED;
        }
    }

    if (NULL == g_bleServiceListMutex)
    {
        g_bleServiceListMutex = ca_mutex_new();
        if (NULL == g_bleServiceListMutex)
        {
            OIC_LOG(ERROR, TZ_BLE_CLIENT_TAG, "ca_mutex_new failed");
            return CA_STATUS_FAILED;
        }
    }

    if (NULL == g_bleReqRespClientCbMutex)
    {
        g_bleReqRespClientCbMutex = ca_mutex_new();
        if (NULL == g_bleReqRespClientCbMutex)
        {
            OIC_LOG(ERROR, TZ_BLE_CLIENT_TAG, "ca_mutex_new failed");
            return CA_STATUS_FAILED;
        }
    }

    if (NULL == g_bleClientThreadPoolMutex)
    {
        g_bleClientThreadPoolMutex = ca_mutex_new();
        if (NULL == g_bleClientThreadPoolMutex)
        {
            OIC_LOG(ERROR, TZ_BLE_CLIENT_TAG, "ca_mutex_new failed");
            return CA_STATUS_FAILED;
        }
    }

    if (NULL == g_bleClientConnectMutex)
    {
        g_bleClientConnectMutex = ca_mutex_new();
        if (NULL == g_bleClientConnectMutex)
        {
            OIC_LOG(ERROR, TZ_BLE_CLIENT_TAG, "ca_mutex_new failed");
            return CA_STATUS_FAILED;
        }
    }

    if (NULL == g_bleClientSendCondWait)
    {
        g_bleClientSendCondWait = ca_cond_new();
        if (NULL == g_bleClientSendCondWait)
        {
            OIC_LOG(ERROR, TZ_BLE_CLIENT_TAG, "ca_cond_new failed");
            return CA_STATUS_FAILED;
        }
    }

    if (NULL == g_bleServerBDAddressMutex)
    {
        g_bleServerBDAddressMutex = ca_mutex_new();
        if (NULL == g_bleServerBDAddressMutex)
        {
            OIC_LOG(ERROR, TZ_BLE_CLIENT_TAG, "ca_mutex_new failed");
            return CA_STATUS_FAILED;
        }
    }

    OIC_LOG(DEBUG,  TZ_BLE_CLIENT_TAG, "OUT");
    return CA_STATUS_OK;
}
示例#15
0
void CASetLEReqRespClientCallback(CABLEDataReceivedCallback callback)
{
    OIC_LOG(DEBUG, TAG, "IN");
    OIC_LOG(DEBUG, TAG, "OUT");
}
示例#16
0
/*
* Function to device revocation
* This function will remove credential of target device from all devices in subnet.
*
* @param[in] ctx Application context would be returned in result callback
* @param[in] waitTimeForOwnedDeviceDiscovery Maximum wait time for owned device discovery.(seconds)
* @param[in] pTargetDev Device information to be revoked.
* @param[in] resultCallback callback provided by API user, callback will be called when
*            credential revocation is finished.
 * @return  OC_STACK_OK in case of success and other value otherwise.
*/
OCStackResult OCRemoveDevice(void* ctx, unsigned short waitTimeForOwnedDeviceDiscovery,
                            const OCProvisionDev_t* pTargetDev,
                            OCProvisionResultCB resultCallback)
{
    OIC_LOG(INFO, TAG, "IN OCRemoveDevice");
    OCStackResult res = OC_STACK_ERROR;
    if (!pTargetDev || 0 == waitTimeForOwnedDeviceDiscovery)
    {
        OIC_LOG(INFO, TAG, "OCRemoveDevice : Invalied parameters");
        return OC_STACK_INVALID_PARAM;
    }
    if (!resultCallback)
    {
        OIC_LOG(INFO, TAG, "OCRemoveDevice : NULL Callback");
        return OC_STACK_INVALID_CALLBACK;
    }

    // Send DELETE requests to linked devices
    OCStackResult resReq = OC_STACK_ERROR; // Check that we have to wait callback or not.
    resReq = SRPRemoveDevice(ctx, waitTimeForOwnedDeviceDiscovery, pTargetDev, resultCallback);
    if (OC_STACK_OK != resReq)
    {
        if (OC_STACK_CONTINUE == resReq)
        {
            OIC_LOG(DEBUG, TAG, "OCRemoveDevice : Revoked device has no linked device except PT.");
        }
        else
        {
            OIC_LOG(ERROR, TAG, "OCRemoveDevice : Failed to invoke SRPRemoveDevice");
            res = resReq;
            goto error;
        }
    }

    // Remove credential of revoked device from SVR database
    const OicSecCred_t *cred = NULL;
    cred = GetCredResourceData(&pTargetDev->doxm->deviceID);
    if (cred == NULL)
    {
        OIC_LOG(ERROR, TAG, "OCRemoveDevice : Failed to get credential of remove device.");
        goto error;
    }

    res = RemoveCredential(&cred->subject);
    if (res != OC_STACK_RESOURCE_DELETED)
    {
        OIC_LOG(ERROR, TAG, "OCRemoveDevice : Failed to remove credential.");
        goto error;
    }

    /**
     * Change the device status as stale status.
     * If all request are successed, this device information will be deleted.
     */
    res = PDMSetDeviceStale(&pTargetDev->doxm->deviceID);
    if (res != OC_STACK_OK)
    {
        OIC_LOG(ERROR, TAG, "OCRemoveDevice : Failed to set device status as stale");
        goto error;
    }

    // TODO: We need to add new mechanism to clean up the stale state of the device.

    res = resReq;

    //Close the DTLS session of the removed device.
    CAEndpoint_t* endpoint = (CAEndpoint_t *)&pTargetDev->endpoint;
    endpoint->port = pTargetDev->securePort;
    CAResult_t caResult = CACloseDtlsSession(endpoint);
    if(CA_STATUS_OK != caResult)
    {
        OIC_LOG_V(WARNING, TAG, "OCRemoveDevice : Failed to close DTLS session : %d", caResult);
    }

    /**
     * If there is no linked device, PM does not send any request.
     * So we should directly invoke the result callback to inform the result of OCRemoveDevice.
     */
    if(OC_STACK_CONTINUE == res)
    {
        if(resultCallback)
        {
            resultCallback(ctx, 0, NULL, false);
        }
        res = OC_STACK_OK;
    }

error:
    OIC_LOG(INFO, TAG, "OUT OCRemoveDevice");
    return res;
}
示例#17
0
void CASetBLEClientErrorHandleCallback(CABLEErrorHandleCallback callback)
{
    OIC_LOG(DEBUG, TAG, "IN");
    OIC_LOG(DEBUG, TAG, "OUT");
}
示例#18
0
/**
 * Callback to handle credential provisioning.
 */
static void ProvisionCredsCB(void* ctx, int nOfRes, OCProvisionResult_t *arr, bool hasError)
{
    if (NULL == ctx)
    {
        OIC_LOG(ERROR,TAG,"Error occured while credential provisioning");
        return;
    }
    Linkdata_t *link = (Linkdata_t*)ctx;
    OCProvisionResultCB resultCallback = link->resultCallback;
    OIC_LOG_V(INFO, TAG, "has error returned %d",hasError);
    UpdateLinkResults(link, 1, arr[0].res);
    UpdateLinkResults(link, 2, arr[1].res);
    if (hasError)
    {
        OIC_LOG(ERROR,TAG,"Error occured while credential provisioning");
        ((OCProvisionResultCB)(resultCallback))(link->ctx, nOfRes,
                                                link->resArr,
                                                true);
         OICFree(link->resArr);
         OICFree(link);
         return;
    }
    if (NULL != link->pDev1Acl)
    {

        OCStackResult res =  SRPProvisionACL(ctx, link->pDev1, link->pDev1Acl, &AclProv1CB);
        if (OC_STACK_OK!=res)
        {
             OIC_LOG(ERROR, TAG, "Error while provisioning ACL for device 1");
             UpdateLinkResults(link, 1, res);
             ((OCProvisionResultCB)(resultCallback))(link->ctx, link->currentCountResults,
                                                     link->resArr,
                                                     true);
              OICFree(link->resArr);
              OICFree(link);
        }
    }
    else if (NULL!=link->pDev2Acl)
    {
        OIC_LOG(ERROR, TAG, "ACL for device 1 is NULL");
        OCStackResult res =  SRPProvisionACL(ctx, link->pDev2, link->pDev2Acl, &AclProv2CB);
        if (OC_STACK_OK!=res)
        {
             OIC_LOG(ERROR, TAG, "Error while provisioning ACL for device 2");
              UpdateLinkResults(link, 2, res);
             ((OCProvisionResultCB)(resultCallback))(link->ctx, link->currentCountResults,
                                                     link->resArr,
                                                     true);
              OICFree(link->resArr);
              OICFree(link);
        }
    }
    else
    {
        OIC_LOG(INFO, TAG, "ACLs of both devices are NULL");
        ((OCProvisionResultCB)(resultCallback))(link->ctx, link->currentCountResults,
                                                link->resArr,
                                                false);
        OICFree(link->resArr);
        OICFree(link);
    }
    return;
}
示例#19
0
void CAStopLEGattClient()
{
    OIC_LOG(DEBUG, TAG, "IN");
    OIC_LOG(DEBUG, TAG, "OUT");
}
示例#20
0
/**
 * function to provision credentials between two devices and ACLs for the devices who act as a server.
 *
 * @param[in] ctx Application context would be returned in result callback.
 * @param[in] type Type of credentials to be provisioned to the device.
 * @param[in] pDev1 Pointer to OCProvisionDev_t instance,respresenting resource to be provsioned.
 * @param[in] acl ACL for device 1. If this is not required set NULL.
 * @param[in] pDev2 Pointer to OCProvisionDev_t instance,respresenting resource to be provsioned.
 * @param[in] acl ACL for device 2. If this is not required set NULL.
 * @param[in] resultCallback callback provided by API user, callback will be called when
 *            provisioning request recieves a response from first resource server.
 * @return  OC_STACK_OK in case of success and other value otherwise.
 */
OCStackResult OCProvisionPairwiseDevices(void* ctx, OicSecCredType_t type, size_t keySize,
                                         const OCProvisionDev_t *pDev1, OicSecAcl_t *pDev1Acl,
                                         const OCProvisionDev_t *pDev2, OicSecAcl_t *pDev2Acl,
                                         OCProvisionResultCB resultCallback)
{

    if (!pDev1 || !pDev2 || !pDev1->doxm || !pDev2->doxm)
    {
        OIC_LOG(ERROR, TAG, "OCProvisionPairwiseDevices : Invalid parameters");
        return OC_STACK_INVALID_PARAM;
    }
    if (!resultCallback)
    {
        OIC_LOG(INFO, TAG, "OCProvisionPairwiseDevices : NULL Callback");
        return OC_STACK_INVALID_CALLBACK;
    }
    if (!(keySize == OWNER_PSK_LENGTH_128 || keySize == OWNER_PSK_LENGTH_256))
    {
        OIC_LOG(INFO, TAG, "OCProvisionPairwiseDevices : Invalid key size");
        return OC_STACK_INVALID_PARAM;
    }
    if (0 == memcmp(&pDev1->doxm->deviceID, &pDev2->doxm->deviceID, sizeof(OicUuid_t)))
    {
        OIC_LOG(INFO, TAG, "OCProvisionPairwiseDevices : Same device ID");
        return OC_STACK_INVALID_PARAM;
    }

    OIC_LOG(DEBUG, TAG, "Checking link in DB");
    bool linkExists = true;
    OCStackResult res = PDMIsLinkExists(&pDev1->doxm->deviceID, &pDev2->doxm->deviceID, &linkExists);
    if(res != OC_STACK_OK)
    {
        OIC_LOG(ERROR, TAG, "Internal Error Occured");
        return res;
    }
    if (linkExists)
    {
        OIC_LOG(ERROR, TAG, "Link already exists");
        return OC_STACK_INVALID_PARAM;
    }

    int noOfResults = 2; // Initial Value
    if (NULL != pDev1Acl)
    {
        ++noOfResults;
    }
    if (NULL != pDev2Acl)
    {
       ++noOfResults;
    }
    Linkdata_t *link = (Linkdata_t*) OICMalloc(sizeof(Linkdata_t));
    if (!link)
    {
        OIC_LOG(ERROR, TAG, "Failed to memory allocation");
        return OC_STACK_NO_MEMORY;
    }
    OIC_LOG_V(INFO,TAG, "Maximum no od results %d",noOfResults);

    link->pDev1 = pDev1;
    link->pDev1Acl = pDev1Acl;
    link->pDev2 = pDev2;
    link->pDev2Acl = pDev2Acl;
    link->ctx = ctx;
    // 1 call for each device for credential provisioning. implict call by SRPProvisioning credential
    // 1 call for ACL provisioning for device 1 and 1 call for ACL provisioning for device 2.
    link->numOfResults = noOfResults;
    link->resultCallback = resultCallback;
    link->currentCountResults = 0;
    link->resArr = (OCProvisionResult_t*) OICMalloc(sizeof(OCProvisionResult_t)*noOfResults);
    res = SRPProvisionCredentials(link, type, keySize,
                                     pDev1, pDev2, &ProvisionCredsCB);
    if (res != OC_STACK_OK)
    {
        OICFree(link->resArr);
        OICFree(link);
    }
    return res;

}
示例#21
0
CAResult_t CAInitializeLEGattClient()
{
    OIC_LOG(DEBUG, TAG, "IN");
    OIC_LOG(DEBUG, TAG, "OUT");
    return CA_STATUS_OK;
}
示例#22
0
OCStackResult OCGetDevInfoFromNetwork(unsigned short waittime,
                                       OCProvisionDev_t** pOwnedDevList,
                                       OCProvisionDev_t** pUnownedDevList)
{
    //TODO will be replaced by more efficient logic
    if (pOwnedDevList == NULL || *pOwnedDevList != NULL || pUnownedDevList == NULL
         || *pUnownedDevList != NULL || 0 == waittime)
    {
        return OC_STACK_INVALID_PARAM;
    }

    // Code for unowned discovery
    OCProvisionDev_t *unownedDevice = NULL;
    OCStackResult res =  OCDiscoverUnownedDevices(waittime/2, &unownedDevice);
    if (OC_STACK_OK != res)
    {
        OIC_LOG(ERROR,TAG, "Error in unowned discovery");
        return res;
    }

    // Code for owned discovery
    OCProvisionDev_t *ownedDevice = NULL;
    res =  OCDiscoverOwnedDevices(waittime/2, &ownedDevice);
    if (OC_STACK_OK != res)
    {
        OIC_LOG(ERROR,TAG, "Error in owned discovery");
        PMDeleteDeviceList(unownedDevice);
        return res;
    }

    // Code to get list of all the owned devices.
    OCUuidList_t *uuidList = NULL;
    size_t numOfDevices = 0;
    res =  PDMGetOwnedDevices(&uuidList, &numOfDevices);
    if (OC_STACK_OK != res)
    {
        OIC_LOG(ERROR, TAG, "Error while getting info from DB");
        PMDeleteDeviceList(unownedDevice);
        PMDeleteDeviceList(ownedDevice);
        return res;
    }

    // Code to compare devices in owned list and deviceid from DB.
    OCProvisionDev_t* pCurDev = ownedDevice;
    size_t deleteCnt = 0;
    while (pCurDev)
    {
        if(true == PMDeleteFromUUIDList(uuidList, &pCurDev->doxm->deviceID))
        {
            deleteCnt++;
        }
        pCurDev = pCurDev->next;
    }
    // If there is no remaind device in uuidList, we have to assign NULL to prevent free.
    if (deleteCnt == numOfDevices)
    {
        uuidList = NULL;
    }
    // Code to add information of the devices which are currently off in owned list.
    OCUuidList_t *powerOffDeviceList = uuidList;
    while (powerOffDeviceList)
    {
        OCProvisionDev_t *ptr = (OCProvisionDev_t *)OICCalloc(1, sizeof (OCProvisionDev_t));
        if (NULL == ptr)
        {
            OIC_LOG(ERROR,TAG,"Fail to allocate memory");
            PMDeleteDeviceList(unownedDevice);
            PMDeleteDeviceList(ownedDevice);
            OCDeleteUuidList(uuidList);
            return OC_STACK_NO_MEMORY;
        }

        ptr->doxm = (OicSecDoxm_t*)OICCalloc(1, sizeof(OicSecDoxm_t));
        if (NULL == ptr->doxm)
        {
            OIC_LOG(ERROR,TAG,"Fail to allocate memory");
            PMDeleteDeviceList(unownedDevice);
            PMDeleteDeviceList(ownedDevice);
            OCDeleteUuidList(uuidList);
            OICFree(ptr);
            return OC_STACK_NO_MEMORY;
        }

        memcpy(ptr->doxm->deviceID.id, powerOffDeviceList->dev.id, sizeof(ptr->doxm->deviceID.id));

        ptr->devStatus = DEV_STATUS_OFF;
        LL_PREPEND(ownedDevice, ptr);
        powerOffDeviceList = powerOffDeviceList->next;

    }
    OCDeleteUuidList(uuidList);
    *pOwnedDevList = ownedDevice;
    *pUnownedDevList = unownedDevice;
    return OC_STACK_OK;
}
示例#23
0
// get address from bluetooth socket
jstring CAEDRNativeGetAddressFromDeviceSocket(JNIEnv *env, jobject bluetoothSocketObj)
{
    if (!bluetoothSocketObj)
    {
        OIC_LOG(ERROR, TAG, "[EDR] getRemoteAddress: bluetoothSocketObj is null");
        return NULL;
    }

    jclass jni_cid_BTSocket = (*env)->FindClass(env, CLASSPATH_BT_SOCKET);
    if (!jni_cid_BTSocket)
    {
        OIC_LOG(ERROR, TAG, "[EDR] getRemoteAddress: jni_cid_BTSocket is null");
        return NULL;
    }

    jmethodID jni_mid_getRemoteDevice = (*env)->GetMethodID(
            env, jni_cid_BTSocket, "getRemoteDevice", "()Landroid/bluetooth/BluetoothDevice;");
    if (!jni_mid_getRemoteDevice)
    {
        (*env)->DeleteLocalRef(env, jni_cid_BTSocket);

        OIC_LOG(ERROR, TAG, "[EDR] getRemoteAddress: jni_mid_getRemoteDevice is null");
        return NULL;
    }

    jobject jni_obj_remoteBTDevice = (*env)->CallObjectMethod(env, bluetoothSocketObj,
                                                              jni_mid_getRemoteDevice);
    if (!jni_obj_remoteBTDevice)
    {
        (*env)->DeleteLocalRef(env, jni_cid_BTSocket);

        OIC_LOG(ERROR, TAG, "[EDR] getRemoteAddress: jni_obj_remoteBTDevice is null");
        return NULL;
    }

    jclass jni_cid_BTDevice = (*env)->FindClass(env, CLASSPATH_BT_DEVICE);
    if (!jni_cid_BTDevice)
    {
        (*env)->DeleteLocalRef(env, jni_obj_remoteBTDevice);
        (*env)->DeleteLocalRef(env, jni_cid_BTSocket);

        OIC_LOG(ERROR, TAG, "[EDR] getRemoteAddress: jni_cid_BTDevice is null");
        return NULL;
    }
    jmethodID j_mid_getAddress = (*env)->GetMethodID(env, jni_cid_BTDevice, "getAddress",
                                                     METHODID_STRINGNONPARAM);
    if (!j_mid_getAddress)
    {
        (*env)->DeleteLocalRef(env, jni_obj_remoteBTDevice);
        (*env)->DeleteLocalRef(env, jni_cid_BTDevice);
        (*env)->DeleteLocalRef(env, jni_cid_BTSocket);

        OIC_LOG(ERROR, TAG, "[EDR] getRemoteAddress: j_mid_getAddress is null");
        return NULL;
    }

    jstring j_str_address = (*env)->CallObjectMethod(env, jni_obj_remoteBTDevice, j_mid_getAddress);
    if (!j_str_address)
    {
        (*env)->DeleteLocalRef(env, jni_obj_remoteBTDevice);
        (*env)->DeleteLocalRef(env, jni_cid_BTDevice);
        (*env)->DeleteLocalRef(env, jni_cid_BTSocket);

        OIC_LOG(ERROR, TAG, "[EDR] getRemoteAddress: j_str_address is null");
        return NULL;
    }

    (*env)->DeleteLocalRef(env, jni_obj_remoteBTDevice);
    (*env)->DeleteLocalRef(env, jni_cid_BTDevice);
    (*env)->DeleteLocalRef(env, jni_cid_BTSocket);

    return j_str_address;
}
CAResult_t CAGetLEAddress(char **local_address)
{
    OIC_LOG(DEBUG, TAG, "Get Linux BLE local device information.");

    if (local_address == NULL)
    {
        return CA_STATUS_INVALID_PARAM;
    }

    /**
     * @bug Attempting to get LE interface information before this
     *      connectivity abstraction adapter has started (e.g. via
     *      @c CASelectNetwork()) could result in an inaccurate list
     *      of LE interfaces.  For example, detection of hot-plugged
     *      bluetooth adapters will only work after the LE IoTivity
     *      network has been selected.  If the LE IoTivity network
     *      hasn't been selected, the hot-plugged bluetooth adapter
     *      will not be reflected in the @c CALocalConnectivity_t list
     *      returned by this function.
     *      @par
     *      This issue caused by the fact that the event loop that
     *      handles such events can only be run after this LE
     *      adapter/transport is started.  The event loop cannot be
     *      started earlier, e.g. during @c CAInitialize(), due to a
     *      limitation in the CA transport termination code that
     *      requires thread pools to be destroyed before transport
     *      termination.  If the event loop was added as a task to the
     *      thread pool during @c CAInitialize(), it's possible that
     *      the thread running that event loop could be blocked
     *      waiting for events during a later call to
     *      @c CATerminate() if @c CASelectNetwork() was not called
     *      beforehand.  The thread pool destruction that occurs
     *      during @c CATerminate() waits for threads in the pool to
     *      exit.  However, in this case the event loop thread is
     *      still blocked waiting for events since it may not have
     *      been stopped since the transport itself was not stopped,
     *      meaning termination will also be blocked.
     *      @par
     *      Other than refactoring to the termination code to allow
     *      thread pools to be started during @c CAInitialize(), the
     *      only other choice we have to prevent the hang at
     *      termination is to move the event loop creation and
     *      termination to the @c CAAdapterStart() and
     *      @c CAAdapterStop() implementations, respectively, which is
     *      why we have this bug.
     */
    if (!CALECheckStarted())
      return CA_ADAPTER_NOT_ENABLED;

    *local_address = NULL;

    ca_mutex_lock(g_context.lock);

    for (GList * l = g_context.adapters; l != NULL; l = l->next)
    {
        GDBusProxy * const adapter = G_DBUS_PROXY(l->data);

        /*
          The local bluetooth adapter MAC address is stored in the
          org.bluez.Adapter1.Address property.
        */
        GVariant * const prop =
            g_dbus_proxy_get_cached_property(adapter, "Address");

        /*
          Unless the org.bluez.Adapter1.Address property no longer
          exists, prop should not be NULL!  We have bigger problems if
          this assert() is ever tripped since that would mean the
          org.bluez.Adapter1 D-Bus interface changed.
        */
        assert(prop != NULL);

        gchar const * const address = g_variant_get_string(prop, NULL);

        *local_address = OICStrdup(address);

        /*
          No longer need the property variant.  The address has been
          copied.
        */
        g_variant_unref(prop);

        /**
         * @todo Unfortunately the CA LE interface defined in
         *       caleinterface.h assumes that only one BLE adapter
         *       will exist on a given host.  However, this
         *       implementation can handle multiple BLE adapters.  The
         *       CA LE interface should be updated so that it can
         *       handle multiple BLE adapters.  For now we'll just
         *       return the address for the first BLE adapter in the
         *       list.
         */
        break;
    }

    ca_mutex_unlock(g_context.lock);

    return *local_address != NULL ? CA_STATUS_OK : CA_STATUS_FAILED;
}
示例#25
0
// It will be updated when android EDR support is added
void CAEDRClientUnsetCallbacks()
{
    OIC_LOG(DEBUG, TAG, "IN");

    OIC_LOG(DEBUG, TAG, "OUT");
}
CAResult_t CAStartLEAdapter()
{
    /*
      This function is called by the connectivity abstraction when
      CASelectNetwork(CA_ADAPTER_GATT_BTLE) is called by the user.
    */

    OIC_LOG(DEBUG, TAG, __func__);

    CAResult_t result = CA_STATUS_FAILED;

    // Only start if we were previously stopped.
    if (CALECheckStarted())
    {
        return result;
    }

    /**
     * Spawn a thread to run the GLib event loop that will drive D-Bus
     * signal handling.
     *
     * @note Ideally this should be done in the @c CAInitializeLE()
     *       function so that we can detect local bluetooth adapter
     *       changes right away, without having to first start this LE
     *       adapter/transport via @cCASelectNetwork().  However, a
     *       limitation in the CA termination code that destroys the
     *       thread pool before the transport adapters prevents us
     *       from doing that without potentially triggering a
     *       @c pthread_join() call that blocks indefinitely due to
     *       this event loop not being stopped.  See the comments in
     *       the @c CAGetLEInterfaceInformation() function below for
     *       further details.
     */
    result = ca_thread_pool_add_task(g_context.client_thread_pool,
                                     CALEStartEventLoop,
                                     &g_context);

    /*
      Wait for the GLib event loop to actually run before returning.

      This addresses corner cases where operations are incorrectly
      permitted to run in parallel before the event loop is run. For
      example, the LE transport could have been stopped in a thread
      parallel to the one starting the event loop start.  In that case
      the GLib event loop may never exit since the stop operation that
      causes the event loop to exit occurred before event loop
      started.  That ultimately causes the CA layer termination to
      block indefinitely on a pthread_join().  The solution is to only
      return from the LE transport start operation once we know the
      event loop is up and running.
    */
    struct timespec abs_timeout;
    if (result == CA_STATUS_OK
        && clock_gettime(CLOCK_REALTIME, &abs_timeout) == 0)
    {
        static time_t const relative_timeout = 2;  // seconds
        abs_timeout.tv_sec += relative_timeout;

        int const wait_result =
            sem_timedwait(&g_context.le_started, &abs_timeout);

        if (wait_result == 0)
        {
            result = CA_STATUS_OK;
        }
    }

    return result;
}
示例#27
0
void CAEDRJniInitContext()
{
    OIC_LOG(DEBUG, TAG, "CAEDRJniInitContext");

    g_context = (jobject) CANativeJNIGetContext();
}
示例#28
0
void CASetLEClientThreadPoolHandle(ca_thread_pool_t handle)
{
    OIC_LOG(DEBUG, TAG, "IN");
    OIC_LOG(DEBUG, TAG, "OUT");
}
示例#29
0
CAResult_t CAEDRDestroyJniInterface()
{
    OIC_LOG(DEBUG, TAG, "CAEDRDestroyJniInterface");

    if (!g_jvm)
    {
        OIC_LOG(ERROR, TAG, "g_jvm is null");
        return CA_STATUS_FAILED;
    }

    bool isAttached = false;
    JNIEnv* env;
    jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
    if (JNI_OK != res)
    {
        OIC_LOG(INFO, TAG, "Could not get JNIEnv pointer");
        res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);

        if (JNI_OK != res)
        {
            OIC_LOG(ERROR, TAG, "AttachCurrentThread has failed");
            return CA_STATUS_FAILED;
        }
        isAttached = true;
    }

    jclass jni_EDRJniInterface = (*env)->FindClass(env, CLASSPATH_BT_INTERFACE);
    if (!jni_EDRJniInterface)
    {
        OIC_LOG(ERROR, TAG, "Could not get CaEdrInterface class");
        goto error_exit;
    }

    jmethodID jni_EDRInterfaceDestroyMethod = (*env)->GetStaticMethodID(env, jni_EDRJniInterface,
                                                                        "destroyEdrInterface",
                                                                        "()V");
    if (!jni_EDRInterfaceDestroyMethod)
    {
        OIC_LOG(ERROR, TAG, "Could not get CaEdrInterface destroy method");
        goto error_exit;
    }

    (*env)->CallStaticVoidMethod(env, jni_EDRJniInterface, jni_EDRInterfaceDestroyMethod);

    if ((*env)->ExceptionCheck(env))
    {
        OIC_LOG(ERROR, TAG, "destroyEdrInterface has failed");
        (*env)->ExceptionDescribe(env);
        (*env)->ExceptionClear(env);
        goto error_exit;
    }

    OIC_LOG(DEBUG, TAG, "Destroy instance for CaEdrInterface");

    if (isAttached)
    {
        (*g_jvm)->DetachCurrentThread(g_jvm);
    }

    return CA_STATUS_OK;

error_exit:

    if (isAttached)
    {
        (*g_jvm)->DetachCurrentThread(g_jvm);
    }

    return CA_STATUS_FAILED;
}
示例#30
0
void CABleGattConnectionStateChangedCb(int result, bool connected,
                                       const char *remoteAddress, void *userData)
{
    OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "IN ");

    OIC_LOG_V(DEBUG, TZ_BLE_CLIENT_TAG, "CABleGattConnectionStateChangedCb result[%d] ", result);

    VERIFY_NON_NULL_VOID(remoteAddress, TZ_BLE_CLIENT_TAG, "remote address is NULL");

    CAResult_t ret = CA_STATUS_FAILED;
    if (!connected)
    {
        OIC_LOG_V(DEBUG, TZ_BLE_CLIENT_TAG, "DisConnected from [%s] ", remoteAddress);

        ret = CABleGattStartDeviceDiscovery();
        if (CA_STATUS_OK != ret)
        {
            OIC_LOG(ERROR, TZ_BLE_CLIENT_TAG, "CABleGattStartDeviceDiscovery failed");
            return;
        }
    }
    else
    {
        OIC_LOG_V(DEBUG, TZ_BLE_CLIENT_TAG, "Connected to [%s] ", remoteAddress);

        ca_mutex_lock(g_bleServerBDAddressMutex);

        g_remoteAddress = OICStrdup(remoteAddress);

        ca_mutex_unlock(g_bleServerBDAddressMutex);

        VERIFY_NON_NULL_VOID(g_remoteAddress, TZ_BLE_CLIENT_TAG, "Malloc failed");

        char *addr = OICStrdup(remoteAddress);

        ca_mutex_lock(g_bleClientThreadPoolMutex);
        if (NULL == g_bleClientThreadPool)
        {
            OIC_LOG(ERROR, TZ_BLE_CLIENT_TAG, "g_bleClientThreadPool is NULL");
            OICFree(addr);

            ca_mutex_lock(g_bleServerBDAddressMutex);
            OICFree(g_remoteAddress);
            ca_mutex_unlock(g_bleServerBDAddressMutex);

            ca_mutex_unlock(g_bleClientThreadPoolMutex);
            return;
        }

        ret = ca_thread_pool_add_task(g_bleClientThreadPool, CADiscoverBLEServicesThread,
                                     addr);
        if (CA_STATUS_OK != ret)
        {
            OIC_LOG_V(ERROR, TZ_BLE_CLIENT_TAG, "ca_thread_pool_add_task failed with ret [%d]", ret);
            OICFree(addr);

            ca_mutex_lock(g_bleServerBDAddressMutex);
            OICFree(g_remoteAddress);
            ca_mutex_unlock(g_bleServerBDAddressMutex);

            ca_mutex_unlock(g_bleClientThreadPoolMutex);
            return;
        }
        ca_mutex_unlock(g_bleClientThreadPoolMutex);
    }

    OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "OUT");
}