]> Gitweb @ Texas Instruments - Open Source Git Repositories - git.TI.com/gitweb - keystone-rtos/rm-lld.git/blobdiff - src/rm.c
Checking in latest changes
[keystone-rtos/rm-lld.git] / src / rm.c
index a7137978888f48ca9ba98f8d79b82938557b6d3a..e546fc3f09be869737c996a1d0028a1394c1085e 100644 (file)
--- a/src/rm.c
+++ b/src/rm.c
 /* RM Types */\r
 #include <ti/drv/rm/rm_types.h>\r
 \r
-/* RM includes */\r
+/* RM external includes */\r
 #include <ti/drv/rm/rm.h>\r
-#include <ti/drv/rm/rm_services.h>\r
-#include <ti/drv/rm/rm_transport.h>\r
-#include <ti/drv/rm/rm_policy.h>\r
-#include <ti/drv/rm/include/rm_pvt.h>\r
+#include <ti/drv/rm/rmservices.h>\r
+#include <ti/drv/rm/rmtransport.h>\r
+#include <ti/drv/rm/rmpolicy.h>\r
+\r
+/* RM internal includes */\r
+#include <ti/drv/rm/include/rmloc.h>\r
 \r
 /* RM OSAL layer */\r
 #include <rm_osal.h>\r
@@ -69,378 +71,326 @@ const char   rmVersionStr[] = RM_VERSION_STR ":" __DATE__  ":" __TIME__;
  ********************** Internal Functions ****************************\r
  **********************************************************************/\r
 \r
-void Rm_transactionQueueAdd(Rm_Inst *rmInst, uint32_t transactionId, \r
-                            Rm_TransportHandle transportHandle, void *callbackFunc)\r
+/* At the very least the transaction ID needs to be provided to create a transaction */\r
+Rm_Transaction *Rm_transactionQueueAdd(Rm_Inst *rmInst, uint32_t transactionId)\r
 {\r
-    Rm_TransactionQueueEntry *transactionQueue = (Rm_TransactionQueueEntry *) rmInst->transactionQueue;\r
-    Rm_TransactionQueueEntry *newEntry;\r
+    Rm_Transaction *transactionQueue = (Rm_Transaction *)rmInst->transactionQueue;\r
+    Rm_Transaction *newTransaction = NULL;\r
     void *key;\r
 \r
     /* Lock access to the RM instance's transaction queue */\r
     key = Rm_osalLocalCsEnter();\r
 \r
-    /* Get memory for a new transaction queue entry from local memory */\r
-    newEntry = Rm_osalMalloc (sizeof(Rm_TransactionQueueNode), false);\r
+    /* Get memory for a new transaction from local memory */\r
+    newTransaction = Rm_osalMalloc(sizeof(Rm_Transaction), false);\r
+\r
+    /* Return if the memory allocated for the transaction entry is NULL */\r
+    if (newTransaction == NULL)\r
+    {\r
+        Rm_osalLocalCsExit(key);\r
+        return(newTransaction);\r
+    }\r
+\r
+    /* Clear the transaction */\r
+    memset((void *)newTransaction, 0, sizeof(Rm_Transaction));\r
 \r
-    /* Populate the new entry. */\r
-    newEntry->transactionId = transactionId;\r
-    newEntry->transportHandle = transportHandle;\r
-    newEntry->transactionCallback = callbackFunc;\r
-    newEntry->nextEntry = NULL;  /* New entry's nextEntry pointer will always be NULL */\r
+    /* Populate transaction with the provided ID */\r
+    newTransaction->id = transactionId;\r
+    /* New transaction's nextTransaction pointer will always be NULL */\r
+    newTransaction->nextTransaction = NULL;  \r
 \r
-    /* Check if there are any entries in the transaction queue */\r
+    /* Check if there are any transactions in the transaction queue */\r
     if (transactionQueue)\r
     {\r
-        /* At least one entry in the transaction queue.  Add the new entry to the end of the\r
-         * transaction queue */\r
-        while (transactionQueue->nextEntry != NULL)\r
+        /* At least one transaction in the transaction queue.  Add the new entry to the \r
+         * end of the transaction queue */\r
+        while (transactionQueue->nextTransaction != NULL)\r
         {\r
-            /* Traverse the list until arriving at the last entry */\r
-            transactionQueue = transactionQueue->nextEntry;\r
+            /* Traverse the list until arriving at the last transaction */\r
+            transactionQueue = transactionQueue->nextTransaction;\r
         }\r
 \r
-        /* Add the new entry to the end of the queue */\r
-        transactionQueue->nextEntry = newEntry;\r
+        /* Add the new transaction to the end of the queue */\r
+        transactionQueue->nextTransaction = newTransaction;\r
     }\r
     else\r
     {\r
-        /* The transaction queue does not currently exist.  The new entry is the first entry */\r
-        rmInst->routeMap = newEntry;\r
+        /* The transaction queue does not currently exist.  The new transaction is the \r
+         * first transaction */\r
+        rmInst->transactionQueue = newTransaction;\r
     }\r
 \r
     Rm_osalLocalCsExit(key);\r
+    return (newTransaction);\r
 }\r
 \r
-Rm_TransactionQueueEntry *Rm_transactionQueueFind(Rm_Inst *rmInst, uint32_t transactionId)\r
+Rm_Transaction *Rm_transactionQueueFind(Rm_Inst *rmInst, uint32_t transactionId)\r
 {\r
-    Rm_TransactionQueueEntry *entry = (Rm_TransactionQueueEntry *) rmInst->transactionQueue;\r
+    Rm_Transaction *transaction = (Rm_Transaction *)rmInst->transactionQueue;\r
     void *key;\r
 \r
-    /* Lock access to the RM instance's transaction queue */\r
-    key = Rm_osalLocalCsEnter();\r
-\r
-    /* Make sure there is at least one entry in the transaction queue */\r
-    if (entry != NULL)\r
+    /* Make sure there is at least one transaction in the transaction queue */\r
+    if (transaction != NULL)\r
     {\r
         /* Find the transaction ID within the specified RM instance's transaction queue.\r
-         * If the end of the transaction queue is reached without finding the entry the \r
-         * entry pointer will be NULL */\r
-        while (entry != NULL)\r
+         * If the end of the transaction queue is reached without finding the transaction the \r
+         * transaction pointer will be NULL */\r
+        while (transaction != NULL)\r
         {\r
-            if (entry->transactionId == transactionId)\r
+            if (transaction->transactionId == transactionId)\r
             {\r
-                /* Match: break out of loop and return the entry */\r
+                /* Match: break out of loop and return the transaction */\r
                 break;             \r
             }\r
-            entry = entry->nextEntry;\r
+            transaction = transaction->nextTransaction;\r
         }\r
     }\r
-    \r
-    Rm_osalLocalCsExit(key);\r
-    return (entry);\r
+\r
+    return (transaction);\r
 }\r
 \r
-uint32_t Rm_transactionQueueDelete(Rm_Inst *rmInst, uint32_t transactionId)\r
+int32_t Rm_transactionQueueDelete(Rm_Inst *rmInst, uint32_t transactionId)\r
 {\r
-    Rm_TransactionQueueEntry *currentEntry = (Rm_TransactionQueueEntry *) rmInst->transactionQueue;\r
-    Rm_TransactionQueueEntry *prevEntry = NULL;\r
+    Rm_Transaction *transaction = (Rm_Transaction *) rmInst->transactionQueue;\r
+    Rm_Transaction *prevTransaction = NULL;\r
     void *key;\r
 \r
     /* Lock access to the RM instance's transaction queue */\r
     key = Rm_osalLocalCsEnter();\r
 \r
     /* Make sure there is at least one entry in the transaction queue */\r
-    if (currentEntry == NULL)\r
+    if (transaction == NULL)\r
     {\r
         Rm_osalLocalCsExit(key);\r
-        return (-1); /* TEMP ERROR RETURN */\r
+        return (RM_SERVICE_ERROR_NO_TRANSACTIONS_IN_QUEUE);\r
     }\r
 \r
     /* Find the transaction ID within the specified RM instance's transaction queue. */\r
-    while (currentEntry != NULL)\r
+    while (transaction != NULL)\r
     {\r
-        if (currentEntry->transactionId == transactionId)\r
+        if (transaction->transactionId == transactionId)\r
         {\r
-            /* Match: break out of loop and delete the entry */\r
+            /* Match: break out of loop and delete the transaction */\r
             break;             \r
         }\r
 \r
-        prevEntry = currentEntry;\r
-        currentEntry = currentEntry->nextEntry;\r
+        prevTransaction = transaction;\r
+        transaction = transaction->nextEntry;\r
     }\r
 \r
     /* Traversed entire queue but did not find transaction */\r
-    if (currentEntry == NULL)\r
+    if (transaction == NULL)\r
     {\r
         Rm_osalLocalCsExit(key);\r
-        return (-2); /* TEMP ERROR RETURN */\r
+        return (RM_SERVICE_ERROR_SERVICE_TRANSACTION_DOES_NOT_EXIST);\r
     }\r
     else\r
     {\r
-        /* Delete the transaction queue entry */\r
-        if ((prevEntry == NULL) && currentEntry->nextEntry)\r
+        /* Delete the transaction */\r
+        if ((prevTransaction == NULL) && transaction->nextTransaction)\r
         {\r
-            /* Entry to be deleted exists at start of transaction queue.  Map second\r
-             * entry to be start of transaction queue as long as there are more than\r
-             * one entries */\r
-            rmInst->transactionQueue = currentEntry->nextNode;\r
+            /* Transaction to be deleted exists at start of transaction queue.  Map second\r
+             * transaction to be start of transaction queue as long as there are more than\r
+             * one transactions */\r
+            rmInst->transactionQueue = transaction->nextTransaction;\r
         }\r
         else\r
         {\r
-            /* Entry to be deleted is in the middle or at end of the queue.  Adjust adjacent\r
-             * entry pointers.  This covers the case where the entry to be removed is at the\r
-             * end of the queue. */\r
-            prevEntry->nextNode = currentEntry->nextNode;\r
+            /* Transaction to be deleted is in the middle or at end of the queue.  Adjust \r
+             * adjacent transaction pointers.  This covers the case where the transaction to be \r
+             * removed is at the end of the queue. */\r
+            prevTransaction->nextTransaction = transaction->nextTransaction;\r
         }\r
 \r
-        /* Delete the node, free the memory associated with the node. */\r
-        Rm_osalFree((void *) currentEntry, sizeof(Rm_TransactionQueueEntry), false);\r
+        /* Free the memory associated with the transaction. */\r
+        Rm_osalFree((void *)transaction, sizeof(Rm_Transaction), false);\r
     }\r
 \r
     Rm_osalLocalCsExit(key);\r
-    return (0); /* RETURN OKAY - FIX MAGIC NUMBER */\r
-}\r
-\r
-/* Used in Client Delegate case where it forwarded requests from Client to Server\r
- * callback will direct to internal function that forwards response from server back\r
- * to client */\r
-void Rm_internalCallback (Rm_ServiceRespInfo *responseInfo)\r
-{\r
-\r
+    return (RM_SERVICE_ACTION_OKAY);\r
 }\r
 \r
 /* Function used to send RM response transactions to lower level agents */\r
 void Rm_transactionResponder (Rm_Inst *rmInst, Rm_Transaction *transaction,\r
                               Rm_TransactionReceipt *receipt)\r
 {\r
-    Rm_TransactionQueueEntry *transactionEntry;\r
+    Rm_TransportNode *dstTransportNode = NULL;\r
     Rm_Packet *rmPkt = NULL;\r
-    Rm_ProtocolPkt *rmProtPkt = NULL;\r
 \r
-    /* Find the transaction request that matches the received response */\r
-    transactionEntry = Rm_transactionQueueFind(rmInst,transaction->pktId);\r
-\r
-    if (transactionEntry == NULL)\r
-    {\r
-        /* No transaction request matching the transaction ID was forwarded from\r
-         * this RM instace */\r
-        receipt->transactionResult = RM_SERVICE_ERROR_TRANSACTION_DOES_NOT_EXST_FOR_THIS_RM_INSTANCE;\r
-        return;\r
-    }\r
+    /* Find the transport for the RM instance that sent the request. */\r
+    dstTransportNode = Rm_transportNodeFindRemoteName(rmInst, transaction->sourceInstName);\r
 \r
-    /* Create a RM packet using the transaction information */\r
-    if (rmInst->transport.rmAllocPkt)\r
-    {\r
-        rmPkt = rmInst->transport.rmAllocPkt(transactionEntry->transportHandle, sizeof(Rm_Packet));\r
-    }\r
-    else\r
-    {\r
-        /* The transport packet alloc API is not plugged */\r
-        receipt->transactionResult = RM_SERVICE_ERROR_TRANSPORT_PKT_ALLOC_API_NULL;\r
-        return;\r
+    /* Create a RM packet using the service information */\r
+    switch (transaction->type)\r
+    {\r
+        case Rm_service_RESOURCE_ALLOCATE:\r
+        case Rm_service_RESOURCE_BLOCK_ALLOCATE:\r
+        case Rm_service_RESOURCE_ALLOCATE_BY_NAME:\r
+        case Rm_service_RESOURCE_FREE:\r
+        case Rm_service_RESOURCE_BLOCK_FREE:\r
+        case Rm_service_RESOURCE_FREE_BY_NAME:\r
+            rmPkt = Rm_transportCreateResourceResponsePkt(rmInst, dstTransportNode, \r
+                                                          transaction, receipt);\r
+            break;\r
+        case Rm_service_RESOURCE_MAP_TO_NAME:\r
+        case Rm_service_RESOURCE_UNMAP_NAME:\r
+            rmPkt = Rm_transportCreateNsResponsePkt(rmInst, dstTransportNode,\r
+                                                    transaction, receipt);\r
+            break;\r
+        default:\r
+            /* Invalid service type.  Flag the error and return */\r
+            receipt->serviceResult = RM_SERVICE_ERROR_INVALID_SERVICE_TYPE;\r
+            break;\r
     }\r
 \r
-    /* Make sure a buffer for the packet was allocated  */\r
-    if (rmPkt == NULL)\r
+    if (receipt->serviceResult <= RM_SERVICE_ERROR_BASE)\r
     {\r
-        receipt->transactionResult = RM_SERVICE_ERROR_TRANSPORT_NULL_PKT_BUF;\r
+        /* Delete the transaction and return immediately because an error occurred \r
+         * allocating the packet */\r
+        Rm_transactionQueueDelete(rmInst, transaction->id);\r
         return;\r
     }\r
 \r
-    /* Make sure allocated buffer is large enough to fit the protocol packet plus the \r
-     * rmPktLen field */\r
-    if (rmPkt->rmPktLen < (sizeof(Rm_ProtocolPkt) + sizeof(uint32_t))\r
-    {   \r
-        receipt->transactionResult = RM_SERVICE_ERROR_TRANSPORT_PKT_BUF_TOO_SMALL;\r
-        return;\r
-    }\r
-\r
-\r
-    /* Initialize the rmPkt.  Do not assume the transport code will do it */                            \r
-    memset((void *)rmPkt, 0, sizeof(Rm_Packet));\r
-\r
-    /* Assign the rmData field to be the rmProtPkt */\r
-    rmProtPkt = &(rmPkt->rmData[0]);\r
-\r
-    /* Populate the response packet with the transaction response details for\r
-     * the lower leverl RM instance */\r
-    rmProtPkt->rmPktId = transactionEntry->transactionId;\r
-    strcpy((void *)rmProtPkt->rmInstName,(void *)rmInst->name);\r
-    rmProtPkt->rmCmd = (uint32_t) transaction->command;\r
-    rmProtPkt->rmDetails = transaction->details;\r
-    if (transaction->command == Rm_command_POLICY_RESPONSE)\r
-    {\r
-        /* Copy the policy data if the transaction is policy based */\r
-        memcpy ((void *)rmProtPkt->u.rmPolicyData, (void *)transaction->u.policyData,\r
-                RM_MAX_POLICY_SIZE_BYTES);\r
-    }\r
-    else\r
-    {\r
-        /* Otherwise copy the resource data */\r
-        memcpy ((void *)&(rmProtPkt->u.resInfo), (void *) &(transaction->u.resourceInfo),\r
-                sizeof(Rm_ResourceInfo));\r
-    }\r
-\r
     /* Send the RM packet to the application transport */\r
-    if (rmInst->transport.rmSend)\r
+    if (rmInst->transport.rmSend((Rm_TransportHandle) dstTransportNode, rmPkt))\r
     {\r
-        if (!(rmInst->transport.rmSend(transactionEntry->transportHandle, rmPkt))\r
+        /* Non-NULL value returned by transport send.  An error occurred\r
+         * in the transport while attempting to send the packet.*/\r
+        receipt->serviceResult = RM_SERVICE_ERROR_TRANPSPORT_SEND_ERROR;\r
+        /* Clean up the packet */\r
+        if (rmInst->transport.rmFreePkt((Rm_TransportHandle) dstTransportNode, rmPkt))\r
         {\r
-            /* Transport returned an error */\r
-\r
-            /* SHOULD TRANSPORT ERROR SOMEHOW BE OR'D WITH THE SERVICE ERROR ??? */\r
-            receipt->transactionResult = RM_SERVICE_ERROR_TRANPSPORT_SEND_ERROR;\r
-            return;\r
+            /* Non-NULL value returned by transport packet free. Flag the\r
+             * error */\r
+             receipt->serviceResult = RM_SERVICE_ERROR_TRANSPORT_FREE_PKT_ERROR;\r
         }\r
-    }\r
-    else\r
-    {\r
-        /* The transport packet send API is not plugged */\r
-        receipt->transactionResult = RM_SERVICE_ERROR_TRANSPORT_PKT_SEND_API_NULL;\r
         return;\r
-    }    \r
-    \r
-    receipt->transactionResult = RM_RESPONSE_PACKET_SENT;\r
-\r
-    /* Delete the transaction entry from the transaction queue */\r
-    Rm_transactionQueueDelete(rmInst,transaction->pktId);\r
+    }\r
 \r
-    return;\r
+    /* Fill out the receipt information and delete the transaction */\r
+    receipt->serviceResult = transaction->details;\r
+    Rm_transactionQueueDelete(rmInst, transaction->id);\r
 }\r
 \r
 /* Function used to forward RM transactions to higher level agents */\r
 void Rm_transactionForwarder (Rm_Inst *rmInst, Rm_Transaction *transaction,\r
                               Rm_TransactionReceipt *receipt)\r
 {\r
-    Rm_TransRouteMapNode *routeMap = (Rm_TransRouteMapNode *) rmInst->routeMap;\r
-    uint32_t transactionId;\r
+    Rm_TransportNode *dstTransportNode = NULL;\r
     Rm_Packet *rmPkt = NULL;\r
-    Rm_ProtocolPkt *rmProtPkt = NULL;\r
 \r
-    /* Make sure at least one transport has been registered */\r
-    if (routeMap == NULL)\r
-    {\r
-        receipt->transactionResult = RM_SERVICE_ERROR_NO_TRANSPORT_REGISTERED;\r
-        return;\r
-    }\r
-    \r
     /* Make sure the RM instance has a transport registered with a higher level agent */\r
-    if (!rmInst->registeredWithDelegateOrServer)\r
+    if (rmInst->registeredWithDelegateOrServer == false)\r
     {\r
-        receipt->transactionResult = RM_SERVICE_ERROR_NOT_REGISTERED_WITH_DEL_OR_SERVER;\r
+        receipt->serviceResult = RM_SERVICE_ERROR_NOT_REGISTERED_WITH_DEL_OR_SERVER;\r
         return;\r
     }\r
 \r
-    /* Parse the RM instance's routing map to find the higher level agent for forwarding */\r
-    while ((routeMap->remoteInstType != Rm_instType_CLIENT_DELEGATE) || \r
-           (routeMap->remoteInstType != Rm_instType_SERVER))\r
+    /* Find the transport for the higher level agent.  Check for a remote Client Delegate first.\r
+     * If a connection does not exist check for a connection to a Server */\r
+    dstTransportNode = Rm_transportNodeFindRemoteInstType(rmInst, Rm_instType_CLIENT_DELEGATE);\r
+    if (dstTransportNode == NULL)\r
     {\r
-        /* Traverse the list until arriving at the upper level agent node */\r
-        routeMap = routeMap->nextNode;\r
+        dstTransportNode = Rm_transportNodeFindRemoteInstType(rmInst, Rm_instType_SERVER);\r
     }\r
 \r
     /* Create a RM packet using the service information */\r
-    if (rmInst->transport.rmAllocPkt)\r
-    {\r
-        rmPkt = rmInst->transport.rmAllocPkt(routeMap->transHandle, sizeof(Rm_Packet));\r
-    }\r
-    else\r
-    {\r
-        /* The transport packet alloc API is not plugged */\r
-        receipt->transactionResult = RM_SERVICE_ERROR_TRANSPORT_PKT_ALLOC_API_NULL;\r
-        return;\r
+    switch (transaction->type)\r
+    {\r
+        case Rm_service_RESOURCE_ALLOCATE:\r
+        case Rm_service_RESOURCE_BLOCK_ALLOCATE:\r
+        case Rm_service_RESOURCE_ALLOCATE_BY_NAME:\r
+        case Rm_service_RESOURCE_FREE:\r
+        case Rm_service_RESOURCE_BLOCK_FREE:\r
+        case Rm_service_RESOURCE_FREE_BY_NAME:\r
+            rmPkt = Rm_transportCreateResourceReqPkt(rmInst, dstTransportNode, \r
+                                                     transaction, receipt);\r
+            break;\r
+        case Rm_service_RESOURCE_MAP_TO_NAME:\r
+        case Rm_service_RESOURCE_UNMAP_NAME:\r
+            rmPkt = Rm_transportCreateNsRequestPkt(rmInst, dstTransportNode,\r
+                                                   transaction, receipt);\r
+            break;\r
+        default:\r
+            /* Invalid service type.  Flag the error and return */\r
+            receipt->serviceResult = RM_SERVICE_ERROR_INVALID_SERVICE_TYPE;\r
+            break;\r
     }\r
 \r
-    /* Make sure a buffer for the packet was allocated  */\r
-    if (rmPkt == NULL)\r
+    if (receipt->serviceResult <= RM_SERVICE_ERROR_BASE)\r
     {\r
-        receipt->transactionResult = RM_SERVICE_ERROR_TRANSPORT_NULL_PKT_BUF;\r
+        /* Return immediately because an error occurred allocating the packet */\r
         return;\r
     }\r
 \r
-    /* Make sure allocated buffer is large enough to fit the protocol packet plus the \r
-     * rmPktLen field */\r
-    if (rmPkt->rmPktLen < (sizeof(Rm_ProtocolPkt) + sizeof(uint32_t))\r
-    {   \r
-        receipt->transactionResult = RM_SERVICE_ERROR_TRANSPORT_PKT_BUF_TOO_SMALL;\r
-        return;\r
-    }\r
-\r
-    /* Create an ID for this transaction.  The ID will be used for two purposes:\r
-     * 1) Matching the response from the higher level RM agent to the request\r
-     * 2) Provided to the service requesting component so that it can match the\r
-     *    service request with the response it receives via its callback function */\r
-    transactionId = ...; /* NEED SCHEME FOR CREATING A MUTUALLY EXCLUSIVE PKT ID.  CAN'T\r
-                          * CONFLICT WITH PCKT IDS CREATED ON OTHER RM INSTANCES */\r
-    /* Initialize the rmPkt.  Do not assume the transport code will do it */                            \r
-    memset((void *)rmPkt, 0, sizeof(Rm_Packet));\r
-                          \r
-    /* Assign the rmData field to be the rmProtPkt */\r
-    rmProtPkt = &(rmPkt->rmData[0]);\r
-    /* Populate the RM packet using the service information */\r
-    rmProtPkt->rmPktId = transactionId;\r
-    strcpy((void *)rmProtPkt->rmInstName,(void *)rmInst->name);\r
-    rmProtPkt->rmCmd = (uint32_t) transaction->command;\r
-    if ((transaction->command == Rm_command_POLICY_REQUEST) ||\r
-        (transaction->command == Rm_command_POLICY_RESPONSE)\r
-    {\r
-        /* Copy the policy data if the transaction is policy based */\r
-        memcpy ((void *)rmProtPkt->u.rmPolicyData, (void *)transaction->u.policyData,\r
-                RM_MAX_POLICY_SIZE_BYTES);\r
-    }\r
-    else\r
-    {\r
-        /* Otherwise copy the resource data */\r
-        memcpy ((void *)&(rmProtPkt->u.resInfo), (void *) &(transaction->u.resourceInfo),\r
-                sizeof(Rm_ResourceInfo));\r
-    }\r
-\r
-    /* Create an entry in the transaction queue */\r
-    Rm_transactionQueueAdd(rmInst, transactionId, transaction->callback);\r
+    /* Switch the queued transaction to the awaiting response state */\r
+    transaction->state = Rm_transactionState_AWAITING_RESPONSE;\r
 \r
     /* Send the RM packet to the application transport */\r
-    if (rmInst->transport.rmSend)\r
+    if (rmInst->transport.rmSend((Rm_TransportHandle) dstTransportNode, rmPkt))\r
     {\r
-        if (!(rmInst->transport.rmSend(routeMap->transHandle, rmPkt))\r
+        /* Non-NULL value returned by transport send.  An error occurred\r
+         * in the transport while attempting to send the packet.*/\r
+        receipt->serviceResult = RM_SERVICE_ERROR_TRANPSPORT_SEND_ERROR;\r
+        /* Clean up the packet */\r
+        if (rmInst->transport.rmFreePkt((Rm_TransportHandle) dstTransportNode, rmPkt))\r
         {\r
-            /* Transport returned an error */\r
-\r
-            /* SHOULD TRANSPORT ERROR SOMEHOW BE OR'D WITH THE SERVICE ERROR ??? */\r
-            receipt->transactionResult = RM_SERVICE_ERROR_TRANPSPORT_SEND_ERROR;\r
-            return;\r
+            /* Non-NULL value returned by transport packet free. Flag the\r
+             * error */\r
+             receipt->serviceResult = RM_SERVICE_ERROR_TRANSPORT_FREE_PKT_ERROR;\r
         }\r
-    }\r
-    else\r
-    {\r
-        /* The transport packet send API is not plugged */\r
-        receipt->transactionResult = RM_SERVICE_ERROR_TRANSPORT_PKT_SEND_API_NULL;\r
         return;\r
-    }    \r
+    }\r
 \r
     /* Inform requesting component that the service is being forwarded to a higher lever\r
      * RM agent for processing.  The result of the service will be provided to the \r
      * component via the specified callback function */\r
-    receipt->transactionResult = RM_SERVICE_PROCESSING;\r
-    receipt->transactionId = transactionId;\r
-    return;\r
+    receipt->serviceResult = RM_SERVICE_PROCESSING;\r
+    receipt->serviceId = transaction->id;\r
 }\r
 \r
 void Rm_transactionProcessor (Rm_Inst *rmInst, Rm_Transaction *transaction, \r
-                                 Rm_TransactionReceipt *receipt)\r
+                              Rm_TransactionReceipt *receipt)\r
 {\r
+    Rm_Transaction *queuedTransaction = NULL;\r
+    \r
     if (rmInst->instType == Rm_instType_CLIENT)\r
     {\r
-        if (transaction->command == Rm_command_RESOURCE_RESPONSE)\r
+        /* Check if the new transaction's ID matches any transactions waiting for\r
+         * responses.  A transaction received as a response will have an ID that \r
+         * matches the transaction that originated the request packet */\r
+        if (queuedTransaction = Rm_transactionQueueFind(rmInst, transaction->id))\r
         {\r
-            /* Responses received by the Client must be issued back to the requesting\r
-             * component */\r
-            Rm_serviceResponder (rmInst, transaction, receipt);\r
+            if (queuedTransaction->state == Rm_transactionState_AWAITING_RESPONSE)\r
+            {\r
+                /* Found a transaction awaiting a response.  Pass both transactions\r
+                 * to the service responder for response processing */\r
+                Rm_serviceResponder(rmInst, transaction, queuedTransaction, receipt);\r
+            }\r
+            else\r
+            {\r
+                /* Request transaction was not in the awaiting response state.  Flag the\r
+                 * error in the receipt and return */\r
+                receipt->serviceResult = RM_SERVICE_ERROR_INVALID_REQUEST_TRANSACTION_STATE_UPON_RESPONSE;\r
+            }\r
         }\r
         else\r
         {\r
-            /* All service requests on Clients are forwarded to the higher level RM agent\r
-             * either a Client Delegate or Server, based on the RM system architecture */\r
-            Rm_transactionForwarder(rmInst, transaction, receipt);\r
+            /* This is a new transaction.  Make sure the transaction is not a \r
+             * response transaction sent to the wrong RM instance */\r
+            if ((transaction->state == Rm_transactionState_RESOURCE_APPROVED) ||\r
+                (transaction->state == Rm_transactionState_RESOURCE_DENIED))\r
+            {\r
+                /* No matching request transaction.  This transaction result was sent to the\r
+                 * wrong RM instance.  Flag the error in the receipt and return */\r
+                receipt->serviceResult = RM_SERVICE_ERROR_INVALID_TRANSACTION_RECEIVED_ON_CLIENT;\r
+            }\r
+            else\r
+            {\r
+                /* All service requests on Clients are forwarded to the higher level RM agent\r
+                 * either a Client Delegate or Server, based on the RM system architecture */\r
+                Rm_transactionForwarder(rmInst, transaction, receipt);\r
+            }\r
         }\r
     }\r
     else\r
@@ -480,116 +430,8 @@ void Rm_transactionProcessor (Rm_Inst *rmInst, Rm_Transaction *transaction,
 \r
 }\r
 \r
-void Rm_serviceHandler (void *rmHandle, Rm_ServiceReqInfo *requestInfo,\r
-                        Rm_ServiceRespInfo *responseInfo)\r
-{\r
-    Rm_Inst *rmInst = (Rm_Inst *) rmHandle;\r
-    Rm_Transaction transaction;\r
-    Rm_TransactionReceipt receipt;\r
-    void *key;\r
-\r
-    /* Prevent another component using the same instance from wiping out the current\r
-     * service request */\r
-    key = Rm_osalLocalCsEnter();\r
-\r
-    /* Make sure serviceType is valid and that a callback function has been provided */\r
-    if ((requestInfo->serviceType < Rm_service_FIRST) || \r
-        (requestInfo->serviceType > Rm_service_LAST))\r
-    {\r
-        responseInfo->serviceResult = RM_SERVICE_ERROR_INVALID_SERVICE_TYPE;\r
-        Rm_osalLocalCsExit(key);\r
-        return;\r
-    }\r
-    else if (requestInfo->serviceCallback == NULL)\r
-    {\r
-        /* RM Client's and Client Delegate's use blocking transports to consult with a \r
-         * high-level RM agent prior to providing a response to the component.  It is \r
-         * assumed the component's cannot block.  Therefore, all responses must go\r
-         * through the callback function provided by the component.  Return an error \r
-         * if the component does not provide a callback function. */\r
-        responseInfo->serviceResult = RM_SERVICE_ERROR_CALLBACK_NOT_PROVIDED;\r
-        Rm_osalLocalCsExit(key);\r
-        return;\r
-    }\r
-\r
-    /* Clear the transaction and receipt prior to using them */\r
-    memset((void *) &transaction, 0, sizeof(Rm_Transaction));\r
-    memset((void *) &transactionReceipt, 0, sizeof(Rm_TransactionReceipt));\r
-\r
-    /* Transfer request information into the internal transaction format */\r
-    transaction.command = (Rm_Command) requestInfo->serviceType;\r
-    transaction.callback = requestInfo->serviceCallback;\r
-    /* Policy modifications will never originate from components */\r
-    strcpy ((void *) &(transaction.u.resourceInfo.resName)[0], (void *)requestInfo->resName);\r
-    transaction.u.resourceInfo.resBase = requestInfo->resourceBase;\r
-    transaction.u.resourceInfo.resNum = requestInfo->resourceNum;\r
-    transaction.u.resourceInfo.resAlign = requestInfo->resourceAlign;\r
-    strcpy ((void *) &(transaction.u.resourceInfo.resNsName)[0], (void *)requestInfo->resNsName);\r
-\r
-    /* Pass the new transaction to the transaction processor */\r
-    Rm_transactionProcessor (rmInst, &transaction, &receipt);\r
-\r
-    /* Copy transaction receipt information into the response info fields for the \r
-     * component based on the result of the transaction.  Denied service requests\r
-     * will have only a valid serviceResult field */\r
-    responseInfo->serviceResult = receipt->transactionResult;\r
-    if (responseInfo->serviceResult == RM_SERVICE_APPROVED)\r
-    {\r
-        /* Service was approved.  The resource data should be passed back\r
-         * to the component */\r
-        responseInfo->resBase = receipt.resBase;\r
-        responseInfo->resNum = receipt.resNum;\r
-    }\r
-    else if (responseInfo->serviceResult == RM_SERVICE_PROCESSING)\r
-    {\r
-        /* The service is still being processed.  Provide the transaction ID\r
-         * back to the component so that it can sort service responses received\r
-         * via the provided callback function */\r
-        responseInfo->requestId = receipt.transactionId;\r
-    }\r
-\r
-    Rm_osalLocalCsExit(key);\r
-    \r
-    return;\r
-}\r
-\r
-/* This function is executed when a RM instance receives a response to one of it's requests\r
- * and the information in the request must be provided to the original requesting component */\r
-void Rm_serviceResponder (Rm_Inst *rmInst, Rm_Transaction *transaction, \r
-                          Rm_TransactionReceipt *receipt)\r
-{\r
-    Rm_TransactionQueueEntry *transactionEntry;\r
-    Rm_ServiceRespInfo responseInfo;\r
-\r
-    /* Find the transaction request that matches the received response */\r
-    transactionEntry = Rm_transactionQueueFind(rmInst,transaction->pktId);\r
-\r
-    if (transactionEntry == NULL)\r
-    {\r
-        /* No transaction request matching the transaction ID was forwarded from\r
-         * this RM instace */\r
-        receipt->transactionResult = RM_SERVICE_ERROR_TRANSACTION_DOES_NOT_EXST_FOR_THIS_RM_INSTANCE;\r
-        return;\r
-    }\r
-\r
-    /* Populate the service response with the transaction response details for\r
-     * the component */\r
-    responseInfo.requestId = transaction->pktId;\r
-    responseInfo.serviceResult = transaction->details;\r
-    responseInfo.resBase = transaction->u.resourceInfo.resBase;\r
-    responseInfo.resNum = transaction->u.resourceInfo.resNum;\r
-\r
-    /* Issue the callback to the requesting component with the response information */\r
-    transactionEntry->transactionCallback(&responseInfo);\r
-\r
-    /* Delete the transaction entry from the transaction queue */\r
-    Rm_transactionQueueDelete(rmInst,transaction->pktId);\r
-\r
-    return;\r
-}\r
-\r
 /**********************************************************************\r
- *********************** Application visible APIs ***************************\r
+ ********************** Application visible APIs **********************\r
  **********************************************************************/\r
 \r
 Rm_Handle Rm_init(Rm_InitCfg *initCfg)\r
@@ -612,6 +454,16 @@ Rm_Handle Rm_init(Rm_InitCfg *initCfg)
     rmInst->registeredWithDelegateOrServer = false;\r
     rmInst->serviceCallback = NULL;\r
 \r
+    /* The transport APIs must be provided */\r
+    if ((initCfg->rmAllocPktFuncPtr == NULL) ||\r
+        (initCfg->rmFreePktFuncPtr == NULL) ||\r
+        (initCfg->rmSendFuncPtr == NULL) ||\r
+        (initCfg->rmReceiveFuncPtr == NULL) ||\r
+        (initCfg->rmNumPktsReceivedFuncPtr == NULL))\r
+    {\r
+        return (NULL);\r
+    }\r
+        \r
     /* Populate the instance transport callouts */\r
     rmInst->transport.rmAllocPkt = initCfg->rmAllocPktFuncPtr;\r
     rmInst->transport.rmFreePkt = initCfg->rmFreePktFuncPtr;\r
@@ -646,267 +498,6 @@ Rm_Handle Rm_init(Rm_InitCfg *initCfg)
     return ((Rm_Handle) rmInst);\r
 }\r
 \r
-Rm_Result Rm_preMainAllocResource(Rm_PreMainAllocInfo *preMainAllocInfo)\r
-{\r
-\r
-}\r
-\r
-Rm_ServiceHandle Rm_getServiceHandle(Rm_Handle rmHandle)\r
-{\r
-    Rm_Inst *rmInst = (Rm_Inst *) rmHandle;\r
-    Rm_ServicesPort *newServicePort;\r
-    \r
-    /* Create a new service handle for the specified RM instance */\r
-    \r
-    /* Get memory for a new service port from local memory */\r
-    newServicePort = Rm_osalMalloc (sizeof(Rm_ServicesPort), false);\r
-\r
-    newServicePort->rmHandle = rmHandle;\r
-    newServicePort->rmService = rmServiceHandler;\r
-\r
-    return ((Rm_ServiceHandle) newServicePort);\r
-}\r
-\r
-Rm_TransportHandle Rm_registerTransport (Rm_Handle rmHandle, Rm_TransCfg *transCfg)\r
-{\r
-    Rm_Inst *rmInst = (Rm_Inst *) rmHandle;\r
-    Rm_TransRouteMapNode *existingRouteMap = (Rm_TransRouteMapNode *) rmInst->routeMap;\r
-    Rm_TransRouteMapNode *newRouteMapNode;\r
-\r
-    /* RM Servers cannot connect to other Servers */\r
-    if ((rmInst->instType == Rm_instType_SERVER) &&\r
-         (transCfg->rmRemoteInstType == Rm_instType_SERVER))\r
-    {\r
-        return (NULL); /* Error -return null */\r
-    }\r
-\r
-    /* Verify Clients and Client Delegates are not registering with more than one \r
-     * Client Delegate or Server. Assuming a Client Delegate can register with another \r
-     * Client Delegate that can "act" as a server */\r
-    if (((rmInst->instType == Rm_instType_CLIENT) || \r
-         (rmInst->instType == Rm_instType_CLIENT_DELEGATE)) &&\r
-        ((transCfg->rmRemoteInstType == Rm_instType_CLIENT_DELEGATE) ||\r
-         (transCfg->rmRemoteInstType == Rm_instType_SERVER)) &&\r
-        rmInst->registeredWithDelegateOrServer)\r
-    {\r
-        return (NULL); /* Error -return null */\r
-    }         \r
-\r
-    /* Error checks passed - Create a new transport handle for the specified RM instance */\r
-    \r
-    /* Get memory for a new routing map node from local memory */\r
-    newRouteMapNode = Rm_osalMalloc (sizeof(Rm_TransRouteMapNode), false);\r
-\r
-    /* Populate the new node.  The address of the node itself is stored since this address is returned\r
-     *  to the application as the Rm_TransportHandle */\r
-    newRouteMapNode->transHandle = newRouteMapNode;\r
-    newRouteMapNode->remoteInstType = transCfg->rmRemoteInstType;\r
-    newRouteMapNode->nextNode = NULL;  /* New node will always be NULL */\r
-\r
-    /* Check if there are any entries in the routing map */\r
-    if (existingRouteMap)\r
-    {\r
-        /* At least one entry in the routing map.  Add the new routing map node to the end of the\r
-         * routing map node list */\r
-        while (existingRouteMap->nextNode != NULL)\r
-        {\r
-            /* Traverse the list until arriving at the last node */\r
-            existingRouteMap = existingRouteMap->nextNode;\r
-        }\r
-\r
-        /* Add the new node to the end of the list */\r
-        existingRouteMap->nextNode = newRouteMapNode;\r
-    }\r
-    else\r
-    {\r
-        /* A routing map does not currently exist.  The new node is the first entry */\r
-        rmInst->routeMap = newRouteMapNode;\r
-    }\r
-\r
-    /* Specify RM instance has registered with a higher level agent */\r
-    if ((newRouteMapNode->remoteInstType == Rm_instType_CLIENT_DELEGATE) ||\r
-        (newRouteMapNode->remoteInstType == Rm_instType_SERVER))\r
-    {\r
-        rmInst->registeredWithDelegateOrServer = true;\r
-    }\r
-\r
-    return ((Rm_TransportHandle) newRouteMapNode);\r
-}\r
-\r
-Rm_Result Rm_unregisterTransport (Rm_Handle rmHandle, Rm_TransportHandle transHandle)\r
-{\r
-    Rm_Inst *rmInst = (Rm_Inst *) rmHandle;\r
-    Rm_TransRouteMapNode *routeMapNode = (Rm_TransRouteMapNode *) rmInst->routeMap;\r
-    Rm_TransRouteMapNode *prevNode = NULL;\r
-\r
-    /* Make sure a routing map exists for the RM instance */\r
-    if (routeMapNode == NULL)\r
-    {\r
-        return (-1); /* TEMP ERROR RETURN */\r
-    }\r
-\r
-    /* Find the transport handle within the specified RM instance's routing map. */\r
-    while (1)\r
-    {\r
-        if (routeMapNode->transHandle == transHandle)\r
-        {\r
-            /* Match: break out of loop and delete the node */\r
-            break;             \r
-        }\r
-        else if (routeMapNode->nextNode == NULL)\r
-        {\r
-            return (-1); /* TEMP ERROR: transhandle does not exist for RM instance */\r
-        }\r
-\r
-        prevNode = routeMapNode;\r
-        routeMapNode = routeMapNode->nextNode;\r
-    }\r
-    \r
-    /* Delete the routing map node */\r
-    if ((prevNode == NULL) && routeMapNode->nextNode)\r
-    {\r
-        /* Node to be deleted exists at start of route map.  Map second node to be start of\r
-         * node list as long as there are more than one routing map nodes */\r
-        rmInst->routeMap = routeMapNode->nextNode;\r
-    }\r
-    else\r
-    {\r
-        /* Node to be deleted is in the middle or at end of the list.  Adjust adjacent\r
-         * nodes pointers.  This covers the case where the node to be removed is at the\r
-         * end of the list. */\r
-        prevNode->nextNode = routeMapNode->nextNode;\r
-    }\r
-\r
-    /* Remove specification in RM instance that it has been connected to an upper level agent\r
-     * if the node to be deleted has a remote instance type of Client Delegate or Server */\r
-    if ((routeMapNode->remoteInstType == Rm_instType_CLIENT_DELEGATE) ||\r
-        (routeMapNode->remoteInstType == Rm_instType_SERVER))\r
-    {\r
-        rmInst->registeredWithDelegateOrServer = false;\r
-    }\r
-\r
-    /* Delete the node, free the memory associated with the node. */\r
-    Rm_osalFree((void *) routeMapNode, sizeof(Rm_TransRouteMapNode), false);\r
-\r
-    return (RM_OK);\r
-}\r
-\r
-\r
-Rm_TransVerifyResult Rm_verifyTransport (Rm_Handle rmHandle, uint32_t timeout, \r
-                                         Rm_TransFailData *failData)\r
-{\r
-\r
-}\r
-\r
-/* Resource requests that come directly from application go through this API */\r
-void Rm_requestService (void *rmHandle, Rm_ServiceReqInfo *requestInfo,\r
-                        Rm_ServiceRespInfo *responseInfo)\r
-{\r
-    Rm_serviceHandler(rmHandle, requestInfo, responseInfo);\r
-}\r
-\r
-/* Used by the application to pass RM packets received from a transport to RM.\r
- * CODE THE FUNCTION SUCH THAT IT CAN BE CALLED DIRECTLY BY APP OR BE PLUGGED\r
- * AS PART OF AN ISR HANDLER FOR THE TRANSACTION RECEIVE */\r
-Rm_Result Rm_receiveRmPkt(Rm_Handle rmHandle, Rm_TransportHandle transHandle, Rm_Packet *pkt)\r
-{\r\r\r
-    Rm_Inst *rmInst = (Rm_Inst *)rmHandle;\r
-    Rm_ProtocolPkt rmProtPkt = &(pkt->rmData)[0];\r
-    Rm_Transaction transaction;\r
-    Rm_TransactionReceipt receipt;\r
-    void *key;\r
-\r
-    /* Lock access to the RM instance's transaction queue */\r
-    key = Rm_osalLocalCsEnter();    \r
-\r
-    /* Initialize the transaction and receipt */\r
-    memset((void *)&transaction, 0, sizeof(Rm_Transaction));\r
-    memset((void *)&receipt, 0, sizeof(Rm_TransactionReceipt));\r
-\r
-    /* Create a new transaction based on the packet details */\r
-    transaction.pktId = rmProtPkt->rmPktId;\r
-    transaction.command = (Rm_Command) rmProtPkt->rmCmd;\r
-    transaction.details = rmProtPkt->rmDetails;\r
-    transaction.receivedTransport = transHandle;\r
-    if ((transaction->command == Rm_command_POLICY_REQUEST) ||\r
-        (transaction->command == Rm_command_POLICY_RESPONSE)\r
-    {\r
-        /* Copy the policy data if the transaction is policy based */\r
-        memcpy ((void *)transInfo->u.policyData, (void *)rmProtPkt->u.rmPolicyData,\r
-                RM_MAX_POLICY_SIZE_BYTES);\r
-    }\r
-    else\r
-    {\r
-        /* Otherwise copy the resource data */\r
-        memcpy((void *)transaction.u.resourceInfo,(void *)rmProtPkt->u.resInfo, \r
-               sizeof(Rm_ResourceInfo));\r
-    }\r
-\r
-    /* Process the transaction */\r
-    Rm_transactionProcessor(rmInst,&transaction,&receipt)\r
-\r
-    /* IS RECEIPT DATA NEEDED FOR ANYTHING HERE??*/\r
-\r
-    Rm_osalLocalCsExit(key);\r
-    return (0);    \r
-}\r
-\r
-/* Application can call this API so that RM handles reception of packets based on\r
- * the RM handle and transport handle provided */\r
-Rm_Result Rm_getRmPkt(Rm_Handle rmHandle, Rm_TransportHandle transHandle)\r
-{\r
-    Rm_Inst *rmInst = (Rm_Inst *)rmHandle;\r
-    Rm_TransRouteMapNode *transNode = rmInst->routeMap;\r
-    Rm_Packet *rmPkt = NULL;\r
-    Rm_Result retVal = 0;\r
-    void *key;\r
-\r
-    /* Lock access to the RM instance's transaction queue */\r
-    key = Rm_osalLocalCsEnter();    \r
-\r
-    /* Verify the transport handle is registered with the RM handle */\r
-    while (transNode != NULL)\r
-    {\r
-        if (transNode->transHandle == transHandle)\r
-        {\r
-           /* Break out of loop if an entry in the route map has been found */\r
-           break;\r
-        }\r
-        transNode = transNode->nextNode;\r
-    }\r
-\r
-    if (transNode == NULL)\r
-    {\r
-        Rm_osalLocalCsExit(key);\r
-        return (-1) /* ERROR: THE TRANSPORT HANDLE IS NOT REGISTERED WITH THE RM HANDLE */\r
-    }\r
-\r
-    /* Check to see if any RM packets are available.  Process any available packets. */\r
-    while (rmInst->transport.rmNumPktsReceived(transHandle))\r
-    {\r
-        rmInst->transport.rmReceive(transHandle, rmPkt);\r
-\r
-        if (rmPkt == NULL)\r
-        {\r
-            retVal = -1;  /* ERROR - PACKET RECEIVED FROM TRANSPORT IS NULL */\r
-        }\r
-\r
-        /* Pass the packet to RM */\r
-        retVal = Rm_receiveRmPkt(rmHandle, transHandle, rmPkt);\r
-        /* Delete the packet */\r
-        rmInst->transport.rmFreePkt(transHandle, rmPkt);\r
-\r
-        if (retVal)\r
-        {\r
-            /* If retVal is not 0 (Okay) there was an error so break out of loop and return */\r
-            break;\r
-        }\r
-    }\r
-    \r
-    Rm_osalLocalCsExit(key);\r
-    return (retVal); \r
-}\r
-\r
 uint32_t Rm_getVersion (void)\r
 {\r
     return RM_VERSION_ID;\r