Пример #1
0
CAResult_t CAStartLEGattServer()
{
    OIC_LOG(DEBUG, TZ_BLE_SERVER_TAG, "IN");

    CAResult_t ret = CAInitGattServerMutexVariables();
    if (CA_STATUS_OK != ret )
    {
        OIC_LOG(ERROR, TZ_BLE_SERVER_TAG, "CAInitGattServerMutexVariables failed!");
        CATerminateGattServerMutexVariables();
        return CA_SERVER_NOT_STARTED;
    }

    ca_mutex_lock(g_bleServerThreadPoolMutex);
    if (NULL == g_bleServerThreadPool)
    {
        OIC_LOG(ERROR, TZ_BLE_SERVER_TAG, "g_bleServerThreadPool is NULL");
        ca_mutex_unlock(g_bleServerThreadPoolMutex);
        return CA_STATUS_FAILED;
    }

    ret = ca_thread_pool_add_task(g_bleServerThreadPool, CAStartBleGattServerThread,
                                 NULL);
    if (CA_STATUS_OK != ret)
    {
        OIC_LOG_V(ERROR, TZ_BLE_SERVER_TAG, "ca_thread_pool_add_task failed with ret [%d]", ret);
        ca_mutex_unlock(g_bleServerThreadPoolMutex);
        return CA_STATUS_FAILED;
    }

    ca_mutex_unlock(g_bleServerThreadPoolMutex);
    OIC_LOG(DEBUG, TZ_BLE_SERVER_TAG, "OUT");
    return CA_STATUS_OK;
}
Пример #2
0
CAResult_t CAStartLEGattServer()
{
    OIC_LOG(DEBUG, TAG, "IN");

    ca_mutex_lock(g_leServerThreadPoolMutex);
    if (NULL == g_leServerThreadPool)
    {
        OIC_LOG(ERROR, TAG, "g_leServerThreadPool is NULL");
        ca_mutex_unlock(g_leServerThreadPoolMutex);
        return CA_STATUS_FAILED;
    }

    CAResult_t ret = ca_thread_pool_add_task(g_leServerThreadPool, CAStartLEGattServerThread,
                                             NULL);
    if (CA_STATUS_OK != ret)
    {
        OIC_LOG_V(ERROR, TAG, "ca_thread_pool_add_task failed with ret [%d]", ret);
        ca_mutex_unlock(g_leServerThreadPoolMutex);
        return CA_STATUS_FAILED;
    }

    ca_mutex_unlock(g_leServerThreadPoolMutex);
    OIC_LOG(DEBUG, TAG, "OUT");
    return CA_STATUS_OK;
}
Пример #3
0
CAResult_t CAEDRServerStartAcceptThread()
{
    bool isAttached = false;
    JNIEnv* env = NULL;
    jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
    if (JNI_OK != res)
    {
        OIC_LOG(DEBUG, TAG, "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_FAILED;
        }
        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);
    }

    oc_mutex_lock(g_mutexStateList);
    CAEDRNativeCreateDeviceStateList();
    oc_mutex_unlock(g_mutexStateList);

    oc_mutex_lock(g_mutexObjectList);
    CAEDRNativeCreateDeviceSocketList();
    oc_mutex_unlock(g_mutexObjectList);

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

    CAAdapterReceiveThreadContext_t *ctx = (CAAdapterReceiveThreadContext_t *) OICMalloc(
            sizeof(CAAdapterReceiveThreadContext_t));
    if (!ctx)
    {
        OIC_LOG(ERROR, TAG, "Out of memory!");
        return CA_MEMORY_ALLOC_FAILED;
    }

    ctx->stopFlag = &g_stopAccept;
    if (CA_STATUS_OK != ca_thread_pool_add_task(g_threadPoolHandle, CAAcceptHandler,
                                                (void *) ctx, NULL))
    {
        OIC_LOG(ERROR, TAG, "Failed to create read thread!");
        OICFree((void *) ctx);
        return CA_STATUS_FAILED;
    }

    return CA_STATUS_OK;
}
Пример #4
0
void CABleGattDescriptorDiscoveredCb(int result, unsigned char format, int total,
                                     bt_gatt_attribute_h descriptor,
                                     bt_gatt_attribute_h characteristic, void *userData)
{
    OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "IN");

    stGattCharDescriptor_t *stTemp = (stGattCharDescriptor_t *)OICCalloc(1, sizeof(
                                                                         stGattCharDescriptor_t));

    VERIFY_NON_NULL_VOID(stTemp, TZ_BLE_CLIENT_TAG, "malloc failed!");

    stTemp->desc = (uint8_t *)OICMalloc(total);
    if (NULL == stTemp->desc)
    {
        OIC_LOG(ERROR, TZ_BLE_CLIENT_TAG, "malloc failed");
        OICFree(stTemp);
        return;
    }
    memcpy(stTemp->desc, descriptor, total);

    OIC_LOG_V(DEBUG, TZ_BLE_CLIENT_TAG, "result[%d] format[%d] total[%d]", result, format, total);
    OIC_LOG_V(DEBUG, TZ_BLE_CLIENT_TAG, "characteristic [%s]", (const char *) characteristic);


    bt_gatt_clone_attribute_handle(&(stTemp->characteristic), characteristic);
    stTemp->total = total;

    ca_mutex_lock(g_bleClientThreadPoolMutex);
    if (NULL == g_bleClientThreadPool)
    {
        OIC_LOG(ERROR, TZ_BLE_CLIENT_TAG, "g_bleClientThreadPool is NULL");
        bt_gatt_destroy_attribute_handle(stTemp->characteristic);
        OICFree(stTemp->desc);
        OICFree(stTemp);
        ca_mutex_unlock(g_bleClientThreadPoolMutex);
        return;
    }

    CAResult_t ret = ca_thread_pool_add_task(g_bleClientThreadPool,
                                            CASetCharacteristicDescriptorValueThread,
                                            stTemp);
    if (CA_STATUS_OK != ret)
    {
        OIC_LOG(ERROR, TZ_BLE_CLIENT_TAG, "ca_thread_pool_add_task failed");
        bt_gatt_destroy_attribute_handle(stTemp->characteristic);
        OICFree(stTemp->desc);
        OICFree(stTemp);
        ca_mutex_unlock(g_bleClientThreadPoolMutex);
        return;
    }

    OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG,
            "LE Client initialization flow complete");

    ca_mutex_unlock(g_bleClientThreadPoolMutex);

    OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "OUT");
}
CAResult_t CAEDRStartMulticastServer()
{
    OIC_LOG(DEBUG, TAG, "CAEDRStartMulticastServer");

    ca_mutex_lock(g_mutexMulticastServer);

    /**
     * The task to listen to data from multicast socket is added to the thread pool.
     * This is a blocking call is made where we try to receive some data.
     * We will keep waiting until some data is received.
     * This task will be terminated when thread pool is freed on stopping the adapters.
     * Thread context will be freed by thread on exit.
     */
    CAAdapterReceiveThreadContext_t *ctx = (CAAdapterReceiveThreadContext_t *) OICMalloc(
            sizeof(CAAdapterReceiveThreadContext_t));
    if (!ctx)
    {
        OIC_LOG(ERROR, TAG, "Out of memory!");
        ca_mutex_unlock(g_mutexMulticastServer);

        return CA_MEMORY_ALLOC_FAILED;
    }

    ctx->stopFlag = &g_stopMulticast;
    ctx->type = CA_MULTICAST_SERVER;

    g_stopMulticast = false;
    if (CA_STATUS_OK != ca_thread_pool_add_task(g_threadPoolHandle, CAReceiveHandler, (void *) ctx))
    {
        OIC_LOG(ERROR, TAG, "thread_pool_add_task failed!");

        g_stopMulticast = true;
        ca_mutex_unlock(g_mutexMulticastServer);
        OICFree((void *) ctx);

        return CA_STATUS_FAILED;
    }
    ca_mutex_unlock(g_mutexMulticastServer);

    OIC_LOG(DEBUG, TAG, "OUT");
    return CA_STATUS_OK;
}
Пример #6
0
static CAResult_t CAIPStartPacketReceiverHandler()
{
    OIC_LOG(DEBUG, IP_SERVER_TAG, "IN");

    ca_mutex_lock(g_mutexServerInfoList);

    uint32_t listLength = u_arraylist_length(g_serverInfoList);

    ca_mutex_unlock(g_mutexServerInfoList);

    ca_mutex_lock(g_mutexAdapterServerContext);

    if (!g_adapterIPServerContext)
    {
        OIC_LOG(ERROR, IP_SERVER_TAG, "g_adapterIPServerContext NULL");
        ca_mutex_unlock(g_mutexAdapterServerContext);
        return CA_STATUS_FAILED;
    }

    if (1 == listLength) //Its first time.
    {
        g_packetHandlerStopFlag = false;
        if (CA_STATUS_OK != ca_thread_pool_add_task(g_adapterIPServerContext->threadPool,
                                                   CAReceiveHandler, NULL ))
        {
            OIC_LOG(ERROR, IP_SERVER_TAG, "thread_pool_add_task failed!");
            ca_mutex_unlock(g_mutexAdapterServerContext);
            return CA_STATUS_FAILED;
        }
        OIC_LOG(DEBUG, IP_SERVER_TAG, "CAReceiveHandler thread started successfully.");
    }
    else
    {
        OIC_LOG(DEBUG, IP_SERVER_TAG, "CAReceiveHandler thread already is running");
    }
    ca_mutex_unlock(g_mutexAdapterServerContext);

    OIC_LOG(DEBUG, IP_SERVER_TAG, "OUT");

    return CA_STATUS_OK;
}
Пример #7
0
CAResult_t CAEDRStartReceiveThread(bool isSecured)
{
    OIC_LOG(DEBUG, TAG, "CAEDRStartReceiveThread");

    oc_mutex_lock(g_mutexReceiveServer);

    /**
     * The task to listen for data from unicast is added to the thread pool.
     * This is a blocking call is made where we try to receive some data..
     * We will keep waiting until some data is received.
     * This task will be terminated when thread pool is freed on stopping the adapters.
     * Thread context will be freed by thread on exit.
     */
    CAAdapterReceiveThreadContext_t *ctx = (CAAdapterReceiveThreadContext_t *) OICMalloc(
            sizeof(CAAdapterReceiveThreadContext_t));
    if (!ctx)
    {
        OIC_LOG(ERROR, TAG, "Out of memory!");
        oc_mutex_unlock(g_mutexReceiveServer);
        return CA_MEMORY_ALLOC_FAILED;
    }

    g_stopUnicast = false;
    ctx->stopFlag = &g_stopUnicast;
    ctx->type = isSecured ? CA_SECURED_UNICAST_SERVER : CA_UNICAST_SERVER;
    if (CA_STATUS_OK != ca_thread_pool_add_task(g_threadPoolHandle, CAReceiveHandler,
                                                (void *) ctx, NULL))
    {
        OIC_LOG(ERROR, TAG, "Failed to create read thread!");
        oc_mutex_unlock(g_mutexReceiveServer);
        OICFree((void *) ctx);
        return CA_STATUS_FAILED;
    }
    oc_mutex_unlock(g_mutexReceiveServer);

    OIC_LOG(DEBUG, TAG, "OUT");
    return CA_STATUS_OK;
}
Пример #8
0
CAResult_t CAEDRStartNetworkMonitor()
{
    OIC_LOG(DEBUG, EDR_ADAPTER_TAG, "IN");

    g_mainloop = g_main_loop_new(NULL, 0);
    if(!g_mainloop)
    {
        OIC_LOG(ERROR, EDR_ADAPTER_TAG, "g_main_loop_new failed\n");
        return CA_STATUS_FAILED;
    }

    if (CA_STATUS_OK != ca_thread_pool_add_task(g_threadPoolHandle, GMainLoopThread, (void *) NULL))
    {
        OIC_LOG(ERROR, EDR_ADAPTER_TAG, "Failed to create thread!");
        return CA_STATUS_FAILED;
    }

    // Initialize Bluetooth service
    int err = bt_initialize();
    if (BT_ERROR_NONE != err)
    {
        OIC_LOG_V(ERROR, EDR_ADAPTER_TAG, "Bluetooth initialization failed!, error num [%x]",
                  err);
        return CA_STATUS_FAILED;
    }

    int ret = bt_adapter_set_state_changed_cb(CAEDRAdapterStateChangeCallback, NULL);
    if(BT_ERROR_NONE != ret)
    {
       OIC_LOG(ERROR, EDR_ADAPTER_TAG, "bt_adapter_set_state_changed_cb failed");
       return CA_STATUS_FAILED;
    }

    OIC_LOG(DEBUG, EDR_ADAPTER_TAG, "OUT");
    return CA_STATUS_OK;
}
Пример #9
0
CAResult_t CAStartLEGattClient()
{
    OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "IN");

    CAResult_t retVal = CAInitGattClientMutexVariables();

    if (CA_STATUS_OK != retVal)
    {
        OIC_LOG(ERROR, TZ_BLE_CLIENT_TAG, "CAInitGattClientMutexVariables failed!");
        CATerminateGattClientMutexVariables();
        return CA_STATUS_FAILED;
    }

    ca_mutex_lock(g_bleClientThreadPoolMutex);
    if (NULL == g_bleClientThreadPool)
    {
        OIC_LOG(ERROR, TZ_BLE_CLIENT_TAG, "gBleServerThreadPool is NULL");
        CATerminateGattClientMutexVariables();
        ca_mutex_unlock(g_bleClientThreadPoolMutex);
        return CA_STATUS_FAILED;
    }

    retVal = ca_thread_pool_add_task(g_bleClientThreadPool, CAStartBleGattClientThread,
                                     NULL);
    if (CA_STATUS_OK != retVal)
    {
        OIC_LOG(ERROR, TZ_BLE_CLIENT_TAG, "ca_thread_pool_add_task failed");
        CATerminateGattClientMutexVariables();
        ca_mutex_unlock(g_bleClientThreadPoolMutex);
        return CA_STATUS_FAILED;
    }
    ca_mutex_unlock(g_bleClientThreadPoolMutex);

    OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "OUT");
    return CA_STATUS_OK;
}
Пример #10
0
void CAEDRNotifyNetworkStatus(CANetworkStatus_t status)
{
    OIC_LOG(DEBUG, EDR_ADAPTER_TAG, "IN");

    // Create localconnectivity
    if (NULL == g_localConnectivity)
    {
        CAEDRGetInterfaceInformation(&g_localConnectivity);
    }

    if (CA_INTERFACE_UP == status)
    {
        if (false == g_adapterState)
        {
            // Get Bluetooth adapter state
            bool adapterState = false;
            if (CA_STATUS_OK != CAEDRGetAdapterEnableState(&adapterState))
            {
                OIC_LOG(ERROR, EDR_ADAPTER_TAG, "Failed to get adapter enable state");
                return;
            }

            if (false== adapterState)
            {
                OIC_LOG(ERROR, EDR_ADAPTER_TAG, "Bluetooth adapter is disabled!");
                g_adapterState = false;
                return;
            }
            CAEDRClientSetCallbacks();
            g_adapterState = true;
            CAAdapterStartQueue();
            // starting RFCommServer
            if (true == g_serverState)
            {
                CAStartServer();
                g_serverState = false;
            }
        }
    }
    else
    {
        g_adapterState = false;
    }

    // Notify to upper layer
    if (g_networkChangeCallback && g_localConnectivity && g_edrThreadPool)
    {
        // Add notification task to thread pool
        CAEDRNetworkEvent *event = CAEDRCreateNetworkEvent(g_localConnectivity, status);
        if (NULL != event)
        {
            if (CA_STATUS_OK != ca_thread_pool_add_task(g_edrThreadPool,
                                                        CAEDROnNetworkStatusChanged,event))
            {
                OIC_LOG(ERROR, EDR_ADAPTER_TAG, "Failed to create threadpool!");
                return;
            }
        }
    }

    OIC_LOG_V(DEBUG, EDR_ADAPTER_TAG, "OUT");
}
Пример #11
0
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;
}
Пример #12
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");
}
Пример #13
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");
}
Пример #14
0
bool CABleGattPrimaryServiceCb(bt_gatt_attribute_h service, int index, int count,
                               void *userData)
{
    OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "IN");

    VERIFY_NON_NULL_RET(service, TZ_BLE_CLIENT_TAG, "Param service is NULL", false);

    VERIFY_NON_NULL_RET(userData, TZ_BLE_CLIENT_TAG, "Param userData is NULL", false);

    OIC_LOG_V(DEBUG, TZ_BLE_CLIENT_TAG, "Service info [%s] index [%d] count [%d]", (char *)service,
              index, count);

    CAResult_t result = CAVerifyOICServiceByServiceHandle(service);

    if (CA_STATUS_OK == result)
    {
        OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "Its OIC service");

        OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG , "Registering to watch characteristics changes");

        result = CABleGattWatchCharacteristicChanges(service);
        if (CA_STATUS_OK != result)
        {
            OIC_LOG(ERROR, TZ_BLE_CLIENT_TAG,
                      "CABleGattWatchCharacteristicChanges failed!");
            return false;
        }

        stGattServiceInfo_t *stTemp = (stGattServiceInfo_t *)OICCalloc(1,
                                                                      sizeof(stGattServiceInfo_t));
        VERIFY_NON_NULL_RET(stTemp, TZ_BLE_CLIENT_TAG, "Calloc Failed", false);

        char *bdAddress = (char *)userData;

        stTemp->address = OICStrdup(bdAddress);
        if (NULL == stTemp->address)
        {
            OIC_LOG(ERROR, TZ_BLE_CLIENT_TAG , "Malloc failed!");
            OICFree(stTemp);
            return false;
        }

        BLEServiceInfo *bleServiceInfo = NULL;

        result = CACreateBLEServiceInfo(bdAddress, service, &bleServiceInfo);
        if (CA_STATUS_OK != result)
        {
            OIC_LOG(ERROR, TZ_BLE_CLIENT_TAG , "CACreateBLEServiceInfo failed! ");
            OICFree(stTemp->address);
            OICFree(stTemp);
            OICFree(bleServiceInfo);
            return false;
        }
        if (NULL == bleServiceInfo )
        {
            OIC_LOG(ERROR, TZ_BLE_CLIENT_TAG , " bleServiceInfo is NULL");
            OICFree(stTemp->address);
            OICFree(stTemp);
            OICFree(bleServiceInfo);
            return false;
        }

        OIC_LOG_V(DEBUG, TZ_BLE_CLIENT_TAG ,
                  " serviceInfo remote address [%s]", bleServiceInfo->bdAddress);

        ca_mutex_lock(g_bleServiceListMutex);
        result = CAAddBLEServiceInfoToList(&g_bLEServiceList, bleServiceInfo);
        ca_mutex_unlock(g_bleServiceListMutex);
        if (CA_STATUS_OK != result)
        {
            OIC_LOG(ERROR, TZ_BLE_CLIENT_TAG , "CAAddBLEServiceInfoToList failed!");
            OICFree(stTemp->address);
            OICFree(stTemp);
            CAFreeBLEServiceInfo(bleServiceInfo);
            return false;
        }


        ca_mutex_lock(g_bleClientThreadPoolMutex);
        if (NULL == g_bleClientThreadPool)
        {
            OIC_LOG(ERROR, TZ_BLE_CLIENT_TAG, "g_bleClientThreadPool is NULL");
            OICFree(stTemp->address);
            OICFree(stTemp);
            ca_mutex_lock(g_bleServiceListMutex);
            CARemoveBLEServiceInfoToList(&g_bLEServiceList, bleServiceInfo,
                                         bleServiceInfo->bdAddress);
            ca_mutex_unlock(g_bleServiceListMutex);
            ca_mutex_unlock(g_bleClientThreadPoolMutex);
            return false;
        }
        bt_gatt_clone_attribute_handle(&(stTemp->serviceInfo), service);

        result = ca_thread_pool_add_task(g_bleClientThreadPool,
                                        CADiscoverCharThread,
                                        stTemp);
        if (CA_STATUS_OK != result)
        {
            OIC_LOG_V(ERROR, TZ_BLE_CLIENT_TAG,
                      "ca_thread_pool_add_task failed with ret [%d]", result);
            OICFree(stTemp->address);
            OICFree(stTemp);
            ca_mutex_lock(g_bleServiceListMutex);
            CARemoveBLEServiceInfoToList(&g_bLEServiceList, bleServiceInfo,
                                         bleServiceInfo->bdAddress);
            ca_mutex_unlock(g_bleServiceListMutex);
            ca_mutex_unlock(g_bleClientThreadPoolMutex);
            return false;
        }
        ca_mutex_unlock(g_bleClientThreadPoolMutex);
    }

    OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "OUT ");
    return true;;
}
Пример #15
0
bool CABleGattCharacteristicsDiscoveredCb(int result,
        int inputIndex, int total,
        bt_gatt_attribute_h characteristic, void *userData)
{

    OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "IN");

    VERIFY_NON_NULL_RET(characteristic, TZ_BLE_CLIENT_TAG, "Param characteristic is NULL", false);

    VERIFY_NON_NULL_RET(userData, TZ_BLE_CLIENT_TAG, "Param userData is NULL", false);

    OIC_LOG_V(DEBUG, TZ_BLE_CLIENT_TAG,
              "result [%d] input_index [%d] total [%d]",
              result, inputIndex, total);

    BLEServiceInfo *bleServiceInfo = NULL;

    ca_mutex_lock(g_bleServiceListMutex);

    char *bdAddress = (char *) userData;
    CAGetBLEServiceInfo(g_bLEServiceList, bdAddress, &bleServiceInfo);

    ca_mutex_unlock(g_bleServiceListMutex);

    char *uuid = NULL;
    bt_gatt_get_service_uuid(characteristic, &uuid);

    VERIFY_NON_NULL_RET(uuid, TZ_BLE_CLIENT_TAG, "uuid is NULL", false);

    OIC_LOG_V(DEBUG, TZ_BLE_CLIENT_TAG, "New Characteristics[%s] of uuid[%s] is obtained",
              (char *)characteristic, uuid);

    if(0 == strcasecmp(uuid, CA_GATT_RESPONSE_CHRC_UUID)) // Server will read on this characterisctics
    {
        OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG , "Read characteristics is obtained");
        OICFree(uuid);
        CAResult_t retVal = CAAppendBLECharInfo(characteristic, BLE_GATT_READ_CHAR, bleServiceInfo);
        if (CA_STATUS_OK != retVal)
        {
            OIC_LOG(ERROR, TZ_BLE_CLIENT_TAG , "CAAppendBLECharInfo failed! ");
            return false;
        }

        stGattServiceInfo_t *stTemp = (stGattServiceInfo_t *)OICCalloc(1,
                                                                      sizeof(stGattServiceInfo_t));

        VERIFY_NON_NULL_RET(stTemp, TZ_BLE_CLIENT_TAG, "calloc failed!", false);

        stTemp->address = OICStrdup(bdAddress);
        if (NULL == stTemp->address)
        {
            OIC_LOG(ERROR, TZ_BLE_CLIENT_TAG , "Malloc failed!");
            OICFree(stTemp);
            return false;
        }

        bt_gatt_clone_attribute_handle(&(stTemp->serviceInfo), characteristic);

        ca_mutex_lock(g_bleClientThreadPoolMutex);
        if (NULL == g_bleClientThreadPool)
        {
            OIC_LOG(ERROR, TZ_BLE_CLIENT_TAG, "g_bleClientThreadPool is NULL");
            bt_gatt_destroy_attribute_handle(stTemp->serviceInfo);
            OICFree(stTemp->address);
            OICFree(stTemp);
            ca_mutex_unlock(g_bleClientThreadPoolMutex);
            return false;
        }

        retVal = ca_thread_pool_add_task(g_bleClientThreadPool,
                                        CADiscoverDescriptorThread,
                                        stTemp);
        if (CA_STATUS_OK != retVal)
        {
            OIC_LOG_V(ERROR, TZ_BLE_CLIENT_TAG,
                      "ca_thread_pool_add_task failed with ret [%d]", retVal);
            bt_gatt_destroy_attribute_handle(stTemp->serviceInfo);
            OICFree(stTemp->address);
            OICFree(stTemp);
            ca_mutex_unlock(g_bleClientThreadPoolMutex);
            return false;
        }
        ca_mutex_unlock(g_bleClientThreadPoolMutex);
    }
    else if (0 == strcasecmp(uuid, CA_GATT_REQUEST_CHRC_UUID)) // Server will write on this characteristics.
    {
        OICFree(uuid);
        OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG , "Write characteristics is obtained");
        CAResult_t retVal = CAAppendBLECharInfo(characteristic, BLE_GATT_WRITE_CHAR, bleServiceInfo);
        if (CA_STATUS_OK != retVal)
        {
            OIC_LOG(ERROR, TZ_BLE_CLIENT_TAG , "CAAppendBLECharInfo failed ");
            return false;
        }
    }
    else
    {
        OICFree(uuid);
        OIC_LOG(ERROR, TZ_BLE_CLIENT_TAG , "service_uuid characteristics is UNKNOWN");
        return false;
    }

    OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "OUT");
    return true;
}
Пример #16
0
CAResult_t CAPeripheralStart(CALEContext * context)
{
    /**
     * @todo Bluetooth adapters that are hot-plugged after the
     *       peripheral has started will not be started!
     */

    CAResult_t result = CA_STATUS_FAILED;

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

    if (!CAPeripheralAdaptersFound(context))
    {
        // No Bluetooth adapters.  Don't bother continuing.
        return result;
    }

    /*
      Spawn a thread to run the Glib event loop that will drive D-Bus
      signal handling.
     */
    result = ca_thread_pool_add_task(context->server_thread_pool,
                                     CAPeripheralStartEventLoop,
                                     context);

    if (result != CA_STATUS_OK)
    {
        return result;
    }

    /*
      Wait until initialization completes before proceeding to
      service and advertisement registration.
    */

    // Number of times to wait for initialization to complete.
    static int const max_retries = 2;

    static uint64_t const timeout =
        2 * MICROSECS_PER_SEC;  // Microseconds

    ca_mutex_lock(g_context.lock);

    for (int i = 0;
         g_context.gatt_services == NULL && i < max_retries;
         ++i)
    {
        if (ca_cond_wait_for(g_context.condition,
                             g_context.lock,
                             timeout) == CA_WAIT_SUCCESS)
        {
            result = CA_STATUS_OK;
        }
    }

    ca_mutex_unlock(g_context.lock);

    if (result != CA_STATUS_OK)
    {
        return result;
    }

    /**
     * First register the GATT services, then register the LE
     * advertisments with BlueZ to make sure the service we're
     * advertising actually exists.
     */
    if (result == CA_STATUS_OK
        && !(CAPeripheralRegisterGattServices(&g_context)
             && CAPeripheralRegisterAdvertisements(&g_context)))
    {
        result = CA_STATUS_FAILED;
    }

    /*
      Make the local bluetooth adapters discoverable over LE by
      enabling LE, enabling advertising, and making the LE device
      connectable.
    */
    result = CAPeripheralSetDiscoverability(context,
                                            CAPeripheralMakeDiscoverable);

    return result;
}
Пример #17
0
CAResult_t CAIPStartServer(const ca_thread_pool_t threadPool)
{
    CAResult_t res = CA_STATUS_OK;

    if (caglobals.ip.started)
    {
        return res;
    }

    if (!IPv4MulticastAddress.s_addr)
    {
        (void)inet_aton(IPv4_MULTICAST, &IPv4MulticastAddress);
        (void)inet_pton(AF_INET6, IPv6_MULTICAST_INT, &IPv6MulticastAddressInt);
        (void)inet_pton(AF_INET6, IPv6_MULTICAST_LNK, &IPv6MulticastAddressLnk);
        (void)inet_pton(AF_INET6, IPv6_MULTICAST_RLM, &IPv6MulticastAddressRlm);
        (void)inet_pton(AF_INET6, IPv6_MULTICAST_ADM, &IPv6MulticastAddressAdm);
        (void)inet_pton(AF_INET6, IPv6_MULTICAST_SIT, &IPv6MulticastAddressSit);
        (void)inet_pton(AF_INET6, IPv6_MULTICAST_ORG, &IPv6MulticastAddressOrg);
        (void)inet_pton(AF_INET6, IPv6_MULTICAST_GLB, &IPv6MulticastAddressGlb);
    }

    if (!caglobals.ip.ipv6enabled && !caglobals.ip.ipv4enabled)
    {
        caglobals.ip.ipv4enabled = true;  // only needed to run CA tests
    }

    if (caglobals.ip.ipv6enabled)
    {
        NEWSOCKET(AF_INET6, u6)
        NEWSOCKET(AF_INET6, u6s)
        NEWSOCKET(AF_INET6, m6)
        NEWSOCKET(AF_INET6, m6s)
        OIC_LOG_V(INFO, TAG, "IPv6 unicast port: %u", caglobals.ip.u6.port);
    }
    if (caglobals.ip.ipv4enabled)
    {
        NEWSOCKET(AF_INET, u4)
        NEWSOCKET(AF_INET, u4s)
        NEWSOCKET(AF_INET, m4)
        NEWSOCKET(AF_INET, m4s)
        OIC_LOG_V(INFO, TAG, "IPv4 unicast port: %u", caglobals.ip.u4.port);
    }

    OIC_LOG_V(DEBUG, TAG,
              "socket summary: u6=%d, u6s=%d, u4=%d, u4s=%d, m6=%d, m6s=%d, m4=%d, m4s=%d",
                             caglobals.ip.u6.fd, caglobals.ip.u6s.fd,
                             caglobals.ip.u4.fd, caglobals.ip.u4s.fd,
                             caglobals.ip.m6.fd, caglobals.ip.m6s.fd,
                             caglobals.ip.m4.fd, caglobals.ip.m4s.fd);

    // create pipe for fast shutdown
    CAInitializePipe();
    CHECKFD(caglobals.ip.shutdownFds[0]);
    CHECKFD(caglobals.ip.shutdownFds[1]);

    // create source of network interface change notifications
    CAInitializeNetlink();

    caglobals.ip.selectTimeout = CAGetPollingInterval(caglobals.ip.selectTimeout);

    CAApplyInterfaces();

    caglobals.ip.terminate = false;
    res = ca_thread_pool_add_task(threadPool, CAReceiveHandler, NULL);
    if (CA_STATUS_OK != res)
    {
        OIC_LOG(ERROR, TAG, "thread_pool_add_task failed");
        return res;
    }
    OIC_LOG(DEBUG, TAG, "CAReceiveHandler thread started successfully.");

    caglobals.ip.started = true;
    return CA_STATUS_OK;
}
Пример #18
0
void testThreadPool(void)
{
    char *string = "Test thread pool";

    //Initialize the mutex
    printf("[testThreadPool] Initializing mutex\n");

    //Initialize the thread pool
    printf("[testThreadPool] Initializing thread pool\n");
    if (CA_STATUS_OK != ca_thread_pool_init(2, &g_threadPoolHandle))
    {
        printf("thread_pool_init failed!\n");
        return;
    }

    //Create the mutex
    printf("[testThreadPool] Creating mutex\n");
    g_mutex = ca_mutex_new();
    if (NULL == g_mutex)
    {
        printf("[testThreadPool] Failed to create mutex!\n");
        ca_thread_pool_free(g_threadPoolHandle);
        return;
    }

    //Create the condition
    printf("[testThreadPool] Creating Condition\n");
    g_cond = ca_cond_new();
    if (NULL == g_cond)
    {
        printf("[testThreadPool] Failed to create condition!\n");
        ca_mutex_free(g_mutex);
        ca_thread_pool_free(g_threadPoolHandle);
        return;
    }

    //Lock the mutex
    printf("[testThreadPool] Locking the mutex\n");
    ca_mutex_lock(g_mutex);

    g_condFlag = false;
    //Add task to thread pool
    printf("[testThreadPool] Adding the task to thread pool\n");
    if (CA_STATUS_OK != ca_thread_pool_add_task(g_threadPoolHandle, task, (void *) string))
    {
        printf("[testThreadPool] thread_pool_add_task failed!\n");
        ca_thread_pool_free(g_threadPoolHandle);
        ca_mutex_unlock(g_mutex);
        ca_mutex_free(g_mutex);
        ca_cond_free(g_cond);
        return;
    }

    //Wait for the task to be executed
    printf("[testThreadPool] Waiting for the task to be completed\n");

    while (!g_condFlag)
    {
        ca_cond_wait(g_cond, g_mutex);
    }

    //Unlock the mutex
    printf("[testThreadPool] Got the signal and unlock the mutex\n");
    ca_mutex_unlock(g_mutex);

    printf("[testThreadPool] Task is completed and terminating threadpool\n");
    ca_cond_free(g_cond);
    ca_mutex_free(g_mutex);
    ca_thread_pool_free(g_threadPoolHandle);

    printf("Exiting from testThreadPool\n");
}