//-------------------------------------------------------------------------------------------------- static void MsgRecvHandler ( le_msg_MessageRef_t msgRef, ///< Reference to the received message. void* opaqueContextPtr ///< contextPtr passed to le_msg_SetServiceRecvHandler() ) //-------------------------------------------------------------------------------------------------- { Context_t* contextPtr = opaqueContextPtr; LE_ASSERT(contextPtr != NULL); LE_TEST(contextPtr->strPtr == ContextStr); LE_TEST(strcmp(contextPtr->strPtr, ContextStr) == 0); le_msg_SessionRef_t sessionRef = le_msg_GetSession(msgRef); LE_ASSERT(sessionRef != NULL); burger_Message_t* msgPtr = le_msg_GetPayloadPtr(msgRef); LE_ASSERT(msgPtr != NULL); LE_INFO("Received '%x'", msgPtr->payload); switch (msgPtr->payload) { case 0xBEEFBEEF: LE_TEST(le_msg_NeedsResponse(msgRef) == false); le_msg_ReleaseMsg(msgRef); break; case 0xDEADBEEF: LE_TEST(le_msg_NeedsResponse(msgRef) == true); contextPtr->requestCount++; LE_INFO("Received transaction request (%d/%d).", contextPtr->requestCount, contextPtr->maxRequestCount); // Construct and send response. msgPtr->payload = 0xBEEFDEAD; le_msg_Respond(msgRef); // If we have received the magic number of requests, tell the client to // terminate the test by sending 0xDEADDEAD to the client. if (contextPtr->requestCount >= contextPtr->maxRequestCount) { LE_INFO("Maximum number of request-response transactions reached."); msgRef = le_msg_CreateMsg(sessionRef); msgPtr = le_msg_GetPayloadPtr(msgRef); msgPtr->payload = 0xDEADDEAD; le_msg_Send(msgRef); } break; default: LE_FATAL("Unexpected message payload (%x)", msgPtr->payload); } }
//-------------------------------------------------------------------------------------------------- void RemoveBugTest ( BugTestRef_t addHandlerRef ///< [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; // Range check values, if appropriate // Create a new message object and get the message buffer _msgRef = le_msg_CreateMsg(GetCurrentSessionRef()); _msgPtr = le_msg_GetPayloadPtr(_msgRef); _msgPtr->id = _MSGID_RemoveBugTest; _msgBufPtr = _msgPtr->buffer; // Pack the input parameters // The passed in handlerRef is a safe reference for the client data object. Need to get the // real handlerRef from the client data object and then delete both the safe reference and // the object since they are no longer needed. _LOCK _ClientData_t* clientDataPtr = le_ref_Lookup(_HandlerRefMap, addHandlerRef); le_ref_DeleteRef(_HandlerRefMap, addHandlerRef); _UNLOCK addHandlerRef = (BugTestRef_t)clientDataPtr->handlerRef; le_mem_Release(clientDataPtr); _msgBufPtr = PackData( _msgBufPtr, &addHandlerRef, sizeof(BugTestRef_t) ); // 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 any "out" parameters // Release the message object, now that all results/output has been copied. le_msg_ReleaseMsg(_responseMsgRef); }
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); }
//-------------------------------------------------------------------------------------------------- void TriggerCallbackTestRespond ( ServerCmdRef_t _cmdRef ) { LE_ASSERT(_cmdRef != NULL); // Get the message related data le_msg_MessageRef_t _msgRef = (le_msg_MessageRef_t)_cmdRef; _Message_t* _msgPtr = le_msg_GetPayloadPtr(_msgRef); __attribute__((unused)) uint8_t* _msgBufPtr = _msgPtr->buffer; // Ensure the passed in msgRef is for the correct message LE_ASSERT(_msgPtr->id == _MSGID_TriggerCallbackTest); // Ensure that this Respond function has not already been called LE_FATAL_IF( !le_msg_NeedsResponse(_msgRef), "Response has already been sent"); // Pack any "out" parameters // Return the response LE_DEBUG("Sending response to client session %p", le_msg_GetSession(_msgRef)); le_msg_Respond(_msgRef); }
static void ServerMsgRecvHandler ( le_msg_MessageRef_t msgRef, void* contextPtr ) { // Get the message payload so that we can get the message "id" _Message_t* msgPtr = le_msg_GetPayloadPtr(msgRef); // Get the client session ref for the current message. This ref is used by the server to // get info about the client process, such as user id. If there are multiple clients, then // the session ref may be different for each message, hence it has to be queried each time. _ClientSessionRef = le_msg_GetSession(msgRef); // Dispatch to appropriate message handler and get response switch (msgPtr->id) { case _MSGID_AddTestAHandler : Handle_AddTestAHandler(msgRef); break; case _MSGID_RemoveTestAHandler : Handle_RemoveTestAHandler(msgRef); break; case _MSGID_allParameters : Handle_allParameters(msgRef); break; case _MSGID_FileTest : Handle_FileTest(msgRef); break; case _MSGID_TriggerTestA : Handle_TriggerTestA(msgRef); break; case _MSGID_AddBugTestHandler : Handle_AddBugTestHandler(msgRef); break; case _MSGID_RemoveBugTestHandler : Handle_RemoveBugTestHandler(msgRef); break; case _MSGID_TestCallback : Handle_TestCallback(msgRef); break; case _MSGID_TriggerCallbackTest : Handle_TriggerCallbackTest(msgRef); break; default: LE_ERROR("Unknowm msg id = %i", msgPtr->id); } // Clear the client session ref associated with the current message, since the message // has now been processed. _ClientSessionRef = 0; }
static void Handle_allParameters ( le_msg_MessageRef_t _msgRef ) { // Get the message buffer pointer __attribute__((unused)) uint8_t* _msgBufPtr = ((_Message_t*)le_msg_GetPayloadPtr(_msgRef))->buffer; // Unpack the input parameters from the message common_EnumExample_t a; _msgBufPtr = UnpackData( _msgBufPtr, &a, sizeof(common_EnumExample_t) ); size_t dataNumElements; _msgBufPtr = UnpackData( _msgBufPtr, &dataNumElements, sizeof(size_t) ); uint32_t data[dataNumElements]; _msgBufPtr = UnpackData( _msgBufPtr, data, dataNumElements*sizeof(uint32_t) ); size_t outputNumElements; _msgBufPtr = UnpackData( _msgBufPtr, &outputNumElements, sizeof(size_t) ); const char* label; _msgBufPtr = UnpackString( _msgBufPtr, &label ); size_t responseNumElements; _msgBufPtr = UnpackData( _msgBufPtr, &responseNumElements, sizeof(size_t) ); size_t moreNumElements; _msgBufPtr = UnpackData( _msgBufPtr, &moreNumElements, sizeof(size_t) ); // Call the function allParameters ( (ServerCmdRef_t)_msgRef, a, data, dataNumElements, outputNumElements, label, responseNumElements, moreNumElements ); }
//-------------------------------------------------------------------------------------------------- void allParametersRespond ( ServerCmdRef_t _cmdRef, uint32_t b, size_t outputNumElements, uint32_t* outputPtr, char* response, char* more ) { LE_ASSERT(_cmdRef != NULL); // Get the message related data le_msg_MessageRef_t _msgRef = (le_msg_MessageRef_t)_cmdRef; _Message_t* _msgPtr = le_msg_GetPayloadPtr(_msgRef); __attribute__((unused)) uint8_t* _msgBufPtr = _msgPtr->buffer; // Ensure the passed in msgRef is for the correct message LE_ASSERT(_msgPtr->id == _MSGID_allParameters); // Ensure that this Respond function has not already been called LE_FATAL_IF( !le_msg_NeedsResponse(_msgRef), "Response has already been sent"); // Pack any "out" parameters _msgBufPtr = PackData( _msgBufPtr, &b, sizeof(uint32_t) ); _msgBufPtr = PackData( _msgBufPtr, &outputNumElements, sizeof(size_t) ); _msgBufPtr = PackData( _msgBufPtr, outputPtr, outputNumElements*sizeof(uint32_t) ); _msgBufPtr = PackString( _msgBufPtr, response ); _msgBufPtr = PackString( _msgBufPtr, more ); // Return the response LE_DEBUG("Sending response to client session %p", le_msg_GetSession(_msgRef)); le_msg_Respond(_msgRef); }
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); } }
// This function parses the message buffer received from the server, and then calls the user // registered handler, which is stored in a client data object. static void _Handle_AddBugTest ( void* _reportPtr, void* _notUsed ) { le_msg_MessageRef_t _msgRef = _reportPtr; _Message_t* _msgPtr = le_msg_GetPayloadPtr(_msgRef); uint8_t* _msgBufPtr = _msgPtr->buffer; // The clientContextPtr always exists and is always first. void* _clientContextPtr; _msgBufPtr = UnpackData( _msgBufPtr, &_clientContextPtr, sizeof(void*) ); // Pull out additional data from the context pointer _ClientData_t* _clientDataPtr = _clientContextPtr; BugTestFunc_t _handlerRef_AddBugTest = (BugTestFunc_t)_clientDataPtr->handlerPtr; void* contextPtr = _clientDataPtr->contextPtr; // Unpack the remaining parameters // Call the registered handler if ( _handlerRef_AddBugTest != NULL ) { _handlerRef_AddBugTest( contextPtr ); } else { LE_ERROR("ERROR in client _Handle_AddBugTest: no registered handler"); } // Release the message, now that we are finished with it. le_msg_ReleaseMsg(_msgRef); }
static void AsyncResponse_AddBugTestHandler ( void* contextPtr ) { le_msg_MessageRef_t _msgRef; _Message_t* _msgPtr; _ServerData_t* serverDataPtr = (_ServerData_t*)contextPtr; // Will not be used if no data is sent back to client __attribute__((unused)) uint8_t* _msgBufPtr; // Create a new message object and get the message buffer _msgRef = le_msg_CreateMsg(serverDataPtr->clientSessionRef); _msgPtr = le_msg_GetPayloadPtr(_msgRef); _msgPtr->id = _MSGID_AddBugTestHandler; _msgBufPtr = _msgPtr->buffer; // Always pack the client context pointer first _msgBufPtr = PackData( _msgBufPtr, &(serverDataPtr->contextPtr), sizeof(void*) ); // Pack the input parameters // Send the async response to the client LE_DEBUG("Sending message to client session %p : %ti bytes sent", serverDataPtr->clientSessionRef, _msgBufPtr-_msgPtr->buffer); SendMsgToClient(_msgRef); }
//-------------------------------------------------------------------------------------------------- static void List ( void ) //-------------------------------------------------------------------------------------------------- { le_msg_MessageRef_t msgRef = le_msg_CreateMsg(SessionRef); le_msg_SetFd(msgRef, 1); le_sdtp_Msg_t* msgPtr = le_msg_GetPayloadPtr(msgRef); msgPtr->msgType = LE_SDTP_MSGID_LIST; msgRef = le_msg_RequestSyncResponse(msgRef); if (msgRef == NULL) { ExitWithErrorMsg("Communication with Service Directory failed."); } le_msg_ReleaseMsg(msgRef); exit(EXIT_SUCCESS); }
static void Handle_TestCallback ( 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 uint32_t someParm; _msgBufPtr = UnpackData( _msgBufPtr, &someParm, sizeof(uint32_t) ); size_t dataArrayNumElements; _msgBufPtr = UnpackData( _msgBufPtr, &dataArrayNumElements, sizeof(size_t) ); uint8_t dataArray[dataArrayNumElements]; _msgBufPtr = UnpackData( _msgBufPtr, dataArray, dataArrayNumElements*sizeof(uint8_t) ); 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 int32_t _result; _result = TestCallback ( someParm, dataArray, dataArrayNumElements, AsyncResponse_TestCallback, contextPtr ); // 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); }
//-------------------------------------------------------------------------------------------------- void TriggerTestA ( void ) { 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; // Range check values, if appropriate // Create a new message object and get the message buffer _msgRef = le_msg_CreateMsg(GetCurrentSessionRef()); _msgPtr = le_msg_GetPayloadPtr(_msgRef); _msgPtr->id = _MSGID_TriggerTestA; _msgBufPtr = _msgPtr->buffer; // Pack the input parameters // 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 any "out" parameters // Release the message object, now that all results/output has been copied. le_msg_ReleaseMsg(_responseMsgRef); }
static void Handle_RemoveBugTestHandler ( 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 BugTestHandlerRef_t addHandlerRef; _msgBufPtr = UnpackData( _msgBufPtr, &addHandlerRef, sizeof(BugTestHandlerRef_t) ); // The passed in handlerRef is a safe reference for the server data object. Need to get the // real handlerRef from the server data object and then delete both the safe reference and // the object since they are no longer needed. _LOCK _ServerData_t* serverDataPtr = le_ref_Lookup(_HandlerRefMap, addHandlerRef); if ( serverDataPtr == NULL ) { _UNLOCK LE_KILL_CLIENT("Invalid reference"); return; } le_ref_DeleteRef(_HandlerRefMap, addHandlerRef); _UNLOCK addHandlerRef = (BugTestHandlerRef_t)serverDataPtr->handlerRef; le_mem_Release(serverDataPtr); // Define storage for output parameters // Call the function RemoveBugTestHandler ( addHandlerRef ); // Re-use the message buffer for the response _msgBufPtr = _msgBufStartPtr; // 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); }
static void Handle_TriggerTestA ( le_msg_MessageRef_t _msgRef ) { // Get the message buffer pointer __attribute__((unused)) uint8_t* _msgBufPtr = ((_Message_t*)le_msg_GetPayloadPtr(_msgRef))->buffer; // Unpack the input parameters from the message // Call the function TriggerTestA ( (ServerCmdRef_t)_msgRef ); }
//-------------------------------------------------------------------------------------------------- static void AppendToCommand ( le_msg_MessageRef_t msgRef, ///< Command message to which the text should be appended. const char* textPtr ///< Text to append to the message. ) { if (LE_OVERFLOW == le_utf8_Append(le_msg_GetPayloadPtr(msgRef), textPtr, le_msg_GetMaxPayloadSize(msgRef), NULL) ) { ExitWithErrorMsg("Command string is too long."); } }
static void Handle_TriggerCallbackTest ( le_msg_MessageRef_t _msgRef ) { // Get the message buffer pointer __attribute__((unused)) uint8_t* _msgBufPtr = ((_Message_t*)le_msg_GetPayloadPtr(_msgRef))->buffer; // Unpack the input parameters from the message uint32_t data; _msgBufPtr = UnpackData( _msgBufPtr, &data, sizeof(uint32_t) ); // Call the function TriggerCallbackTest ( (ServerCmdRef_t)_msgRef, data ); }
static void Handle_FileTest ( le_msg_MessageRef_t _msgRef ) { // Get the message buffer pointer __attribute__((unused)) uint8_t* _msgBufPtr = ((_Message_t*)le_msg_GetPayloadPtr(_msgRef))->buffer; // Unpack the input parameters from the message int dataFile; dataFile = le_msg_GetFd(_msgRef); // Call the function FileTest ( (ServerCmdRef_t)_msgRef, dataFile ); }
static void AsyncResponse_TestCallback ( uint32_t data, const char* name, int dataFile, void* contextPtr ) { le_msg_MessageRef_t _msgRef; _Message_t* _msgPtr; _ServerData_t* serverDataPtr = (_ServerData_t*)contextPtr; // This is a one-time handler; if the server accidently calls it a second time, then // the client sesssion ref would be NULL. if ( serverDataPtr->clientSessionRef == NULL ) { LE_FATAL("Handler passed to TestCallback() can't be called more than once"); } // Will not be used if no data is sent back to client __attribute__((unused)) uint8_t* _msgBufPtr; // Create a new message object and get the message buffer _msgRef = le_msg_CreateMsg(serverDataPtr->clientSessionRef); _msgPtr = le_msg_GetPayloadPtr(_msgRef); _msgPtr->id = _MSGID_TestCallback; _msgBufPtr = _msgPtr->buffer; // Always pack the client context pointer first _msgBufPtr = PackData( _msgBufPtr, &(serverDataPtr->contextPtr), sizeof(void*) ); // Pack the input parameters _msgBufPtr = PackData( _msgBufPtr, &data, sizeof(uint32_t) ); _msgBufPtr = PackString( _msgBufPtr, name ); le_msg_SetFd(_msgRef, dataFile); // Send the async response to the client LE_DEBUG("Sending message to client session %p : %ti bytes sent", serverDataPtr->clientSessionRef, _msgBufPtr-_msgPtr->buffer); SendMsgToClient(_msgRef); // The registered handler has been called, so no longer need the server data. // Explicitly set clientSessionRef to NULL, so that we can catch if this function gets // accidently called again. serverDataPtr->clientSessionRef = NULL; le_mem_Release(serverDataPtr); }
//-------------------------------------------------------------------------------------------------- static void MsgReceiveHandler ( le_msg_MessageRef_t msgRef, void* contextPtr // not used. ) { const char* responseStr = le_msg_GetPayloadPtr(msgRef); // Print out whatever the Log Control Daemon sent us. printf("%s\n", responseStr); // If the first character of the response is a '*', then there has been an error. if (responseStr[0] == '*') { ErrorOccurred = true; } }
//-------------------------------------------------------------------------------------------------- static void SendUnbindAllRequest ( void ) //-------------------------------------------------------------------------------------------------- { le_msg_MessageRef_t msgRef = le_msg_CreateMsg(SessionRef); le_sdtp_Msg_t* msgPtr = le_msg_GetPayloadPtr(msgRef); msgPtr->msgType = LE_SDTP_MSGID_UNBIND_ALL; msgRef = le_msg_RequestSyncResponse(msgRef); if (msgRef == NULL) { ExitWithErrorMsg("Communication with Service Directory failed."); } le_msg_ReleaseMsg(msgRef); }
static void Handle_TriggerCallbackTest ( 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 uint32_t data; _msgBufPtr = UnpackData( _msgBufPtr, &data, sizeof(uint32_t) ); // Define storage for output parameters // Call the function TriggerCallbackTest ( data ); // Re-use the message buffer for the response _msgBufPtr = _msgBufStartPtr; // 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); }
static void Handle_FileTest ( 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 int dataFile; dataFile = le_msg_GetFd(_msgRef); // Define storage for output parameters int dataOut; // Call the function FileTest ( dataFile, &dataOut ); // Re-use the message buffer for the response _msgBufPtr = _msgBufStartPtr; // Pack any "out" parameters le_msg_SetFd(_msgRef, dataOut); // Return the response LE_DEBUG("Sending response to client session %p : %ti bytes sent", le_msg_GetSession(_msgRef), _msgBufPtr-_msgBufStartPtr); le_msg_Respond(_msgRef); }
//-------------------------------------------------------------------------------------------------- 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; }
static void Handle_allParameters ( 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 common_EnumExample_t a; _msgBufPtr = UnpackData( _msgBufPtr, &a, sizeof(common_EnumExample_t) ); size_t dataNumElements; _msgBufPtr = UnpackData( _msgBufPtr, &dataNumElements, sizeof(size_t) ); uint32_t data[dataNumElements]; _msgBufPtr = UnpackData( _msgBufPtr, data, dataNumElements*sizeof(uint32_t) ); size_t outputNumElements; _msgBufPtr = UnpackData( _msgBufPtr, &outputNumElements, sizeof(size_t) ); if ( outputNumElements > 10 ) { LE_DEBUG("Adjusting outputNumElements from %zd to 10", outputNumElements); outputNumElements = 10; } char label[21]; _msgBufPtr = UnpackString( _msgBufPtr, label, 21 ); size_t responseNumElements; _msgBufPtr = UnpackData( _msgBufPtr, &responseNumElements, sizeof(size_t) ); size_t moreNumElements; _msgBufPtr = UnpackData( _msgBufPtr, &moreNumElements, sizeof(size_t) ); // Define storage for output parameters uint32_t b; uint32_t output[outputNumElements]; char response[responseNumElements]; response[0]=0; char more[moreNumElements]; more[0]=0; // Call the function allParameters ( a, &b, data, dataNumElements, output, &outputNumElements, label, response, responseNumElements, more, moreNumElements ); // Re-use the message buffer for the response _msgBufPtr = _msgBufStartPtr; // Pack any "out" parameters _msgBufPtr = PackData( _msgBufPtr, &b, sizeof(uint32_t) ); _msgBufPtr = PackData( _msgBufPtr, &outputNumElements, sizeof(size_t) ); _msgBufPtr = PackData( _msgBufPtr, output, outputNumElements*sizeof(uint32_t) ); _msgBufPtr = PackString( _msgBufPtr, response ); _msgBufPtr = PackString( _msgBufPtr, more ); // Return the response LE_DEBUG("Sending response to client session %p : %ti bytes sent", le_msg_GetSession(_msgRef), _msgBufPtr-_msgBufStartPtr); le_msg_Respond(_msgRef); }
//-------------------------------------------------------------------------------------------------- static void SendBindRequest ( uid_t uid, ///< [in] Unix user ID of the client whose binding is being created. le_cfg_IteratorRef_t i ///< [in] Configuration read iterator. ) //-------------------------------------------------------------------------------------------------- { le_result_t result; le_msg_MessageRef_t msgRef = le_msg_CreateMsg(SessionRef); le_sdtp_Msg_t* msgPtr = le_msg_GetPayloadPtr(msgRef); msgPtr->msgType = LE_SDTP_MSGID_BIND; msgPtr->client = uid; // Fetch the client's service name. result = le_cfg_GetNodeName(i, "", msgPtr->clientServiceName, sizeof(msgPtr->clientServiceName)); if (result != LE_OK) { char path[LIMIT_MAX_PATH_BYTES]; le_cfg_GetPath(i, "", path, sizeof(path)); LE_CRIT("Configured client service name too long (@ %s)", path); return; } // Fetch the server's user ID. result = GetServerUid(i, &msgPtr->server); if (result != LE_OK) { return; } // Fetch the server's service name. result = le_cfg_GetString(i, "interface", msgPtr->serverServiceName, sizeof(msgPtr->serverServiceName), ""); if (result != LE_OK) { char path[LIMIT_MAX_PATH_BYTES]; le_cfg_GetPath(i, "interface", path, sizeof(path)); LE_CRIT("Server interface name too big (@ %s)", path); return; } if (msgPtr->serverServiceName[0] == '\0') { char path[LIMIT_MAX_PATH_BYTES]; le_cfg_GetPath(i, "interface", path, sizeof(path)); LE_CRIT("Server interface name missing (@ %s)", path); return; } msgRef = le_msg_RequestSyncResponse(msgRef); if (msgRef == NULL) { ExitWithErrorMsg("Communication with Service Directory failed."); } le_msg_ReleaseMsg(msgRef); }
//-------------------------------------------------------------------------------------------------- void allParameters ( common_EnumExample_t a, ///< [IN] ///< first one-line comment ///< second one-line comment uint32_t* bPtr, ///< [OUT] const uint32_t* dataPtr, ///< [IN] size_t dataNumElements, ///< [IN] uint32_t* outputPtr, ///< [OUT] ///< some more comments here ///< and some comments here as well size_t* outputNumElementsPtr, ///< [INOUT] const char* label, ///< [IN] char* response, ///< [OUT] ///< comments on final parameter, first line ///< and more comments size_t responseNumElements, ///< [IN] char* more, ///< [OUT] ///< This parameter tests a bug fix size_t moreNumElements ///< [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; // Range check values, if appropriate if ( dataNumElements > 10 ) LE_FATAL("dataNumElements > 10"); if ( strlen(label) > 20 ) LE_FATAL("strlen(label) > 20"); // Create a new message object and get the message buffer _msgRef = le_msg_CreateMsg(GetCurrentSessionRef()); _msgPtr = le_msg_GetPayloadPtr(_msgRef); _msgPtr->id = _MSGID_allParameters; _msgBufPtr = _msgPtr->buffer; // Pack the input parameters _msgBufPtr = PackData( _msgBufPtr, &a, sizeof(common_EnumExample_t) ); _msgBufPtr = PackData( _msgBufPtr, &dataNumElements, sizeof(size_t) ); _msgBufPtr = PackData( _msgBufPtr, dataPtr, dataNumElements*sizeof(uint32_t) ); _msgBufPtr = PackData( _msgBufPtr, outputNumElementsPtr, sizeof(size_t) ); _msgBufPtr = PackString( _msgBufPtr, label ); _msgBufPtr = PackData( _msgBufPtr, &responseNumElements, sizeof(size_t) ); _msgBufPtr = PackData( _msgBufPtr, &moreNumElements, sizeof(size_t) ); // 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 any "out" parameters _msgBufPtr = UnpackData( _msgBufPtr, bPtr, sizeof(uint32_t) ); _msgBufPtr = UnpackData( _msgBufPtr, outputNumElementsPtr, sizeof(size_t) ); _msgBufPtr = UnpackData( _msgBufPtr, outputPtr, *outputNumElementsPtr*sizeof(uint32_t) ); _msgBufPtr = UnpackDataString( _msgBufPtr, response, responseNumElements*sizeof(char) ); _msgBufPtr = UnpackDataString( _msgBufPtr, more, moreNumElements*sizeof(char) ); // Release the message object, now that all results/output has been copied. le_msg_ReleaseMsg(_responseMsgRef); }