Exemple #1
0
//--------------------------------------------------------------------------------------------------
void le_antenna_Init
(
    void
)
{
    // Create safe reference map for antenna references.
    AntennaRefMap = le_ref_CreateMap("AntennaRef", LE_ANTENNA_MAX);

    memset( AntennaCtx, 0, LE_ANTENNA_MAX*sizeof(AntennaCtx_t) );

    pa_antenna_AddStatusHandler ( AntennaStatus );

    // Init the context
    le_antenna_Type_t antenna;

    for (antenna = LE_ANTENNA_PRIMARY_CELLULAR; antenna < LE_ANTENNA_MAX; antenna++)
    {
        char eventName[32];
        snprintf(eventName, sizeof(eventName), "AntennaStatus_%d", antenna);

        AntennaCtx[antenna].antennaType = antenna;
        AntennaCtx[antenna].antennaRef = le_ref_CreateRef(AntennaRefMap, &AntennaCtx[antenna]);
        AntennaCtx[antenna].statusEventId = le_event_CreateId(
                                            eventName,
                                            sizeof(pa_antenna_StatusInd_t));
        AntennaCtx[antenna].statusEventHandlerRef = NULL;
    }
}
Exemple #2
0
static void Handle_AddTestAHandler
(
    le_msg_MessageRef_t _msgRef

)
{
    // Get the message buffer pointer
    uint8_t* _msgBufPtr = ((_Message_t*)le_msg_GetPayloadPtr(_msgRef))->buffer;

    // Needed if we are returning a result or output values
    uint8_t* _msgBufStartPtr = _msgBufPtr;

    // Unpack the input parameters from the message


    void* contextPtr;
    _msgBufPtr = UnpackData( _msgBufPtr, &contextPtr, sizeof(void*) );

    // Create a new server data object and fill it in
    _ServerData_t* serverDataPtr = le_mem_ForceAlloc(_ServerDataPool);
    serverDataPtr->clientSessionRef = le_msg_GetSession(_msgRef);
    serverDataPtr->contextPtr = contextPtr;
    serverDataPtr->handlerRef = NULL;
    serverDataPtr->removeHandlerFunc = NULL;
    contextPtr = serverDataPtr;

    // Define storage for output parameters


    // Call the function
    TestAHandlerRef_t _result;
    _result = AddTestAHandler ( AsyncResponse_AddTestAHandler, contextPtr );

    // Put the handler reference result and a pointer to the associated remove function
    // into the server data object.  This function pointer is needed in case the client
    // is closed and the handlers need to be removed.
    serverDataPtr->handlerRef = (le_event_HandlerRef_t)_result;
    serverDataPtr->removeHandlerFunc = (RemoveHandlerFunc_t)RemoveTestAHandler;

    // Return a safe reference to the server data object as the reference.
    _LOCK
    _result = le_ref_CreateRef(_HandlerRefMap, serverDataPtr);
    _UNLOCK


    // Re-use the message buffer for the response
    _msgBufPtr = _msgBufStartPtr;

    // Pack the result first
    _msgBufPtr = PackData( _msgBufPtr, &_result, sizeof(_result) );

    // Pack any "out" parameters


    // Return the response
    LE_DEBUG("Sending response to client session %p : %ti bytes sent",
             le_msg_GetSession(_msgRef),
             _msgBufPtr-_msgBufStartPtr);
    le_msg_Respond(_msgRef);
}
Exemple #3
0
//--------------------------------------------------------------------------------------------------
le_mrc_ScanInformation_Ref_t le_mrc_GetFirstCellularNetworkScan
(
    le_mrc_ScanInformation_ListRef_t  scanInformationListRef ///< [IN] The list of scan information.
)
{
    pa_mrc_ScanInformation_t* nodePtr;
    le_dls_Link_t*          linkPtr;

    le_mrc_ScanInformationList_t* scanInformationListPtr = le_ref_Lookup(ScanInformationListRefMap,
                                                                         scanInformationListRef);

    if (scanInformationListPtr == NULL)
    {
        LE_KILL_CLIENT("Invalid reference (%p) provided!", scanInformationListRef);
        return NULL;
    }

    linkPtr = le_dls_Peek(&(scanInformationListPtr->paScanInformationList));
    if (linkPtr != NULL)
    {
        nodePtr = CONTAINER_OF(linkPtr, pa_mrc_ScanInformation_t, link);
        scanInformationListPtr->currentLink = linkPtr;

        le_mrc_ScanInformationSafeRef_t* newScanInformationPtr = le_mem_ForceAlloc(ScanInformationSafeRefPool);
        newScanInformationPtr->safeRef = le_ref_CreateRef(ScanInformationRefMap,nodePtr);
        newScanInformationPtr->link = LE_DLS_LINK_INIT;
        le_dls_Queue(&(scanInformationListPtr->safeRefScanInformationList),&(newScanInformationPtr->link));

        return (le_mrc_ScanInformation_Ref_t)newScanInformationPtr->safeRef;
    }
    else
    {
        return NULL;
    }
}
//--------------------------------------------------------------------------------------------------
le_msg_SessionEventHandlerRef_t le_msg_AddServiceCloseHandler
(
    le_msg_ServiceRef_t             serviceRef, ///< [in] Reference to the service.
    le_msg_SessionEventHandler_t    handlerFunc,///< [in] Handler function.
    void*                           contextPtr  ///< [in] Opaque pointer value to pass to handler.
)
//--------------------------------------------------------------------------------------------------
{
    LE_FATAL_IF(serviceRef == NULL,
                "Service doesn't exist. Make sure service is started before setting handlers");
    LE_FATAL_IF(serviceRef->serverThread != le_thread_GetCurrent(),
                "Service (%s:%s) not owned by calling thread.",
                serviceRef->id.name,
                le_msg_GetProtocolIdStr(serviceRef->id.protocolRef));

    // Create the node.
    SessionEventHandler_t* closeEventPtr = le_mem_ForceAlloc(HandlerEventPoolRef);

    // Initialize the node.
    closeEventPtr->handler = handlerFunc;
    closeEventPtr->contextPtr = contextPtr;
    closeEventPtr->link = LE_DLS_LINK_INIT;
    closeEventPtr->listPtr = &serviceRef->closeListPtr;

    // Add the node to the head of the list by passing in the node's link.
    le_dls_Stack(&serviceRef->closeListPtr, &closeEventPtr->link);

    // Need to return a unique reference that will be used by the remove function.
    closeEventPtr->ref = le_ref_CreateRef(HandlersRefMap, &closeEventPtr->link);

    return closeEventPtr->ref;
}
//--------------------------------------------------------------------------------------------------
le_cellnet_RequestObjRef_t le_cellnet_Request
(
    void
)
{
    uint32_t command = REQUEST_COMMAND;
    le_event_Report(CommandEvent, &command, sizeof(command));

    // Need to return a unique reference that will be used by Release.
    return le_ref_CreateRef(RequestRefMap, (void*)1);
}
Exemple #6
0
//--------------------------------------------------------------------------------------------------
le_event_FdMonitorRef_t le_event_CreateFdMonitor
(
    const char*     name,       ///< [in] Name of the object (for diagnostics).
    int             fd          ///< [in] File descriptor to be monitored for events.
)
//--------------------------------------------------------------------------------------------------
{
    // Get a pointer to the thread-specific event loop data record.
    event_PerThreadRec_t* perThreadRecPtr = thread_GetEventRecPtr();

    // Allocate the object.
    FdMonitor_t* fdMonitorPtr = le_mem_ForceAlloc(FdMonitorPool);

    // Initialize the object.
    fdMonitorPtr->link = LE_DLS_LINK_INIT;
    fdMonitorPtr->fd = fd;
    fdMonitorPtr->threadRecPtr = perThreadRecPtr;
    memset(fdMonitorPtr->handlerArray, 0, sizeof(fdMonitorPtr->handlerArray));

    // To start with, no events are in the set to be monitored.  They will be added as handlers
    // are registered for them. (Although, EPOLLHUP and EPOLLERR will always be monitored
    // regardless of what flags we specify).  We use epoll in "level-triggered mode".
    fdMonitorPtr->epollEvents = 0;

    // Assume that the event should wake up the system; can be changed later.
    fdMonitorPtr->wakeUp = true;

    // Copy the name into it.
    if (le_utf8_Copy(fdMonitorPtr->name, name, sizeof(fdMonitorPtr->name), NULL) == LE_OVERFLOW)
    {
        LE_WARN("FD Monitor object name '%s' truncated to '%s'.", name, fdMonitorPtr->name);
    }

    LOCK

    // Create a safe reference for the object.
    fdMonitorPtr->safeRef = le_ref_CreateRef(FdMonitorRefMap, fdMonitorPtr);

    // Add it to the thread's FD Monitor list.
    le_dls_Queue(&perThreadRecPtr->fdMonitorList, &fdMonitorPtr->link);

    // Tell epoll(7) to start monitoring this fd.
    struct epoll_event ev;
    ev.events = fdMonitorPtr->epollEvents;
    ev.data.ptr = fdMonitorPtr->safeRef;
    if (epoll_ctl(perThreadRecPtr->epollFd, EPOLL_CTL_ADD, fd, &ev) == -1)
    {
        LE_FATAL("epoll_ctl(ADD) failed for fd %d. errno = %d (%m)", fd, errno);
    }

    UNLOCK

    return fdMonitorPtr->safeRef;
}
Exemple #7
0
//--------------------------------------------------------------------------------------------------
static ThreadObj_t* CreateThread
(
    const char*             name,       ///< [in] Name of the thread.
    le_thread_MainFunc_t    mainFunc,   ///< [in] The thread's main function.
    void*                   context     ///< [in] Value to pass to mainFunc when it is called.
)
{
    // Create a new thread object.
    ThreadObj_t* threadPtr = le_mem_ForceAlloc(ThreadPool);

    // Copy the name.  We will make the names unique by adding the thread ID later so we allow any
    // string as the name.
    LE_WARN_IF(le_utf8_Copy(threadPtr->name, name, sizeof(threadPtr->name), NULL) == LE_OVERFLOW,
               "Thread name '%s' has been truncated to '%s'.",
               name,
               threadPtr->name);

    // Initialize the pthreads attribute structure.
    LE_ASSERT(pthread_attr_init(&(threadPtr->attr)) == 0);

    // Make sure when we create the thread it takes it attributes from the attribute object,
    // as opposed to inheriting them from its parent thread.
    if (pthread_attr_setinheritsched(&(threadPtr->attr), PTHREAD_EXPLICIT_SCHED) != 0)
    {
        LE_CRIT("Could not set scheduling policy inheritance for thread '%s'.", name);
    }

    // By default, Legato threads are not joinable (they are detached).
    if (pthread_attr_setdetachstate(&(threadPtr->attr), PTHREAD_CREATE_DETACHED) != 0)
    {
        LE_CRIT("Could not set the detached state for thread '%s'.", name);
    }

    threadPtr->isJoinable = false;
    threadPtr->isStarted = false;
    threadPtr->mainFunc = mainFunc;
    threadPtr->context = context;
    threadPtr->destructorList = LE_SLS_LIST_INIT;
    threadPtr->threadHandle = 0;

    memset(&threadPtr->mutexRec, 0, sizeof(threadPtr->mutexRec));
    memset(&threadPtr->semaphoreRec, 0, sizeof(threadPtr->semaphoreRec));
    memset(&threadPtr->eventRec, 0, sizeof(threadPtr->eventRec));
    memset(&threadPtr->timerRec, 0, sizeof(threadPtr->timerRec));

    // Create a safe reference for this object.
    Lock();
    threadPtr->safeRef = le_ref_CreateRef(ThreadRefMap, threadPtr);
    Unlock();

    return threadPtr;
}
Exemple #8
0
//--------------------------------------------------------------------------------------------------
le_mrc_ScanInformation_ListRef_t le_mrc_PerformCellularNetworkScan
(
    le_mrc_Rat_t ratMask ///< [IN] Technology mask
)
{
    le_result_t result;
    le_mrc_ScanInformationList_t* newScanInformationListPtr = NULL;
    uint32_t networkScan = 0;

    newScanInformationListPtr = le_mem_ForceAlloc(ScanInformationListPool);
    newScanInformationListPtr->paScanInformationList = LE_DLS_LIST_INIT;
    newScanInformationListPtr->safeRefScanInformationList = LE_DLS_LIST_INIT;
    newScanInformationListPtr->currentLink = NULL;

    if (ratMask == LE_MRC_RAT_ALL) {
        networkScan |= PA_MRC_METWORK_MASK_GSM;
        networkScan |= PA_MRC_METWORK_MASK_UTMS;
        networkScan |= PA_MRC_METWORK_MASK_LTE;
        networkScan |= PA_MRC_METWORK_MASK_TD_SCDMA;
    }
    else
    {
        if (ratMask&LE_MRC_RAT_GSM)
        {
            networkScan |= PA_MRC_METWORK_MASK_GSM;
        }
        if (ratMask&LE_MRC_RAT_UTMS)
        {
            networkScan |= PA_MRC_METWORK_MASK_UTMS;
        }
        if (ratMask&LE_MRC_RAT_LTE)
        {
            networkScan |= PA_MRC_METWORK_MASK_LTE;
        }
        if (ratMask&LE_MRC_RAT_TC_SCDMA)
        {
            networkScan |= PA_MRC_METWORK_MASK_LTE;
        }
    }

    result = pa_mrc_PerformNetworkScan(networkScan,PA_MRC_SCAN_PLMN,
                                       &(newScanInformationListPtr->paScanInformationList));

    if (result != LE_OK)
    {
        le_mem_Release(newScanInformationListPtr);

        return NULL;
    }

    return le_ref_CreateRef(ScanInformationListRefMap, newScanInformationListPtr);
}
Exemple #9
0
//--------------------------------------------------------------------------------------------------
le_event_FdHandlerRef_t le_event_SetFdHandler
(
    le_event_FdMonitorRef_t  monitorRef, ///< [in] Reference to the File Descriptor Monitor object.
    le_event_FdEventType_t   eventType,  ///< [in] The type of event to be reported to this handler.
    le_event_FdHandlerFunc_t handlerFunc ///< [in] The handler function.
)
//--------------------------------------------------------------------------------------------------
{
    LE_ASSERT(handlerFunc != NULL);

    // Look up the File Descriptor Monitor object using the safe reference provided.
    // Note that the safe reference map is shared by all threads in the process, so it
    // must be protected using the mutex.  The File Descriptor Monitor objects, on the other
    // hand, are only allowed to be accessed by the one thread that created them, so it is
    // safe to unlock the mutex after doing the safe reference lookup.
    LOCK
    FdMonitor_t* monitorPtr = le_ref_Lookup(FdMonitorRefMap, monitorRef);
    UNLOCK

    LE_FATAL_IF(monitorPtr == NULL, "File Descriptor Monitor %p doesn't exist!", monitorRef);
    LE_FATAL_IF(thread_GetEventRecPtr() != monitorPtr->threadRecPtr,
                "FD Monitor '%s' (fd %d) is owned by another thread.",
                monitorPtr->name,
                monitorPtr->fd);

    // Get a pointer to the Handler object in the appropriate spot for this type of event in the
    // FD Monitor's array of handlers.
    Handler_t* handlerPtr = &(monitorPtr->handlerArray[eventType]);

    // Double check that no one has tried setting this handler yet.
    LE_FATAL_IF(handlerPtr->handlerFunc != NULL,
                "FD handler already set for event '%s' on FD Monitor '%s' (fd %d).",
                GetFdEventTypeName(eventType),
                monitorPtr->name,
                monitorPtr->fd);

    // Initialize the Handler object.
    handlerPtr->handlerFunc = handlerFunc;
    handlerPtr->contextPtr = NULL;
    handlerPtr->monitorPtr = monitorPtr;
    LOCK
    handlerPtr->safeRef = le_ref_CreateRef(HandlerRefMap, handlerPtr);
    UNLOCK

    // Enable the monitoring of this event.
    EnableFdMonitoring(monitorPtr, eventType);

    return handlerPtr->safeRef;
}
//--------------------------------------------------------------------------------------------------
le_result_t mqtt_CreateSession
(
    const char* brokerURIPtr,           ///< [IN] The URI of the MQTT broker to connect to.  Should be in
                                        ///  the form protocol://host:port. eg. tcp://1.2.3.4:1883 or
                                        ///  ssl://example.com:8883
    const char* clientIdPtr,            ///< [IN] Any unique string.  If a client connects to an MQTT
                                        ///  broker using the same clientId as an existing session, then
                                        ///  the existing session will be terminated.
    mqtt_SessionRef_t* sessionRefPtr    ///< [OUT] The created session if the return result is LE_OK
)
{
    mqtt_Session* s = le_mem_ForceAlloc(MQTTSessionPoolRef);
    LE_ASSERT(s);
    memset(s, 0, sizeof(*s));
    const MQTTClient_connectOptions initConnOpts = MQTTClient_connectOptions_initializer;
    memcpy(&(s->connectOptions), &initConnOpts, sizeof(initConnOpts));

    const MQTTClient_SSLOptions initSslOpts = MQTTClient_SSLOptions_initializer;
    memcpy(&(s->sslOptions), &initSslOpts, sizeof(initSslOpts));
    s->sslOptions.trustStore = SslCaCertsPathPtr;

    const int createResult = MQTTClient_create(
            &(s->client),
            brokerURIPtr,
            clientIdPtr,
            MQTTCLIENT_PERSISTENCE_NONE,
            NULL);
    if (createResult != MQTTCLIENT_SUCCESS)
    {
        LE_ERROR("Couldn't create MQTT session.  Paho error code: %d", createResult);
        le_mem_Release(s);
        return LE_FAULT;
    }

    le_msg_SessionRef_t clientSession = mqtt_GetClientSessionRef();
    s->clientSession = clientSession;

    *sessionRefPtr = le_ref_CreateRef(SessionRefMap, s);

    LE_ASSERT(MQTTClient_setCallbacks(
            s->client,
            *sessionRefPtr,
            &ConnectionLostHandler,
            &MessageArrivedHandler,
            NULL) == MQTTCLIENT_SUCCESS);

    return LE_OK;
}
Exemple #11
0
//--------------------------------------------------------------------------------------------------
le_cfg_IteratorRef_t ni_CreateRef
(
    ni_IteratorRef_t iteratorRef  ///< The iterator to generate a reference for.
)
//--------------------------------------------------------------------------------------------------
{
    LE_ASSERT(iteratorRef != NULL);
    LE_ASSERT(iteratorRef->reference == NULL);

    iteratorRef->reference = le_ref_CreateRef(IteratorRefMap, iteratorRef);
    LE_DEBUG("Created a new reference <%p> for iterator <%p>.",
             iteratorRef->reference,
             iteratorRef);

    return iteratorRef->reference;
}
Exemple #12
0
//--------------------------------------------------------------------------------------------------
le_avdata_AssetInstanceRef_t le_avdata_Create
(
    const char* assetName
        ///< [IN]
)
{
    // Get the client's credentials.
    pid_t pid;
    uid_t uid;

    if (le_msg_GetClientUserCreds(le_avdata_GetClientSessionRef(), &uid, &pid) != LE_OK)
    {
        LE_KILL_CLIENT("Could not get credentials for the client.");
        return NULL;
    }


    // Look up the process's application name.
    char appName[LE_LIMIT_APP_NAME_LEN+1];

    le_result_t result = le_appInfo_GetName(pid, appName, sizeof(appName));
    LE_FATAL_IF(result == LE_OVERFLOW, "Buffer too small to contain the application name.");

    // TODO: Should this be LE_KILL_CLIENT instead?
    LE_FATAL_IF(result != LE_OK, "Could not get app name");


    // Create an instance of the asset
    assetData_InstanceDataRef_t instRef;
    int instanceId;

    LE_ASSERT( assetData_CreateInstanceByName(appName, assetName, -1, &instRef) == LE_OK );
    LE_ASSERT( instRef != NULL );
    LE_ASSERT( assetData_GetInstanceId(instRef, &instanceId) == LE_OK );
    LE_PRINT_VALUE("%i", instanceId);

    // Return a safe reference for the instance
    InstanceRefData_t* instRefDataPtr = le_mem_ForceAlloc(InstanceRefDataPoolRef);

    instRefDataPtr->clientSessionRef = le_avdata_GetClientSessionRef();
    instRefDataPtr->instRef = instRef;

    instRef = le_ref_CreateRef(InstanceRefMap, instRefDataPtr);

    return instRef;
}
Exemple #13
0
//--------------------------------------------------------------------------------------------------
le_pm_WakeupSourceRef_t le_pm_NewWakeupSource(uint32_t opts, const char *tag)
{
    WakeupSource_t *ws;
    Client_t *cl;
    char name[LEGATO_WS_NAME_LEN];

    if (!tag || *tag == '\0' || strlen(tag) > LE_PM_TAG_LEN) {
        LE_KILL_CLIENT("Error: Tag value is invalid or NULL.");
        return NULL;
    }

    // Find and validate client record
    cl = to_Client_t(le_hashmap_Get(PowerManager.clients,
                                    le_pm_GetClientSessionRef()));

    // Check if identical wakeup source already exists for this client
    sprintf(name, LEGATO_WS_NAME_FORMAT, tag, cl->pid);

    // Lookup wakeup source by name
    ws = (WakeupSource_t*)le_hashmap_Get(PowerManager.locks, name);
    if (ws) {
        LE_KILL_CLIENT("Error: Tag '%s' already exists.", tag);
        return NULL;
    }

    // Allocate and populate wakeup source record (exits on error)
    ws = (WakeupSource_t*)le_mem_ForceAlloc(PowerManager.lpool);
    ws->cookie = PM_WAKEUP_SOURCE_COOKIE;
    strcpy(ws->name, name);
    ws->taken = LE_OFF;
    ws->pid = cl->pid;
    ws->wsref = le_ref_CreateRef(PowerManager.refs, ws);

    // Store record in table of wakeup sources
    if (le_hashmap_Put(PowerManager.locks, ws->name, ws))
        LE_FATAL("Error adding wakeup source '%s'.", ws->name);

    LE_INFO("Created new wakeup source '%s' for pid %d.", ws->name, ws->pid);

    return (le_pm_WakeupSourceRef_t)ws->wsref;
}
Exemple #14
0
//--------------------------------------------------------------------------------------------------
static le_mcc_Call_t* CreateCallObject
(
    const char*                     destinationPtr,
    int16_t                         id,
    le_mcc_Event_t             event,
    le_mcc_TerminationReason_t termination,
    int32_t                         terminationCode
)
{
    le_mcc_Call_t* callPtr = NULL;

    // New call
    callPtr = (le_mcc_Call_t*)le_mem_ForceAlloc(MccCallPool);

    if (!callPtr)
    {
        LE_ERROR("callPtr null !!!!");
        return NULL;
    }

    le_utf8_Copy(callPtr->telNumber, destinationPtr, sizeof(callPtr->telNumber), NULL);
    callPtr->callId = id;
    callPtr->event = event;
    callPtr->termination = termination;
    callPtr->terminationCode = terminationCode;
    callPtr->clirStatus = PA_MCC_DEACTIVATE_CLIR;
    callPtr->inProgress = false;
    callPtr->refCount = 1;
    callPtr->sessionRefList=LE_DLS_LIST_INIT;

    // Create a Safe Reference for this Call object.
    callPtr->callRef = le_ref_CreateRef(MccCallRefMap, callPtr);

    // Update reference count
    UpdateReferenceCount(callPtr);

    return callPtr;
}
Exemple #15
0
//--------------------------------------------------------------------------------------------------
le_avdata_RequestSessionObjRef_t le_avdata_RequestSession
(
    void
)
{
    le_result_t result = LE_OK;

    // If this is a duplicate request send the existing reference.
    le_ref_IterRef_t iterRef = le_ref_GetIterator(AvSessionRequestRefMap);

    while (le_ref_NextNode(iterRef) == LE_OK)
    {
        if (le_ref_GetValue(iterRef) == le_avdata_GetClientSessionRef())
        {
            LE_DEBUG("Duplicate session request from client.");
            return (le_avdata_RequestSessionObjRef_t) le_ref_GetSafeRef(iterRef);
        }
    }

    le_timer_Stop(SessionReleaseTimerRef);

    // Ask the avc server to pass the request to control app or to initiate a session.
    result = avcServer_RequestSession();

    // If the fresh request fails, return NULL.
    if (result != LE_OK)
    {
        return NULL;
    }

    // Need to return a unique reference that will be used by release. Use the client session ref
    // as the data, since we need to delete the ref when the client closes.
    le_avdata_RequestSessionObjRef_t requestRef = le_ref_CreateRef(AvSessionRequestRefMap,
                                                                   le_avdata_GetClientSessionRef());

    return requestRef;
}
Exemple #16
0
//--------------------------------------------------------------------------------------------------
BugTestRef_t AddBugTest
(
    const char* newPathPtr,
        ///< [IN]

    BugTestFunc_t handlerPtr,
        ///< [IN]

    void* contextPtr
        ///< [IN]
)
{
    le_msg_MessageRef_t _msgRef;
    le_msg_MessageRef_t _responseMsgRef;
    _Message_t* _msgPtr;

    // Will not be used if no data is sent/received from server.
    __attribute__((unused)) uint8_t* _msgBufPtr;

    BugTestRef_t _result;

    // Range check values, if appropriate
    if ( strlen(newPathPtr) > 512 ) LE_FATAL("strlen(newPathPtr) > 512");


    // Create a new message object and get the message buffer
    _msgRef = le_msg_CreateMsg(GetCurrentSessionRef());
    _msgPtr = le_msg_GetPayloadPtr(_msgRef);
    _msgPtr->id = _MSGID_AddBugTest;
    _msgBufPtr = _msgPtr->buffer;

    // Pack the input parameters
    _msgBufPtr = PackString( _msgBufPtr, newPathPtr );
    // The input parameters are stored in the client data object, and it is
    // a pointer to this object that is passed down.
    // Create a new client data object and fill it in
    _ClientData_t* _clientDataPtr = le_mem_ForceAlloc(_ClientDataPool);
    _clientDataPtr->handlerPtr = (le_event_HandlerFunc_t)handlerPtr;
    _clientDataPtr->contextPtr = contextPtr;
    _clientDataPtr->callersThreadRef = le_thread_GetCurrent();
    contextPtr = _clientDataPtr;
    _msgBufPtr = PackData( _msgBufPtr, &contextPtr, sizeof(void*) );

    // Send a request to the server and get the response.
    LE_DEBUG("Sending message to server and waiting for response");
    _responseMsgRef = le_msg_RequestSyncResponse(_msgRef);
    // It is a serious error if we don't get a valid response from the server
    LE_FATAL_IF(_responseMsgRef == NULL, "Valid response was not received from server");

    // Process the result and/or output parameters, if there are any.
    _msgPtr = le_msg_GetPayloadPtr(_responseMsgRef);
    _msgBufPtr = _msgPtr->buffer;

    // Unpack the result first
    _msgBufPtr = UnpackData( _msgBufPtr, &_result, sizeof(_result) );
    // Put the handler reference result into the client data object, and
    // then return a safe reference to the client data object as the reference.
    _clientDataPtr->handlerRef = (le_event_HandlerRef_t)_result;
    _LOCK
    _result = le_ref_CreateRef(_HandlerRefMap, _clientDataPtr);
    _UNLOCK

    // Unpack any "out" parameters


    // Release the message object, now that all results/output has been copied.
    le_msg_ReleaseMsg(_responseMsgRef);

    return _result;
}
Exemple #17
0
//--------------------------------------------------------------------------------------------------
le_fdMonitor_Ref_t le_fdMonitor_Create
(
    const char*             name,       ///< [in] Name of the object (for diagnostics).
    int                     fd,         ///< [in] File descriptor to be monitored for events.
    le_fdMonitor_HandlerFunc_t handlerFunc, ///< [in] Handler function.
    short                   events      ///< [in] Initial set of events to be monitored.
)
//--------------------------------------------------------------------------------------------------
{
    // Get a pointer to the thread-specific event loop data record.
    event_PerThreadRec_t* perThreadRecPtr = thread_GetEventRecPtr();

    // Allocate the object.
    FdMonitor_t* fdMonitorPtr = le_mem_ForceAlloc(FdMonitorPool);

    // Initialize the object.
    fdMonitorPtr->link = LE_DLS_LINK_INIT;
    fdMonitorPtr->fd = fd;
    fdMonitorPtr->epollEvents = PollToEPoll(events) | EPOLLWAKEUP;  // Non-deferrable by default.
    fdMonitorPtr->isAlwaysReady = false;
    fdMonitorPtr->threadRecPtr = perThreadRecPtr;
    fdMonitorPtr->handlerFunc = handlerFunc;
    fdMonitorPtr->contextPtr = NULL;

    // Copy the name into it.
    if (le_utf8_Copy(fdMonitorPtr->name, name, sizeof(fdMonitorPtr->name), NULL) == LE_OVERFLOW)
    {
        LE_WARN("FD Monitor object name '%s' truncated to '%s'.", name, fdMonitorPtr->name);
    }

    LOCK

    // Create a safe reference for the object.
    fdMonitorPtr->safeRef = le_ref_CreateRef(FdMonitorRefMap, fdMonitorPtr);

    // Add it to the thread's FD Monitor list.
    le_dls_Queue(&perThreadRecPtr->fdMonitorList, &fdMonitorPtr->link);

    // Tell epoll(7) to start monitoring this fd.
    struct epoll_event ev;
    memset(&ev, 0, sizeof(ev));
    ev.events = fdMonitorPtr->epollEvents;
    ev.data.ptr = fdMonitorPtr->safeRef;
    if (epoll_ctl(perThreadRecPtr->epollFd, EPOLL_CTL_ADD, fd, &ev) == -1)
    {
        if (errno == EPERM)
        {
            LE_DEBUG("fd %d doesn't support epoll(), assuming always readable and writeable.", fd);
            fdMonitorPtr->isAlwaysReady = true;

            // If either EPOLLIN or EPOLLOUT are enabled, queue up the handler for this now.
            uint32_t epollEvents = fdMonitorPtr->epollEvents & (EPOLLIN | EPOLLOUT);
            if (epollEvents != 0)
            {
                fdMon_Report(fdMonitorPtr->safeRef, epollEvents);
            }
        }
        else
        {
            LE_FATAL("epoll_ctl(ADD) failed for fd %d. errno = %d (%m)", fd, errno);
        }
    }

    UNLOCK

    return fdMonitorPtr->safeRef;
}