static void ClientIndicationRecvHandler ( le_msg_MessageRef_t msgRef, void* contextPtr ) { // Get the message payload _Message_t* msgPtr = le_msg_GetPayloadPtr(msgRef); uint8_t* _msgBufPtr = msgPtr->buffer; // Have to partially unpack the received message in order to know which thread // the queued function should actually go to. void* clientContextPtr; _msgBufPtr = UnpackData( _msgBufPtr, &clientContextPtr, sizeof(void*) ); // Pull out the callers thread _ClientData_t* clientDataPtr = clientContextPtr; le_thread_Ref_t callersThreadRef = clientDataPtr->callersThreadRef; // Trigger the appropriate event switch (msgPtr->id) { case _MSGID_AddTestA : le_event_QueueFunctionToThread(callersThreadRef, _Handle_AddTestA, msgRef, NULL); break; case _MSGID_AddBugTest : le_event_QueueFunctionToThread(callersThreadRef, _Handle_AddBugTest, msgRef, NULL); break; default: LE_ERROR("Unknowm msg id = %i for client thread = %p", msgPtr->id, callersThreadRef); } }
//-------------------------------------------------------------------------------------------------- void Testle_ecall_RemoveHandlers ( void ) { int i; // Remove handlers: add le_ecall_RemoveStateChangeHandler to the eventLoop of tasks for (i=0; i<NB_CLIENT; i++) { le_event_QueueFunctionToThread(AppCtx[i].appThreadRef, RemoveHandler, &AppCtx[i], NULL); } // Wait for the tasks SynchTest(); // Provoke event which should call the handlers pa_ecallSimu_ReportEcallState(LE_ECALL_STATE_STARTED); // Wait for the semaphore timeout to check that handlers are not called LE_ASSERT( le_sem_WaitWithTimeOut(ThreadSemaphore, TimeToWait) == LE_TIMEOUT ); }
//-------------------------------------------------------------------------------------------------- void TestSim_RemoveHandlers ( void ) { int i; // Remove handlers: add le_sim_RemoveNewStateHandler and le_sim_RemoveSimToolkitEventHandler // to the eventLoop of tasks for (i=0; i<NB_CLIENT; i++) { le_event_QueueFunctionToThread( AppCtx[i].appThreadRef, RemoveHandler, &AppCtx[i], NULL ); } // Wait for the tasks SynchTest(); // Provoke events which called the handlers (sim state event, and stk event) // Go into ABSENT state CurrentSimState = LE_SIM_ABSENT; pa_simSimu_ReportSimState(CurrentSimState); // Invoke Stk event, and check that no handler is called pa_simSimu_ReportStkEvent(StkEvent); // Wait for the semaphore timeout to check that handlers are not called LE_ASSERT( le_sem_WaitWithTimeOut(ThreadSemaphore, TimeToWait) == LE_TIMEOUT ); }
//-------------------------------------------------------------------------------------------------- static void Testle_Temp_RemoveHandlers ( void ) { int i; // Remove handlers: add le_temp_RemoveThresholdEventHandler to the eventLoop of tasks for (i=0; i<NB_CLIENT; i++) { le_event_QueueFunctionToThread( AppCtx[i].appThreadRef, RemoveHandler, &AppCtx[i], NULL ); } // Wait for the tasks SynchTest(); // trigger an event report ExpectedStatus = 0; pa_tempSimu_TriggerEventReport(ExpectedStatus); // Wait for the semaphore timeout to check that handlers are not called LE_ASSERT( le_sem_WaitWithTimeOut(ThreadSemaphore, TimeToWait) == LE_TIMEOUT ); }
//-------------------------------------------------------------------------------------------------- static void TestMdc_Handler ( void ) { le_result_t res; /* Create the thread to subcribe and call the handlers */ ThreadSemaphore = le_sem_Create("HandlerSem",0); le_thread_Ref_t thread = le_thread_Create("Threadhandler", ThreadTestHandler, NULL); le_thread_Start(thread); int i; le_clk_Time_t timeToWait; timeToWait.sec = 0; timeToWait.usec = 1000000; /* Wait the thread to be ready */ le_sem_Wait(ThreadSemaphore); for (i = 0; i < NB_PROFILE; i++) { /* Start a session for the current profile: the handler should be called */ res = le_mdc_StartSession(ProfileRef[i]); LE_ASSERT(res == LE_OK); /* Wait for the call of the handler (error if timeout) */ LE_ASSERT(le_sem_WaitWithTimeOut(ThreadSemaphore, timeToWait) == LE_OK); /* Check the the handler parameters */ LE_ASSERT(ProfileRefReceivedByHandler == ProfileRef[i]); LE_ASSERT(ConnectionStateReceivedByHandler == true); ConnectionStateReceivedByHandler = false; } for (i = 0; i < NB_PROFILE; i++) { /* Stop a session for the current profile: the handler should be called */ res = le_mdc_StopSession(ProfileRef[i]); LE_ASSERT(res == LE_OK); /* Wait for the call of the handler (error if timeout) */ LE_ASSERT(le_sem_WaitWithTimeOut(ThreadSemaphore, timeToWait) == LE_OK); /* Check the the handler parameters */ LE_ASSERT(ProfileRefReceivedByHandler == ProfileRef[i]); LE_ASSERT(ConnectionStateReceivedByHandler == false); ConnectionStateReceivedByHandler = true; } /* Remove the handler of the profile 1: ther handler can be removed only by the thread which * subscribed to the handler, so put the RemoveHandler() function in queue of this thread */ le_event_QueueFunctionToThread( thread, RemoveHandler, SessionStateHandler[1], NULL); le_sem_Wait(ThreadSemaphore); /* Start a session for the current profile: no handler should be called */ res = le_mdc_StartSession(ProfileRef[1]); /* No semaphore post is waiting, we are expecting a timeout */ LE_ASSERT(le_sem_WaitWithTimeOut(ThreadSemaphore, timeToWait) == LE_TIMEOUT); res = le_mdc_StopSession(ProfileRef[1]); /* No semaphore post is waiting, we are expecting a timeout */ LE_ASSERT(le_sem_WaitWithTimeOut(ThreadSemaphore, timeToWait) == LE_TIMEOUT); }
// wait for all threads to finish creating their mutexes, then ask them to do something. void queueFuncToAllThreads ( le_event_DeferredFunc_t func ) { long cnt = 0; while (cnt < ThreadNum) { le_event_QueueFunctionToThread(ThreadRefArray[cnt], func, NULL, NULL); cnt++; } }
//-------------------------------------------------------------------------------------------------- void TestSim_Stk ( void ) { // Stk handler semaphore StkHandlerSem = (le_sem_Ref_t) le_sem_Create("StkHandlerSem",1); // each thread subscribes to state handler using le_sim_AddSimToolkitEventHandler // This API has to be called by threads int i=0; for (; i<NB_CLIENT; i++) { le_event_QueueFunctionToThread( AppCtx[i].appThreadRef, AddStkHandler, &AppCtx[i], NULL ); } // Wait for the tasks SynchTest(); StkEvent = LE_SIM_REFRESH; // Invoke Stk event pa_simSimu_ReportStkEvent(StkEvent); // Wait for the call of the handlers SynchTest(); // Check the result for (i=0; i<NB_CLIENT; i++) { LE_ASSERT(AppCtx[i].stkEvent == StkEvent); AppCtx[i].stkEvent = 0; } // Test le_sim_AcceptSimToolkitCommand and le_sim_RejectSimToolkitCommand pa_simSimu_SetExpectedStkConfirmationCommand(true); LE_ASSERT( le_sim_AcceptSimToolkitCommand(CurrentSimId) == LE_OK ); pa_simSimu_SetExpectedStkConfirmationCommand(false); LE_ASSERT( le_sim_RejectSimToolkitCommand(CurrentSimId) == LE_OK ); // Check that all handlers have been called as expected LE_ASSERT( le_sem_GetValue(ThreadSemaphore) == 0 ); }
//-------------------------------------------------------------------------------------------------- void TestSim_LocalSwap ( void ) { int i; int doItAgain = 2; while (doItAgain) { doItAgain--; // The thread is calling le_sim_LocalSwapToCommercialSubscription and // le_sim_LocalSwapToEmergencyCallSubscription (that's why we do this operation twice) le_event_QueueFunctionToThread( AppCtx[0].appThreadRef, LocalSwap, &AppCtx[0], NULL ); // Wait a while for le_sim treatment sleep(1); // There's a semaphore in the le_sim to wait for the refresh => report refresh event StkEvent = LE_SIM_REFRESH; // Invoke Stk event pa_simSimu_ReportStkEvent(StkEvent); // Wait for the call of the handlers SynchTest(); // Check the result for (i=0; i<NB_CLIENT; i++) { LE_ASSERT(AppCtx[i].stkEvent == StkEvent); AppCtx[i].stkEvent = 0; } // Check that all handlers have been called as expected LE_ASSERT( le_sem_GetValue(ThreadSemaphore) == 0 ); } }
//-------------------------------------------------------------------------------------------------- __attribute__((unused)) static void SendMsgToClient ( le_msg_MessageRef_t msgRef ///< [in] Reference to the message. ) { /* * If called from a thread other than the server thread, queue the message onto the server * thread. This is necessary to allow async response/handler functions to be called from any * thread, whereas messages to the client can only be sent from the server thread. */ if ( le_thread_GetCurrent() != _ServerThreadRef ) { le_event_QueueFunctionToThread(_ServerThreadRef, SendMsgToClientQueued, msgRef, NULL); } else { le_msg_Send(msgRef); } }
//-------------------------------------------------------------------------------------------------- le_result_t Testle_atServer_Bridge ( int socketFd, int epollFd, SharedData_t* sharedDataPtr ) { LE_INFO("======== Test AT server bridge API ========"); le_result_t ret; le_atServer_BridgeRef_t bridgeRef = NULL; BridgeSemaphore = le_sem_Create("BridgeSem", 0); le_event_QueueFunctionToThread( sharedDataPtr->atServerThread, StartBridge, (void*) &bridgeRef, (void*) sharedDataPtr->devRef); le_sem_Wait(BridgeSemaphore); ret = SendCommandsAndTest(socketFd, epollFd, AtPlusCpinRead, "\r\n+CPIN: READY\r\n" "\r\nOK\r\n"); if (ret != LE_OK) { return ret; } ret = SendCommandsAndTest(socketFd, epollFd, AtPlusCgdcontPara, "\r\nOK\r\n"); if (ret != LE_OK) { return ret; } ret = SendCommandsAndTest(socketFd, epollFd, AtPlusBad, "\r\nERROR\r\n"); if (ret != LE_OK) { return ret; } ret = SendCommandsAndTest(socketFd, epollFd, AtPlusUnknown, "\r\nERROR\r\n"); if (ret != LE_OK) { return ret; } ret = SendCommandsAndTest(socketFd, epollFd, ConcatCpinReadCgdcontRead, "\r\n+CPIN: READY\r\n" "\r\n+CGDCONT: 1,\"IP\",\"orange\"\r\n" "+CGDCONT: 2,\"IP\",\"bouygues\"\r\n" "+CGDCONT: 3,\"IP\",\"sfr\"\r\n" "\r\nOK\r\n"); if (ret != LE_OK) { return ret; } ret = SendCommandsAndTest(socketFd, epollFd, ConcatQ1CpinReadAbcdReadCgdcontTest, "\r\nQ1\r\n" "\r\n+CPIN: READY\r\n" "\r\n+ABCD TYPE: READ\r\n" "\r\n+CGDCONT: (1-16),\"IP\",,,(0-2),(0-4)\r\n" "+CGDCONT: (1-16),\"PPP\",,,(0-2),(0-4)\r\n" "+CGDCONT: (1-16),\"IPV6\",,,(0-2),(0-4)\r\n" "+CGDCONT: (1-16),\"IPV4V6\",,,(0-2),(0-4)\r\n" "\r\nOK\r\n"); if (ret != LE_OK) { return ret; } // Test unsolicited handler LE_ASSERT(UnsolHandler != NULL); UnsolHandler( "+CREG: 1", UnsolHandlerContextPtr); ret = TestResponses(socketFd, epollFd, "\r\n+CREG: 1\r\n"); if (ret != LE_OK) { return ret; } LE_ASSERT_OK(le_atServer_RemoveDeviceFromBridge(sharedDataPtr->devRef, bridgeRef)); LE_ASSERT_OK(le_atServer_CloseBridge(bridgeRef)); LE_INFO("======== AT server bridge API test success ========"); return ret; }