/** * @file rmservices.c * * @brief * This is the Resource Manager services source. * * \par * ============================================================================ * @n (C) Copyright 2012, Texas Instruments, Inc. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the * distribution. * * Neither the name of Texas Instruments Incorporated nor the names of * its contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * * \par */ /* RM Types */ #include /* RM external API includes */ #include /* RM internal API includes */ #include /* RM OSAL layer */ #include /********************************************************************** ********************** Internal Functions **************************** **********************************************************************/ void Rm_serviceHandler (void *rmHandle, Rm_ServiceReqInfo *serviceRequest, Rm_ServiceRespInfo *serviceResponse) { Rm_Inst *rmInst = (Rm_Inst *)rmHandle; Rm_Transaction *transaction; /* Make sure that a callback function has been provided */ if (serviceRequest->callback.serviceCallback == NULL) { /* The RM Client and Client Delegate use blocking transports to consult with a * high-level RM agent prior to providing a response to the component. It is * assumed the component's cannot block. Therefore, all responses must go * through the callback function provided by the component. Return an error * if the component does not provide a callback function. */ serviceResponse->serviceState = RM_SERVICE_ERROR_CALLBACK_NOT_PROVIDED; return; } /* Create a new transaction */ transaction = Rm_transactionQueueAdd(rmInst); if (transaction == NULL) { /* Failed to create a new transaction */ serviceResponse->serviceState = RM_SERVICE_ERROR_TRANSACTION_FAILED_TO_ALLOCATE; } else { /* Transfer request information into the transaction */ transaction->type = serviceRequest->type; strcpy(transaction->serviceSrcInstName, rmInst->name); transaction->callback.serviceCallback = serviceRequest->callback.serviceCallback; transaction->state = RM_SERVICE_PROCESSING; strcpy(&(transaction->resourceInfo.name)[0], serviceRequest->resourceName); transaction->resourceInfo.base = serviceRequest->resourceBase; transaction->resourceInfo.length = serviceRequest->resourceLength; transaction->resourceInfo.alignment = serviceRequest->resourceAlignment; strcpy(&(transaction->resourceInfo.nsName)[0], serviceRequest->resourceNsName); /* Pass the new transaction to the transaction processor */ Rm_transactionProcessor (rmInst, transaction); /* Provide response to the component that requested the service */ serviceResponse->serviceState = transaction->state; if (serviceResponse->serviceState == RM_SERVICE_PROCESSING) { /* The service is still being processed. Provide the transaction ID * back to the component so that it can sort service responses received * via the provided callback function */ serviceResponse->serviceId = transaction->localId; } else if (serviceResponse->serviceState == RM_SERVICE_APPROVED_AND_COMPLETED) { /* Service was approved and service was an allocate request the resource * data is passed back to the component */ if ((transaction->type == Rm_service_RESOURCE_ALLOCATE) || (transaction->type == Rm_service_RESOURCE_GET_BY_NAME)) { strcpy(serviceResponse->resourceName, transaction->resourceInfo.name); serviceResponse->resourceBase = transaction->resourceInfo.base; serviceResponse->resourceLength = transaction->resourceInfo.length; } /* Delete the transaction since a response was received immediately */ Rm_transactionQueueDelete(rmInst, transaction->localId); } else { /* The serviceState field will contain information regarding why the * service was denied or what error the service encountered. Just delete * the transaction since a response was received immediately */ Rm_transactionQueueDelete(rmInst, transaction->localId); } } return; } /* This function is executed when a RM instance receives a response to one of its requests * and the information in the request must be provided to the original requesting component */ void Rm_serviceResponder (Rm_Inst *rmInst, Rm_Transaction *transaction) { Rm_ServiceRespInfo serviceResponse; /* The responseTransaction will contain the resultant state details of * the requestTransaction's service request */ serviceResponse.serviceState = transaction->state; /* Pass back the ID that was provided to the component when it requested * the service */ serviceResponse.serviceId = transaction->localId; /* Service was approved and service was an allocate request. The resource * data is passed back to the component */ if ((serviceResponse.serviceState == RM_SERVICE_APPROVED_AND_COMPLETED) && ((transaction->type == Rm_service_RESOURCE_ALLOCATE) || (transaction->type == Rm_service_RESOURCE_GET_BY_NAME))) { strcpy(serviceResponse.resourceName, transaction->resourceInfo.name); serviceResponse.resourceBase = transaction->resourceInfo.base; serviceResponse.resourceLength = transaction->resourceInfo.length; } /* Issue the callback to the requesting component with the response information */ transaction->callback.serviceCallback(&serviceResponse); /* Delete the transaction from the transaction queue */ Rm_transactionQueueDelete(rmInst, transaction->localId); return; } /********************************************************************** ********************** Application visible APIs ********************** **********************************************************************/ void Rm_preMainAllocService(Rm_PreMainAllocInfo *preMainAllocInfo, Rm_ServiceRespInfo *serviceResponse) { } Rm_ServicePort *Rm_getServicePort(Rm_Handle rmHandle) { Rm_ServicePort *newServicePort = NULL; /* Create a new service handle for the specified RM instance */ /* Get memory for a new service port from local memory */ newServicePort = Rm_osalMalloc (sizeof(Rm_ServicePort)); /* Return NULL immediately if malloc returned NULL */ if (newServicePort == NULL) { return (newServicePort); } newServicePort->rmHandle = rmHandle; newServicePort->rmService = Rm_serviceHandler; return (newServicePort); } /** @} */