summary | shortlog | log | commit | commitdiff | tree
raw | patch | inline | side by side (parent: 9b41022)
raw | patch | inline | side by side (parent: 9b41022)
author | Justin Sobota <jsobota@ti.com> | |
Fri, 2 Nov 2012 20:44:39 +0000 (16:44 -0400) | ||
committer | Justin Sobota <jsobota@ti.com> | |
Fri, 2 Nov 2012 20:44:39 +0000 (16:44 -0400) |
include/rm_pvt.h | patch | blob | history | |
rm_services.h | patch | blob | history | |
src/rm.c | patch | blob | history |
diff --git a/include/rm_pvt.h b/include/rm_pvt.h
index bbb1016f513ccad7b24665b3cf9df6dffdcf5f83..190bf41ca1636a1d0667f7bf258a3e1a855c746f 100644 (file)
--- a/include/rm_pvt.h
+++ b/include/rm_pvt.h
#define RM_MAX_POLICY_SIZE_BYTES (64) // Placeholder: This will change
// during development
-/* Pointer to RM instance's transport routing map */
+/** Pointer to RM instance's transport routing map */
typedef void *Rm_TransRouteMap;
-typedef Rm_ServiceResult Rm_TransactionResult;
+/** Pointer to RM instance's transaction queue */
+typedef void *Rm_TransactionQueue;
/**
* @brief RM transport routing map linked list node
Rm_TransRouteMapNode *nextNode;
} Rm_TransRouteMapNode;
+/**
+ * @brief RM transaction queue linked list node
+ */
+typedef struct {
+ /** The transaction ID for the transaction awaiting a response */
+ uint32_t transactionId;
+ /** The callback function associated with the transaction ID. Will
+ * be called when a response is received matching the transaction ID. */
+ void *transactionCallback;
+ /** Link to the next transaction queue entry */
+ Rm_TransactionQueueEntry *nextEntry;
+} Rm_TransactionQueueEntry;
+
/**
* @brief RM protocol commands. The first N commands should be synchronized with
* the Rm_ServiceType enum in rm_service.h
Rm_command_POLICY_RESPONSE
} Rm_Command;
+
+/* REMOVE BELOW??? */
+/**
+ * @brief RM transaction states. The transaction state describes what processes have
+ * been executed on the transaction thus far
+ */
+typedef enum {
+ /** Transaction is being processed */
+ Rm_transactionState_PROCESSING = 0,
+ /** Transaction has been approved */
+ Rm_transactionState_APPROVED = 1,
+ /** Transaction has been denied */
+ Rm_transactionState_DENIED = 2
+} Rm_TransactionState;
+
/**
* @brief RM protocol packet resource information
*/
* from components and RM commands received from other RM instances.
*/
typedef struct {
- /* Transaction type */
- Rm_Command transType;
- /* Transaction details */
+ /** Transaction type */
+ Rm_Command transCommand;
+ /** Packet ID of packet that transaction originated from. This field will be
+ * NULL if transaction originated from a component */
+ uint32_t transPktId;
+ /** Transaction's associated callback function is the transaction originated
+ * from a registered component */
+ void *transCallback;
+ /** Transaction details */
union {
/** If the command has to do with resources these fields
* will contain the resource information */
- Rm_ResourceInfo transInfo;
+ Rm_ResourceInfo resourceInfo;
/** Pointer to policy data if the command has to do with policies */
char *policyData;
} u;
* a component that requested a service or a RM instance that sent a command.
*/
typedef struct {
+ int32_t transactionResult;
uint32_t transactionId;
uint32_t resBase;
uint32_t resNum;
/* RM instance transport parameters */
Rm_TransRouteMap routeMap;
+ /* RM transaction queue */
+ Rm_TransactionQueue transactionQueue;
/* Transport API function pointers - not global in case application wants to
* hook up different transports to RM */
Rm_TransportCallouts transport;
diff --git a/rm_services.h b/rm_services.h
index c4b915737be39a1aee0f6a8e145a7b33ab33df54..501a77ee0c7c20d14227ab62d88a104836c1c335 100644 (file)
--- a/rm_services.h
+++ b/rm_services.h
*/
#define RM_SERVICE_INDEX_NOT_SPECIFIED (-1)
-/**
- * @brief Result of requested RM service
- */
-typedef enum {
- /** RM Service was okay */
- RM_service_OKAY = 0,
- /** RM Service request not recognized */
- RM_service_INVALID_SERVICE_TYPE = 1
-} Rm_ServiceResult;
+/** RM Service Request (serviceResult) Action Codes and Errors */
+/** RM Service Request Action Code Base */
+#define RM_SERVICE_ACTION_BASE (0)
+/** RM service was approved. The resource data in the response is valid if
+ * the service has been approved. */
+#define RM_SERVICE_APPROVED (RM_SERVICE_ACTION_BASE)
+/** RM service was denied. The resource data in the response is not valid */
+#define RM_SERVICE_DENIED (RM_SERVICE_APPROVED+1)
+/** RM service is being processed. Typically this means the service is
+ * being sent to a higher level RM agent for processing */
+#define RM_SERVICE_PROCESSING (RM_SERVICE_DENIED+2)
+
+/** RM Service Request Error Code Base */
+#define RM_SERVICE_ERROR_BASE (-64)
+/** RM service request type not recognized */
+#define RM_SERVICE_ERROR_INVALID_SERVICE_TYPE (RM_SERVICE_ERROR_BASE)
+/** RM Service request was not provided a component callback
+ * function. Service requests may result in blocking operations. A callback
+ * function must always be provided with a service request since
+ * blocked or non-blocked operations cannot be promised. */
+#define RM_SERVICE_ERROR_CALLBACK_NOT_PROVIDED (RM_SERVICE_ERROR_BASE-1)
+/** RM service request needs to be forwarded to another RM agent but no transports
+ * have been registered */
+#define RM_SERVICE_ERROR_NO_TRANSPORT_REGISTERED (RM_SERVICE_ERROR_BASE-2)
+/** RM service request needs to be forwarded but no client delegate or server has
+ * been registered with the RM instance */
+#define RM_SERVICE_ERROR_NOT_REGISTERED_WITH_DEL_OR_SERVER (RM_SERVICE_ERROR_BASE-3)
+/** RM service request needs to be forwarded but the transport packet alloc API
+ * has not been provided */
+#define RM_SERVICE_ERROR_TRANSPORT_PKT_ALLOC_API_NULL (RM_SERVICE_ERROR_BASE-4)
+/** RM service request needs to be forwarded but the transport packet alloc returned
+ * NULL for the packet buffer */
+#define RM_SERVICE_ERROR_TRANSPORT_NULL_PKT_BUF (RM_SERVICE_ERROR_BASE-5)
+/** RM service request needs to be forwarded but the buffer allocated by transport
+ * is not large enough to fit the RM transport packet */
+#define RM_SERVICE_ERROR_TRANSPORT_PKT_BUF_TOO_SMALL (RM_SERVICE_ERROR_BASE-6)
+/** RM service request needs to be forwarded but the transport returned an error
+ * when trying to send the RM packet to the higher level agent */
+#define RM_SERVICE_ERROR_TRANPSPORT_SEND_ERROR (RM_SERVICE_ERROR_BASE-7)
+/** RM service request needs to be forwarded but the transport packet send API
+ * has not been provided */
+#define RM_SERVICE_ERROR_TRANSPORT_PKT_SEND_API_NULL (RM_SERVICE_ERROR_BASE-8)
/**
* @brief RM service types
*/
typedef enum {
+ /** First service type. Used by RM for bounds checking. Should
+ * not be used by component. */
+ Rm_service_FIRST = 0,
/** RM resource allocate service */
Rm_service_RESOURCE_ALLOCATE = 0,
/** RM resource block allocate service */
- Rm_service_RESOURCE_BLOCK_ALLOCATE,
+ Rm_service_RESOURCE_BLOCK_ALLOCATE = 1,
/** RM resource allocate by name service */
- Rm_service_RESOURCE_ALLOCATE_BY_NAME,
+ Rm_service_RESOURCE_ALLOCATE_BY_NAME = 2,
/** RM resource free service */
- Rm_service_RESOURCE_FREE,
+ Rm_service_RESOURCE_FREE = 3,
/** RM resource block free service */
- Rm_service_RESOURCE_BLOCK_FREE,
+ Rm_service_RESOURCE_BLOCK_FREE = 4,
/** RM resource free by name service */
- Rm_service_RESOURCE_FREE_BY_NAME,
+ Rm_service_RESOURCE_FREE_BY_NAME = 5,
/** RM resource mapping to name service */
- Rm_service_RESOURCE_MAP_TO_NAME,
+ Rm_service_RESOURCE_MAP_TO_NAME = 6,
/** RM resource name unmapping service */
- Rm_service_RESOURCE_UNMAP_NAME,
+ Rm_service_RESOURCE_UNMAP_NAME = 7,
/** RM resource status service */
- Rm_service_RESOURCE_STATUS
+ Rm_service_RESOURCE_STATUS = 8,
+ /** Last service type. Used by RM for bounds checking. Should
+ * not be used by component. */
+ Rm_service_LAST = 8
} Rm_ServiceType;
/**
- * @brief RM service response information provided by RM back to the requesting component
+ * @brief RM service response information provided by RM back to the
+ * requesting component
*/
typedef struct {
+ /** Result of the service request
+ * Non-negative result: RM has taken an action based on the request
+ * Negative result: RM has encountered an error handling the request */
+ int32_t serviceResult;
/** A request ID will be returned to the component if the requested service cannot
- * be completed immediately. The request ID can be used by the component to identify
- * service responses received via the component callback function. A request ID will not
- * be returned if the service request is satisfied immediately */
+ * be completed immediately. The request ID can be used by the component to identify
+ * service responses received via the component callback function. A request ID will not
+ * be returned if the service request is satisfied immediately */
uint32_t requestId;
- /** The value of the returned resource. In the case of a block resource allocation response
- * this field will contain the base value of the block. */
+ /** The base value of the returned resource. In the case of a block resource allocation
+ * response this field will contain the base value of the block. */
int32_t resBase;
/** The number of resources allocated in block requests */
uint32_t resNum;
/** The resource base value. */
int32_t resBase;
/** The number of the specified resources. Will be greater than one only
- * for block allocate and free service requests. */
+ * for block allocate and free service requests. */
uint32_t resNum;
/** Resource alignment in block allocation requests */
uint32_t resAlign;
/** The name server name associated with the resource. Used only for
- * allocate and free by name service requests */
+ * allocate and free by name service requests */
char *resNsName;
/** Component callback function. RM will call this function when the
* resource service request is completed. The callback function supplied
* for this parameter must match this function pointer prototype. */
- void (*serviceCallback) (Rm_ServiceResult rmResult, char *resourceName,
- uint32_t resourceIndex);
+ void (*serviceCallback) (Rm_ServiceRespInfo *responseInfo);
} Rm_ServiceReqInfo;
-
/**
* @brief RM Service Handle provided to software components that
* request RM services for the resources they control
* @param[in] responseInfo
* Service response structure that provides details of RM's response to the
* service request
- *
- * @retval
- * Success - 0 - Service request was handled okay.
- * @retval
- * Failure - non-zero - Service request error.
*/
- Rm_ServiceResult (*rmService)(void *rmHandle, Rm_ServiceReqInfo *requestInfo,
- Rm_ServiceRespInfo *responseInfo);
+ void (*rmService)(void *rmHandle, Rm_ServiceReqInfo *requestInfo,
+ Rm_ServiceRespInfo *responseInfo);
} Rm_ServicesPort;
/**
diff --git a/src/rm.c b/src/rm.c
index 8f54b2ef90baf6e45a0182c10062bdd3418fb417..f4f134dde2a101f74eeb23f621d7bf0c1ca11f53 100644 (file)
--- a/src/rm.c
+++ b/src/rm.c
@@ -66,32 +66,176 @@ Rm_Perms rmQmssPdspFirmwarePerms[RM_ALIGN_PERMISSIONS_ARRAY(RM_QMSS_FIRMWARE_PDS
const char rmVersionStr[] = RM_VERSION_STR ":" __DATE__ ":" __TIME__;
/**********************************************************************
- ********************** Internal Functions *********************************
+ ********************** Internal Functions ****************************
**********************************************************************/
-Rm_TransactionResult rmTransactionForwarder (void *rmHandle, Rm_Transaction *transInfo,
- Rm_TransactionReceipt *transReceipt)
+void Rm_transactionQueueAdd(void *rmHandle, uint32_t transactionId, void *callbackFunc)
+{
+ Rm_Inst *rmInst = (Rm_Inst *)rmHandle;
+ Rm_TransactionQueueEntry *transactionQueue = (Rm_TransactionQueueEntry *) rmInst->transactionQueue;
+ Rm_TransactionQueueEntry *newEntry;
+ void *key;
+
+ /* Lock access to the RM instance's transaction queue */
+ key = Rm_osalLocalCsEnter();
+
+ /* Get memory for a new transaction queue entry from local memory */
+ newEntry = Rm_osalMalloc (sizeof(Rm_TransactionQueueNode), false);
+
+ /* Populate the new entry. */
+ newEntry->transactionId = transactionId;
+ newEntry->transactionCallback = callbackFunc;
+ newEntry->nextEntry = NULL; /* New entry's nextEntry pointer will always be NULL */
+
+ /* Check if there are any entries in the transaction queue */
+ if (transactionQueue)
+ {
+ /* At least one entry in the transaction queue. Add the new entry to the end of the
+ * transaction queue */
+ while (transactionQueue->nextEntry != NULL)
+ {
+ /* Traverse the list until arriving at the last entry */
+ transactionQueue = transactionQueue->nextEntry;
+ }
+
+ /* Add the new entry to the end of the queue */
+ transactionQueue->nextEntry = newEntry;
+ }
+ else
+ {
+ /* The transaction queue does not currently exist. The new entry is the first entry */
+ rmInst->routeMap = newEntry;
+ }
+
+ Rm_osalLocalCsExit(key);
+}
+
+Rm_TransactionQueueEntry *Rm_transactionQueueFind(void *rmHandle, uint32_t transactionId)
+{
+ Rm_Inst *rmInst = (Rm_Inst *)rmHandle;
+ Rm_TransactionQueueEntry *entry = (Rm_TransactionQueueEntry *) rmInst->transactionQueue;
+ void *key;
+
+ /* Lock access to the RM instance's transaction queue */
+ key = Rm_osalLocalCsEnter();
+
+ /* Make sure there is at least one entry in the transaction queue */
+ if (entry != NULL)
+ {
+ /* Find the transaction ID within the specified RM instance's transaction queue.
+ * If the end of the transaction queue is reached without finding the entry the
+ * entry pointer will be NULL */
+ while (entry != NULL)
+ {
+ if (entry->transactionId == transactionId)
+ {
+ /* Match: break out of loop and return the entry */
+ break;
+ }
+ entry = entry->nextEntry;
+ }
+ }
+
+ Rm_osalLocalCsExit(key);
+ return (entry);
+}
+
+uint32_t Rm_transactionQueueDelete(void *rmHandle, uint32_t transactionId)
+{
+ Rm_Inst *rmInst = (Rm_Inst *)rmHandle;
+ Rm_TransactionQueueEntry *currentEntry = (Rm_TransactionQueueEntry *) rmInst->transactionQueue;
+ Rm_TransactionQueueEntry *prevEntry = NULL;
+ void *key;
+
+ /* Lock access to the RM instance's transaction queue */
+ key = Rm_osalLocalCsEnter();
+
+ /* Make sure there is at least one entry in the transaction queue */
+ if (currentEntry == NULL)
+ {
+ Rm_osalLocalCsExit(key);
+ return (-1); /* TEMP ERROR RETURN */
+ }
+
+ /* Find the transaction ID within the specified RM instance's transaction queue. */
+ while (currentEntry != NULL)
+ {
+ if (currentEntry->transactionId == transactionId)
+ {
+ /* Match: break out of loop and delete the entry */
+ break;
+ }
+
+ prevEntry = currentEntry;
+ currentEntry = currentEntry->nextEntry;
+ }
+
+ /* Traversed entire queue but did not find transaction */
+ if (currentEntry == NULL)
+ {
+ Rm_osalLocalCsExit(key);
+ return (-2); /* TEMP ERROR RETURN */
+ }
+ else
+ {
+ /* Delete the transaction queue entry */
+ if ((prevEntry == NULL) && currentEntry->nextEntry)
+ {
+ /* Entry to be deleted exists at start of transaction queue. Map second
+ * entry to be start of transaction queue as long as there are more than
+ * one entries */
+ rmInst->transactionQueue = currentEntry->nextNode;
+ }
+ else
+ {
+ /* Entry to be deleted is in the middle or at end of the queue. Adjust adjacent
+ * entry pointers. This covers the case where the entry to be removed is at the
+ * end of the queue. */
+ prevEntry->nextNode = currentEntry->nextNode;
+ }
+
+ /* Delete the node, free the memory associated with the node. */
+ Rm_osalFree((void *) currentEntry, sizeof(Rm_TransactionQueueEntry), false);
+ }
+
+ Rm_osalLocalCsExit(key);
+ return (0); /* RETURN OKAY - FIX MAGIC NUMBER */
+}
+
+/* Used in Client Delegate case where it forwarded requests from Client to Server
+ * callback will direct to internal function that forwards response from server back
+ * to client */
+void Rm_internalCallback (Rm_ServiceRespInfo *responseInfo)
+{
+
+}
+
+void Rm_transactionForwarder (void *rmHandle, Rm_Transaction *transInfo,
+ Rm_TransactionReceipt *transReceipt)
{
Rm_Inst *rmInst = (Rm_Inst *) rmHandle;
Rm_TransRouteMapNode *routeMap = (Rm_TransRouteMapNode *) rmInst->routeMap;
- Rm_ProtocolPkt *rmPkt = NULL;
+ uint32_t transactionId;
+ Rm_Packet *rmPkt = NULL;
+ Rm_ProtocolPkt *rmProtPkt = NULL;
- /* Error if no transports have been registered and a service has been requested that
- * must be forwarded to another RM agent */
+ /* Make sure at least one transport has been registered */
if (routeMap == NULL)
{
- return (-1); /* temp error */
+ transReceipt->transactionResult = RM_SERVICE_ERROR_NO_TRANSPORT_REGISTERED;
+ return;
}
/* Make sure the RM instance has a transport registered with a higher level agent */
if (!rmInst->registeredWithDelegateOrServer)
{
- return (-1); /* temp error - can't handle request because client delegate or server not registered */
+ transReceipt->transactionResult = RM_SERVICE_ERROR_NOT_REGISTERED_WITH_DEL_OR_SERVER;
+ return;
}
/* Parse the RM instance's routing map to find the higher level agent for forwarding */
while ((routeMap->remoteInstType != Rm_instType_CLIENT_DELEGATE) ||
- (routeMap->remoteInstType != Rm_instType_SERVER))
+ (routeMap->remoteInstType != Rm_instType_SERVER))
{
/* Traverse the list until arriving at the upper level agent node */
routeMap = routeMap->nextNode;
@@ -100,82 +244,187 @@ Rm_TransactionResult rmTransactionForwarder (void *rmHandle, Rm_Transaction *tra
/* Create a RM packet using the service information */
if (rmInst->transport.rmAllocPkt)
{
- rmPkt = rmInst->transport.rmAllocPkt (routeMap->transHandle, sizeof(Rm_ProtocolPkt));
+ rmPkt = rmInst->transport.rmAllocPkt(routeMap->transHandle, sizeof(Rm_Packet));
+ }
+ else
+ {
+ /* The transport packet alloc API is not plugged */
+ transReceipt->transactionResult = RM_SERVICE_ERROR_TRANSPORT_PKT_ALLOC_API_NULL;
+ return;
}
- /* Return error if the packet allocation API is not plugged or if a NULL packet pointer
- * was returned */
- if (!rmPkt)
+ /* Make sure a buffer for the packet was allocated */
+ if (rmPkt == NULL)
{
- return (-1); /* temp error */
+ transReceipt->transactionResult = RM_SERVICE_ERROR_TRANSPORT_NULL_PKT_BUF;
+ return;
+ }
+
+ /* Make sure allocated buffer is large enough to fit the protocol packet plus the
+ * rmPktLen field */
+ if (rmPkt->rmPktLen < (sizeof(Rm_ProtocolPkt) + sizeof(uint32_t))
+ {
+ transReceipt->transactionResult = RM_SERVICE_ERROR_TRANSPORT_PKT_BUF_TOO_SMALL;
+ return;
}
+ /* Create an ID for this transaction. The ID will be used for two purposes:
+ * 1) Matching the response from the higher level RM agent to the request
+ * 2) Provided to the service requesting component so that it can match the
+ * service request with the response it receives via its callback function */
+ transactionId = ...; /* NEED SCHEME FOR CREATING A MUTUALLY EXCLUSIVE PKT ID. CAN'T
+ * CONFLICT WITH PCKT IDS CREATED ON OTHER RM INSTANCES */
+ /* Initialize the rmPkt. Do not assume the transport code will do it */
+ memset((void *)rmPkt, 0, sizeof(Rm_Packet));
+
+ /* Assign the rmData field to be the rmProtPkt */
+ rmProtPkt = &(rmPkt->rmData[0]);
/* Populate the RM packet using the service information */
+ rmProtPkt->rmPktId = transactionId;
+ strcpy((void *)rmProtPkt->rmInstName,(void *)rmInst->name);
+ rmProtPkt->rmCmd = (uint32_t) transInfo->transType;
+ if ((transInfo->transCommand == Rm_command_POLICY_REQUEST) ||
+ (transInfo->transCommand == Rm_command_POLICY_RESPONSE)
+ {
+ /* Copy the policy data if the transaction is policy based */
+ memcpy ((void *)rmProtPkt->u.rmPolicyData, (void *)transInfo->u.policyData,
+ RM_MAX_POLICY_SIZE_BYTES);
+ }
+ else
+ {
+ /* Otherwise copy the resource data */
+ memcpy ((void *)&(rmProtPkt->u.resInfo), (void *) &(transInfo->u.resourceInfo),
+ sizeof(Rm_ResourceInfo));
+ }
+ /* Create an entry in the transaction queue */
+ Rm_transactionQueueAdd(rmHandle, transactionId, transInfo->transCallback);
+ /* Send the RM packet to the application transport */
+ if (rmInst->transport.rmSend)
+ {
+ if (!(rmInst->transport.rmSend(routeMap->transHandle, rmPkt))
+ {
+ /* Transport returned an error */
- /* Inform component that requested the service that the resource is being requested
- * from the higher level RM agent. The component must assume the resource service
- * result will be returned using the specified callback function */
- return (RM_REQUESTING_RESOURCE);
+ /* SHOULD TRANSPORT ERROR SOMEHOW BE OR'D WITH THE SERVICE ERROR ??? */
+ transReceipt->transactionResult = RM_SERVICE_ERROR_TRANPSPORT_SEND_ERROR;
+ return;
+ }
+ }
+ else
+ {
+ /* The transport packet send API is not plugged */
+ transReceipt->transactionResult = RM_SERVICE_ERROR_TRANSPORT_PKT_SEND_API_NULL;
+ return;
+ }
+
+ /* Inform requesting component that the service is being forwarded to a higher lever
+ * RM agent for processing. The result of the service will be provided to the
+ * component via the specified callback function */
+ transReceipt->transactionResult = RM_SERVICE_PROCESSING;
+ transReceipt->transactionId = transactionId;
+ return;
}
-Rm_TransactionResult rmTransactionProcessor (rmHandle, Rm_Transaction *newTransaction,
- Rm_TransactionReceipt *newTransactionReceipt)
+void Rm_transactionProcessor (void *rmHandle, Rm_Transaction *transaction,
+ Rm_TransactionReceipt *transactionReceipt)
{
+ Rm_Inst *rmInst = (Rm_Inst *)rmHandle;
+
+ /* All service requests on Clients are forwarded to the higher level RM agent
+ * either a Client Delegate or Server, based on the RM system architecture */
+ if (rmInst->instType == Rm_instType_CLIENT)
+ {
+ Rm_transactionForwarder(rmHandle, transaction, transactionReceipt);
+
+ if (requestInfo->serviceCallback == NULL)
+ {
+ /* RM Client's always use a blocking RM transport 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 */
+ }
+
+ /* Provide a transaction ID back to the component so that it can map service requests
+ * to the responses received via the component's callback function */
+ responseInfo->requestId = transactionReceipt.transactionId;
+ }
+ else
+ {
+
+
+ }
}
-Rm_ServiceResult rmServiceHandler (void *rmHandle, Rm_ServiceReqInfo *requestInfo,
- Rm_ServiceRespInfo *responseInfo)
+void Rm_serviceHandler (void *rmHandle, Rm_ServiceReqInfo *requestInfo,
+ Rm_ServiceRespInfo *responseInfo)
{
Rm_Inst *rmInst = (Rm_Inst *) rmHandle;
- Rm_Transaction newTransaction;
- Rm_TransactionReceipt newTransactionReceipt;
- Rm_ServiceResult retVal = RM_service_OKAY;
+ Rm_Transaction transaction;
+ Rm_TransactionReceipt transactionReceipt;
void *key;
/* Prevent another component using the same instance from wiping out the current
* service request */
key = Rm_osalLocalCsEnter();
+ /* Make sure serviceType is valid and that a callback function has been provided */
+ if ((requestInfo->serviceType < Rm_service_FIRST) ||
+ (requestInfo->serviceType > Rm_service_LAST))
+ {
+ responseInfo->serviceResult = RM_SERVICE_ERROR_INVALID_SERVICE_TYPE;
+ Rm_osalLocalCsExit(key);
+ return;
+ }
+ else if (requestInfo->serviceCallback == NULL)
+ {
+ responseInfo->serviceResult = RM_SERVICE_ERROR_CALLBACK_NOT_PROVIDED;
+ Rm_osalLocalCsExit(key);
+ return;
+ }
+
+ /* Clear the transaction and receipt prior to using them */
+ memset((void *) &transaction, 0, sizeof(Rm_Transaction));
+ memset((void *) &transactionReceipt, 0, sizeof(Rm_TransactionReceipt));
+
/* Transfer request information into the internal transaction format */
- newTransaction.transType = (Rm_Command) requestInfo->serviceType;
+ transaction.transCommand = (Rm_Command) requestInfo->serviceType;
+ transaction.transCallback = requestInfo->serviceCallback;
/* Policy modifications will never originate from components */
- strcpy ((void *) &(newTransaction.u.transInfo.resName)[0], (void *)requestInfo->resName);
- newTransaction.u.transInfo.resBase = requestInfo->resourceAlign;
- newTransaction.u.transInfo.resNum = requestInfo->resourceNum;
- newTransaction.u.transInfo.resAlign = requestInfo->resourceAlign;
- strcpy ((void *) &(newTransaction.u.transInfo.resNsName)[0], (void *)requestInfo->resNsName);
-
- /* All service requests on Clients are forwarded to the higher level RM agent
- * either a Client Delegate or Server, based on the RM system architecture */
- if (rmInst->instType == Rm_instType_CLIENT)
+ strcpy ((void *) &(transaction.u.resourceInfo.resName)[0], (void *)requestInfo->resName);
+ transaction.u.resourceInfo.resBase = requestInfo->resourceBase;
+ transaction.u.resourceInfo.resNum = requestInfo->resourceNum;
+ transaction.u.resourceInfo.resAlign = requestInfo->resourceAlign;
+ strcpy ((void *) &(transaction.u.resourceInfo.resNsName)[0], (void *)requestInfo->resNsName);
+
+ /* Pass the new transaction to the transaction processor */
+ Rm_transactionProcessor (rmHandle, &transaction, &transactionReceipt);
+
+ /* Copy transaction receipt information into the response info fields for the
+ * component based on the result of the transaction. Denied service requests
+ * will have only a valid serviceResult field */
+ responseInfo->serviceResult = transactionReceipt->transactionResult;
+ if (responseInfo->serviceResult == RM_SERVICE_APPROVED)
{
- retVal = (Rm_ServiceResult) rmTransactionForwarder (rmHandle, &newTransaction, &newTransactionReceipt);
-
- /* Copy internal transaction receipt information into the response info fields for the
- * component */
- responseInfo->requestId = newTransactionReceipt.transactionId;
- responseInfo->resBase = newTransactionReceipt.resBase;
- responseInfo->resNum = newTransactionReceipt.resNum;
+ /* Service was approved. The resource data should be passed back
+ * to the component */
+ responseInfo->resBase = transactionReceipt.resBase;
+ responseInfo->resNum = transactionReceipt.resNum;
}
- else
+ else if (responseInfo->serviceResult == RM_SERVICE_PROCESSING)
{
- /* Directly handle the request if on a Client Delegate or Server. On Client Delegates, if
- * the request cannot be serviced it will be forwarded to the higher level RM instance. */
- retVal = (Rm_ServiceResult) rmTransactionProcessor (rmHandle, &newTransaction, &newTransactionReceipt);
-
- /* Copy internal transaction receipt information into the response info fields for the
- * component */
- responseInfo->requestId = newTransactionReceipt.transactionId;
- responseInfo->resBase = newTransactionReceipt.resBase;
- responseInfo->resNum = newTransactionReceipt.resNum;
+ /* 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 */
+ responseInfo->requestId = transactionReceipt.transactionId;
}
Rm_osalLocalCsExit(key);
- return (retVal);
+ return;
}
/**********************************************************************
rmInst->transport.rmNumPktsReceived = initCfg->rmNumPktsReceivedFuncPtr;
/* Initialize the transport routing map linked list pointer to NULL. The linked list
- * nodes will be created when the application registers transports */
+ * nodes will be created when the application registers transports */
rmInst->routeMap = NULL;
+ /* Initialize the transaction queue linked list pointer to NULL. The linked list
+ * nodes will be created when the transactions are forwarded to higher level RM
+ * agents. */
+ rmInst->transactionQueue= NULL;
+
/* RM Server specific actions */
if (rmInst->instType == Rm_instType_SERVER)
{
-
+ /* parse DTB, etc */
}
/* Instance startup policies are only used for Servers and Client Delegates */
return ((Rm_ServiceHandle) newServicePort);
}
-Rm_TransportHandle Rm_registerTransport (Rm_Handle rmHandle,
- Rm_TransCfg *transCfg)
+/* Resource requests that come directly from application go through this API */
+void Rm_requestService (void *rmHandle, Rm_ServiceReqInfo *requestInfo,
+ Rm_ServiceRespInfo *responseInfo)
+{
+ Rm_serviceHandler(rmHandle, requestInfo, responseInfo);
+}
+
+Rm_TransportHandle Rm_registerTransport (Rm_Handle rmHandle, Rm_TransCfg *transCfg)
{
Rm_Inst *rmInst = (Rm_Inst *) rmHandle;
Rm_TransRouteMapNode *existingRouteMap = (Rm_TransRouteMapNode *) rmInst->routeMap;
return (NULL); /* Error -return null */
}
- /* Verify Clients and Client Delegates are not registering with more than one Client Delegate or Server.
- * Assuming a Client Delegate can register with another Client Delegate that can "act" as a server */
- if (((rmInst->instType == Rm_instType_CLIENT) || (rmInst->instType == Rm_instType_CLIENT_DELEGATE)) &&
- ((transCfg->rmRemoteInstType == Rm_instType_CLIENT_DELEGATE) ||
- (transCfg->rmRemoteInstType == Rm_instType_SERVER)) &&
- rmInst->registeredWithDelegateOrServer)
+ /* Verify Clients and Client Delegates are not registering with more than one
+ * Client Delegate or Server. Assuming a Client Delegate can register with another
+ * Client Delegate that can "act" as a server */
+ if (((rmInst->instType == Rm_instType_CLIENT) ||
+ (rmInst->instType == Rm_instType_CLIENT_DELEGATE)) &&
+ ((transCfg->rmRemoteInstType == Rm_instType_CLIENT_DELEGATE) ||
+ (transCfg->rmRemoteInstType == Rm_instType_SERVER)) &&
+ rmInst->registeredWithDelegateOrServer)
{
return (NULL); /* Error -return null */
}
/* Specify RM instance has registered with a higher level agent */
if ((newRouteMapNode->remoteInstType == Rm_instType_CLIENT_DELEGATE) ||
- (newRouteMapNode->remoteInstType == Rm_instType_SERVER))
+ (newRouteMapNode->remoteInstType == Rm_instType_SERVER))
{
rmInst->registeredWithDelegateOrServer = true;
}
@@ -325,7 +587,7 @@ Rm_Result Rm_unregisterTransport (Rm_Handle rmHandle, Rm_TransportHandle transHa
Rm_TransRouteMapNode *prevNode = NULL;
/* Make sure a routing map exists for the RM instance */
- if (!routeMapNode)
+ if (routeMapNode == NULL)
{
return (-1); /* TEMP ERROR RETURN */
}
@@ -333,18 +595,18 @@ Rm_Result Rm_unregisterTransport (Rm_Handle rmHandle, Rm_TransportHandle transHa
/* Find the transport handle within the specified RM instance's routing map. */
while (1)
{
- if (routeMapNode->transHandle == transHandle)
- {
- /* Match: break out of loop and delete the node */
- break;
- }
- else if (routeMapNode->nextNode == NULL)
- {
- return (-1); /* TEMP ERROR: transhandle does not exist for RM instance */
- }
+ if (routeMapNode->transHandle == transHandle)
+ {
+ /* Match: break out of loop and delete the node */
+ break;
+ }
+ else if (routeMapNode->nextNode == NULL)
+ {
+ return (-1); /* TEMP ERROR: transhandle does not exist for RM instance */
+ }
- prevNode = routeMapNode;
- routeMapNode = routeMapNode->nextNode;
+ prevNode = routeMapNode;
+ routeMapNode = routeMapNode->nextNode;
}
/* Delete the routing map node */
@@ -365,7 +627,7 @@ Rm_Result Rm_unregisterTransport (Rm_Handle rmHandle, Rm_TransportHandle transHa
/* Remove specification in RM instance that it has been connected to an upper level agent
* if the node to be deleted has a remote instance type of Client Delegate or Server */
if ((routeMapNode->remoteInstType == Rm_instType_CLIENT_DELEGATE) ||
- (routeMapNode->remoteInstType == Rm_instType_SERVER))
+ (routeMapNode->remoteInstType == Rm_instType_SERVER))
{
rmInst->registeredWithDelegateOrServer = false;
}