completed request/response infrastructure
authorJustin Sobota <jsobota@ti.com>
Mon, 12 Nov 2012 19:50:57 +0000 (14:50 -0500)
committerJustin Sobota <jsobota@ti.com>
Mon, 12 Nov 2012 19:50:57 +0000 (14:50 -0500)
include/rmtransportloc.h
rmpolicy.h [moved from rm_policy.h with 100% similarity]
rmservices.h
rmtransport.h
src/rm.c
src/rmnameserver.c [new file with mode: 0644]
src/rmpolicy.c [new file with mode: 0644]
src/rmservices.c
src/rmtransport.c

index f736f4a9a8d256a79eeb9c187c22e307b7d6b189..9550b543df53fe15e3e908e9b5763152dd401440 100644 (file)
@@ -194,6 +194,52 @@ typedef struct {
     char policyData[RM_MAX_POLICY_SIZE_BYTES];
 } Rm_PolicyChangePkt;
 
+/** 
+ * @brief Resource Pool Modification Request Packet Types
+ */
+typedef enum {
+    /** Resource pool allocation request */
+    Rm_resPoolModType_ALLOCATE = 0,
+    /** Resource pool free request */
+    Rm_resPoolModType_FREE = 1
+} Rm_ResourcePoolModReqType;
+
+/** 
+ * @brief Resource Pool Modification Request Packet - Packet sent to RM Server from
+ *        RM Client Delegates in order to request resource pool modifications on
+ *        the Client Delegate.  The Client Delegate can request more resource's for
+ *        its local resource pool or it can free resources from its resource pool back
+ *        to the Server. */
+typedef struct {
+    /** The transaction ID associated with the request packet */
+    uint32_t requestId;  
+    /** The resource pool modification request type */
+    Rm_ResourcePoolModReqType resourcePoolModReqType;
+    /** Name of RM Client Delegate instance that is issuing the resource pool 
+     *  modification request. The instance name will be used to validate the 
+     *  request against the RM policy defined for the instance. */
+    char instName[RM_INST_NAME_MAX_CHARS];      
+    /** Resource pool resource request information */
+    Rm_ResourceInfo resourceInfo;
+} Rm_ResourcePoolModRequestPkt;
+
+/** 
+ * @brief Resource Pool Modification Response Packet - Packet sent to RM Client
+ *        Delegates from RM Servers in response to resource pool modification requests.
+ *        The packet will contain resource response information based on the request
+ */
+typedef struct {
+    /** responseID will equal the requestId received in the resource pool mod request
+     *  packet.  This ID should be associated with a transaction stored in 
+     *  the RM instance that sent the resource request packet */
+    uint32_t responseId;
+    /** Result of the resource pool mod request.  Resource request, denied, or error.  The
+     *  return values are externally visible so they're tracked in rmservice.h */
+    int32_t requestResult;
+    /* Resource pool resource response information */
+    Rm_ResourceInfo resourceInfo;
+} Rm_ResourcePoolModResponsePkt;
+
 #ifdef __cplusplus
 }
 #endif
similarity index 100%
rename from rm_policy.h
rename to rmpolicy.h
index 1f4facf4b3b92a9e008269be59c66b0d89daec38..f4f8227f7e891b1bc285a23b70635b542e15565a 100644 (file)
@@ -113,6 +113,10 @@ extern "C" {
 #define RM_SERVICE_ERROR_INVALID_TRANSACTION_RECEIVED_ON_CLIENT (RM_SERVICE_ERROR_BASE-13)
 /** A failure occurred within a registered transport's packet free API */
 #define RM_SERVICE_ERROR_TRANSPORT_FREE_PKT_ERROR (RM_SERVICE_ERROR_BASE-14)
+/** Invalid NameServer object create on non-Server instance */
+#define RM_SERVICE_ERROR_NAMESERVER_OBJECT_CREATE_ON_INVALID_INSTANCE (RM_SERVICE_ERROR_BASE-15)
+/** Invalid NameServer object delete on non-Server instance */
+#define RM_SERVICE_ERROR_NAMESERVER_OBJECT_DELETE_ON_INVALID_INSTANCE (RM_SERVICE_ERROR_BASE-16)
 
 /** RM Transport Error Code Base */
 #define RM_TRANSPORT_ERROR_BASE (-128)
index cb040089750d04b49f1540d4fb58472d74445123..8d12fa5d9648d537788caa481ee9bd050684d4da 100644 (file)
@@ -64,6 +64,8 @@ extern "C" {
 #define RM_TRANSPORT_ERROR_HANDLE_HAS_NOT_BEEN_REGISTERED (RM_TRANSPORT_ERROR_BASE-1)
 /** No transports have been registered with the RM instance */
 #define RM_TRANSPORT_ERROR_NO_TRANSPORTS_REGISTERED  (RM_TRANSPORT_ERROR_BASE-2)
+/** RM packets are available but an error was encountered during reception */
+#define RM_TRANSPORT_ERROR_PACKET_RECEPTION_ERROR (RM_TRANSPORT_ERROR_BASE-3)
 
 /** 
  * @brief Result of RM transport layer operations
@@ -106,7 +108,11 @@ typedef enum {
     /** Policy request packet */
     Rm_pktType_POLICY_REQUEST = 4,
     /** Policy response packet */
-    Rm_pktType_POLICY_CHANGE = 5
+    Rm_pktType_POLICY_CHANGE = 5,
+    /** Resource pool modification request */
+    Rm_pktType_RESOURCE_POOL_MODIFICATION_REQUEST = 6,
+    /** Resource pool modification response */
+    Rm_pktType_RESOURCE_POOL_MODIFICATION_RESPONSE = 7
 } Rm_pktType;
 
 /** 
@@ -202,15 +208,12 @@ typedef struct {
      *  @param[in]  transportHandle
      *      Which application transport to retrieve a packet from
      *
-     *  @param[in]  pkt
-     *      Pointer to received resource packet.
-     *
      *  @retval
-     *      0 - Packet reception okay.
+     *      Non-NULL - Pointer to received RM packet.
      *  @retval
-     *      Non-zero - Packet receive failed.
+     *      NULL - Packet receive failed.
      */
-    int32_t (*rmReceive)(Rm_TransportHandle transportHandle, Rm_Packet *pkt);
+    void * (*rmReceive)(Rm_TransportHandle transportHandle);
     
     /**
      *  @b Description
index e546fc3f09be869737c996a1d0028a1394c1085e..2e8c7904baf172bc55d66460b8ba41b26ba96f53 100644 (file)
--- a/src/rm.c
+++ b/src/rm.c
@@ -272,6 +272,19 @@ void Rm_transactionResponder (Rm_Inst *rmInst, Rm_Transaction *transaction,
     Rm_transactionQueueDelete(rmInst, transaction->id);\r
 }\r
 \r
+void Rm_allocationHandler (Rm_Inst *rmInst, Rm_Transaction *transaction,\r
+                           Rm_TransactionReceipt *receipt)\r
+{\r
+\r
+}\r
+\r
+void Rm_freeHandler (Rm_Inst *rmInst, Rm_Transaction *transaction,\r
+                     Rm_TransactionReceipt *receipt)\r
+{\r
+\r
+}\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
@@ -286,10 +299,14 @@ void Rm_transactionForwarder (Rm_Inst *rmInst, Rm_Transaction *transaction,
         return;\r
     }\r
 \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
+    /* Find the transport for the higher level agent.  Check for a connection to a Client Delegate\r
+     * or a Server.  Clients will be connected to either a Client Delegate or a Server.  Client\r
+     * Delegates will be connected to a Server. */\r
+    if (rmInst->instType == Rm_instType_CLIENT)\r
+    {\r
+        dstTransportNode = Rm_transportNodeFindRemoteInstType(rmInst, Rm_instType_CLIENT_DELEGATE);\r
+    } \r
+    else if (rmInst->instType == Rm_instType_CLIENT_DELEGATE)\r
     {\r
         dstTransportNode = Rm_transportNodeFindRemoteInstType(rmInst, Rm_instType_SERVER);\r
     }\r
@@ -353,8 +370,14 @@ void Rm_transactionProcessor (Rm_Inst *rmInst, Rm_Transaction *transaction,
                               Rm_TransactionReceipt *receipt)\r
 {\r
     Rm_Transaction *queuedTransaction = NULL;\r
-    \r
-    if (rmInst->instType == Rm_instType_CLIENT)\r
+\r
+    /* Handle auto-forwarded transactions.  These transactions include:\r
+     * - All request transactions received on Clients are forwarded to the Client Delegate\r
+     * - NameServer requests received on the Client Delegate are forwarded to the Server */\r
+    if ((rmInst->instType == Rm_instType_CLIENT) ||\r
+        ((rmInst->instType == Rm_instType_CLIENT_DELEGATE) &&\r
+         (transaction->type == Rm_service_RESOURCE_MAP_TO_NAME) ||\r
+         (transaction->type == Rm_service_RESOURCE_UNMAP_NAME)))\r
     {\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
@@ -363,9 +386,36 @@ void Rm_transactionProcessor (Rm_Inst *rmInst, Rm_Transaction *transaction,
         {\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
+                if (rmInst->instType == Rm_instType_CLIENT)\r
+                {\r
+                    /* Client 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 if (rmInst->instType == Rm_instType_CLIENT_DELEGATE)\r
+                {\r
+                    /* Client Delegate found a NameServer transaction awaiting a response. Send the \r
+                     * response to either the transaction or service responder based on the \r
+                     * source instance */\r
+                    if (strcmp(queuedTransaction->sourceInstName, rmInst->name)\r
+                    {\r
+                        /* NameServer transaction originated from another instance.  Use the \r
+                         * transaction responder to send the NameServer result to the source instance.\r
+                         * Need to transfer the NameServer result details to the request transaction \r
+                         * which will be reused for the response. */\r
+                        queuedTransaction->details = transaction->details;\r
+                        Rm_transactionResponder(rmInst, queuedTransaction, receipt);\r
+                        /* Delete the response transaction */\r
+                        Rm_transactionQueueDelete(rmInst, transaction->id);                        \r
+                    }\r
+                    else\r
+                    {\r
+                        /* NameServer request originated on the Client Delegate instance.  Send to the\r
+                         * service responder */\r
+                        Rm_serviceResponder(rmInst, transaction, queuedTransaction,\r
+                                            receipt);\r
+                    }\r
+                }\r
             }\r
             else\r
             {\r
@@ -387,47 +437,180 @@ void Rm_transactionProcessor (Rm_Inst *rmInst, Rm_Transaction *transaction,
             }\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
+                /* All service requests on Clients are forwarded to the higher level RM Client \r
+                 * Delegate.  NameServer requests on Client Delegates are forwarded to the Server. */\r
                 Rm_transactionForwarder(rmInst, transaction, receipt);\r
             }\r
         }\r
     }\r
     else\r
     {\r
-        /* Execute a command processor based on the command type */\r
-        switch (transaction->transCommand)\r
+        /* Client Delegate and Server transaction processors. */\r
+        switch (transaction->type)\r
         {\r
-            case Rm_command_ALLOCATE:\r
-            case Rm_command_BLOCK_ALLOCATE:\r
-            case Rm_command_ALLOCATE_NAMED:\r
-                Rm_allocate(rmInst, transaction, receipt);\r
-                break;\r
-            case Rm_command_FREE:\r
-            case Rm_command_BLOCK_FREE:\r
-            case Rm_command_FREE_NAMED:\r
-                Rm_free(rmInst, transaction, receipt);\r
-                break;\r
-            case Rm_command_MAP_NAME:\r
-                Rm_nsAddObject(rmInst, transaction, receipt);\r
+            case Rm_service_RESOURCE_ALLOCATE:\r
+            case Rm_service_RESOURCE_BLOCK_ALLOCATE:\r
+            case Rm_service_RESOURCE_ALLOCATE_BY_NAME:\r
+                /* Run the transaction through the response handler to take care of any\r
+                 * transactions that are responses to sent allocation requests. */\r
+                if (queuedTransaction = Rm_transactionQueueFind(rmInst, transaction->id))\r
+                {\r
+                    if (queuedTransaction->state == Rm_transactionState_AWAITING_RESPONSE)\r
+                    {\r
+                        /* If source instance name does not match the current instance\r
+                         * name the allocation request came from a client.  The result\r
+                         * must be sent back to the Client */\r
+                        if (strcmp(queuedTransaction->sourceInstName, rmInst->name))\r
+                        {\r
+                            /* Names don't match.  Copy the allocation response resource data \r
+                             * into the original transaction and send it back to the Client */\r
+                            queuedTransaction->details = transaction->details;\r
+                            memcpy ((void *)&(queuedTransaction->resourceInfo), \r
+                                    (void *)&(transaction->resourceInfo), sizeof(Rm_ResourceInfo));\r
+                            Rm_transactionResponder(rmInst, queuedTransaction, receipt);\r
+                            /* Delete the response transaction */\r
+                            Rm_transactionQueueDelete(rmInst, transaction->id);\r
+                        }\r
+                        else\r
+                        {\r
+                            /* Resource allocation request originated locally on Client Delegate\r
+                             * instance. Send the response via the service responder. */\r
+                            Rm_serviceResponder(rmInst, transaction, queuedTransaction,\r
+                                                receipt);                            \r
+                        }\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
+                }\r
+                else\r
+                {\r
+                    /* This is a new transaction request originating from an RM instance with fewer\r
+                     * allocate/free privileges.  Run the allocation handler to see if the resource\r
+                     * request can be handled locally or if it needs to be forwarded to a higher level\r
+                     * agent */\r
+                     Rm_allocationHandler(rmInst, transaction, receipt);\r
+                }\r
                 break;\r
-            case Rm_command_UNMAP_NAME:\r
-                Rm_nsDeleteObject(rmInst, transaction, receipt);\r
-                break;\r
-            case Rm_command_RESOURCE_STATUS:\r
-                Rm_getResourceStatus(rmInst, transaction, receipt);\r
-                break;\r
-            case Rm_command_RESOURCE_RESPONSE:\r
-                \r
+            case Rm_service_RESOURCE_FREE:\r
+            case Rm_service_RESOURCE_BLOCK_FREE:\r
+            case Rm_service_RESOURCE_FREE_BY_NAME:\r
+                /* Run the transaction through the response handler to take care of any\r
+                 * transactions that are responses to sent free requests. */\r
+                if (queuedTransaction = Rm_transactionQueueFind(rmInst, transaction->id))\r
+                {\r
+                    if (queuedTransaction->state == Rm_transactionState_AWAITING_RESPONSE)\r
+                    {\r
+                        /* If source instance name does not match the current instance\r
+                         * name the allocation request came from a client.  The result\r
+                         * must be sent back to the Client */\r
+                        if (strcmp(queuedTransaction->sourceInstName, rmInst->name))\r
+                        {\r
+                            /* Names don't match.  Copy the free response resource data \r
+                             * into the original transaction and send it back to the Client */\r
+                            queuedTransaction->details = transaction->details;\r
+                            memcpy ((void *)&(queuedTransaction->resourceInfo), \r
+                                    (void *)&(transaction->resourceInfo), sizeof(Rm_ResourceInfo));\r
+                            Rm_transactionResponder(rmInst, queuedTransaction, receipt);\r
+                            /* Delete the response transaction */\r
+                            Rm_transactionQueueDelete(rmInst, transaction->id);\r
+                        }\r
+                        else\r
+                        {\r
+                            /* Resource free request originated locally on Client Delegate\r
+                             * instance. Send the response via the service responder. */\r
+                            Rm_serviceResponder(rmInst, transaction, queuedTransaction,\r
+                                                receipt);                            \r
+                        }\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
+                }\r
+                else\r
+                {\r
+                    /* This is a new transaction request originating from an RM instance with fewer\r
+                     * allocate/free privileges.  Run the free handler to see if the resource\r
+                     * request can be handled locally or if it needs to be forwarded to a higher level\r
+                     * agent */\r
+                     Rm_freeHandler(rmInst, transaction, receipt);\r
+                }\r
+\r
                 break;\r
-            case Rm_command_POLICY_REQUEST:\r
+            case Rm_service_RESOURCE_MAP_TO_NAME:\r
+                /* Server is the only RM instance capable of adding NameServer objects */\r
+                if (rmInst->instType == Rm_instType_SERVER)\r
+                {\r
+                    /* Create a new NameServer object with the request transaction information */\r
+                    Rm_nsAddObject(rmInst, transaction, receipt);\r
+\r
+                    /* Return the result of the NameServer addition to the RM instance\r
+                     * that requested it */\r
+                    transaction->details = receipt->serviceResult;\r
+\r
+                    /* If source instance name does not match the current instance\r
+                     * name the NameServer request came from a Client or Client Delegate.  The \r
+                     * result must be sent back to the Client or Client Delegate */\r
+                    if (strcmp(transaction->sourceInstName, rmInst->name))\r
+                    {\r
+                        Rm_transactionResponder(rmInst, queuedTransaction, receipt);\r
+                    }\r
+                    else\r
+                    {\r
+                        /* NameServer addition request originated locally on Server\r
+                         * instance. Send the response via the service responder.  In this case\r
+                         * the request transaction will be passed as NULL since the request\r
+                         * is being reused as the response */\r
+                        Rm_serviceResponder(rmInst, transaction, NULL, receipt);                            \r
+                    }\r
+                }\r
+                else\r
+                {\r
+                    receipt->serviceResult = RM_SERVICE_ERROR_NAMESERVER_OBJECT_CREATE_ON_INVALID_INSTANCE;\r
+                }\r
                 break;\r
-            case Rm_command_POLICY_RESPONSE:\r
+            case Rm_service_RESOURCE_UNMAP_NAME:\r
+                /* Server is the only RM instance capable of deleting NameServer objects */\r
+                if (rmInst->instType == Rm_instType_SERVER)\r
+                {\r
+                    /* Delete an existing NameServer object with the request transaction information */\r
+                    Rm_nsDeleteObject(rmInst, transaction, receipt);\r
+\r
+                    /* Return the result of the NameServer deletion to the RM instance\r
+                     * that requested it */\r
+                    transaction->details = receipt->serviceResult;\r
+\r
+                    /* If source instance name does not match the current instance\r
+                     * name the NameServer request came from a Client or Client Delegate.  The \r
+                     * result must be sent back to the Client or Client Delegate */\r
+                    if (strcmp(transaction->sourceInstName, rmInst->name))\r
+                    {\r
+                        Rm_transactionResponder(rmInst, queuedTransaction, receipt);\r
+                    }\r
+                    else\r
+                    {\r
+                        /* NameServer delete request originated locally on Server\r
+                         * instance. Send the response via the service responder.  In this case\r
+                         * the request transaction will be passed as NULL since the request\r
+                         * is being reused as the response */\r
+                        Rm_serviceResponder(rmInst, transaction, NULL, receipt);                            \r
+                    }                    \r
+                }\r
+                else\r
+                {\r
+                    receipt->serviceResult = RM_SERVICE_ERROR_NAMESERVER_OBJECT_DELETE_ON_INVALID_INSTANCE;\r
+                }\r
                 break;\r
         }\r
-\r
     }\r
-\r
 }\r
 \r
 /**********************************************************************\r
diff --git a/src/rmnameserver.c b/src/rmnameserver.c
new file mode 100644 (file)
index 0000000..fe52b8c
--- /dev/null
@@ -0,0 +1,73 @@
+/**
+ *   @file  rmnameserver.c
+ *
+ *   @brief   
+ *      This is the Resource Manager NameServer 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 <ti/drv/rm/rmtypes.h>
+
+/* RM external API includes */
+
+
+/* RM internal API includes */
+#include <ti/drv/rm/include/rmloc.h>
+#include <ti/drv/rm/include/rmnameserverloc.h>
+
+/* RM OSAL layer */
+#include <rm_osal.h>
+
+/**********************************************************************
+ ********************** Internal Functions ****************************
+ **********************************************************************/
+
+void Rm_nsAddObject(Rm_Inst *rmInst, Rm_Transaction *transaction, 
+                    Rm_TransactionReceipt *receipt)
+{
+    /* STUB APPROVED FOR NOW */
+    receipt->serviceResult = RM_SERVICE_APPROVED;
+
+}
+
+void Rm_nsDeleteObject(Rm_Inst *rmInst, Rm_Transaction *transaction, 
+                    Rm_TransactionReceipt *receipt)
+{
+    /* STUB APPROVED FOR NOW */
+    receipt->serviceResult = RM_SERVICE_APPROVED;
+}
+
diff --git a/src/rmpolicy.c b/src/rmpolicy.c
new file mode 100644 (file)
index 0000000..db4d0bd
--- /dev/null
@@ -0,0 +1,53 @@
+/**
+ *   @file  rmpolicy.c
+ *
+ *   @brief   
+ *      This is the Resource Manager Policy 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 <ti/drv/rm/rmtypes.h>
+
+/* RM external API includes */
+#include <ti/drv/rm/include/rmpolicy.h>
+
+/* RM internal API includes */
+#include <ti/drv/rm/include/rmpolicyloc.h>
+
+/* RM OSAL layer */
+#include <rm_osal.h>
+
index 12ea88bdbf0552c5e06dad722c3b404fc292bac1..43368246b13d1315a0e66c185d7b044240a75a18 100644 (file)
@@ -170,25 +170,40 @@ void Rm_serviceResponder (Rm_Inst *rmInst, Rm_Transaction *responseTransaction,
     serviceResponse.serviceResult = responseTransaction->details;
     /* Pass back the ID that was provided to the component when it requested
      * the service */
-    serviceResponse.requestId = requestTransaction->id;
+    serviceResponse.requestId = responseTransaction->id;
 
     /* Service was approved and service was an allocate request.  The resource
      * data is passed back to the component */
     if ((serviceResponse->serviceResult == RM_SERVICE_APPROVED) &&
-        ((requestTransaction.type == Rm_service_RESOURCE_ALLOCATE) ||
-         (requestTransaction.type == Rm_service_RESOURCE_BLOCK_ALLOCATE) ||
-         (requestTransaction.type == Rm_service_RESOURCE_ALLOCATE_BY_NAME)))
+        ((responseTransaction.type == Rm_service_RESOURCE_ALLOCATE) ||
+         (responseTransaction.type == Rm_service_RESOURCE_BLOCK_ALLOCATE) ||
+         (responseTransaction.type == Rm_service_RESOURCE_ALLOCATE_BY_NAME)))
     {
         serviceResponse->resourceBase = receipt.resourceBase;
         serviceResponse->resourceRange = receipt.resourceRange;
     }
 
     /* Issue the callback to the requesting component with the response information */
-    requestTransaction->callback(&serviceResponse);
+    if (requestTransaction != NULL)
+    {
+        /* The requestTransaction will be NULL if the request transaction is handled
+         * by the same RM instance it was created on.  Typically this applies to RM
+         * Client Delegate and RM Server instances.  In these cases the response
+         * transaction will be a copy of the request transaction, meaning it will contain
+         * the proper callback information */
+        requestTransaction->callback(&serviceResponse);
+    }
+    else
+    {
+        responseTransaction->callback(&serviceResponse);
+    }
 
     /* Delete both transactions from the transaction queue */
     Rm_transactionQueueDelete(rmInst,responseTransaction->id);
-    Rm_transactionQueueDelete(rmInst,requestTransaction->id);
+    if (requestTransaction != NULL)
+    {
+        Rm_transactionQueueDelete(rmInst,requestTransaction->id);
+    }
 
     /* Response to component completed */
     receipt.serviceResult = RM_SERVICE_ACTION_OKAY;
index 3971489822613758de00f4c08b7bdd51d8ff5ea8..ab503df2caaafe0a252adbd08534837ea265c9e3 100644 (file)
@@ -443,10 +443,10 @@ Rm_TransportHandle Rm_transportRegister (Rm_Handle rmHandle, Rm_TransportCfg *tr
     /* 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
-        ((transportCfg->rmRemoteInstType == Rm_instType_CLIENT_DELEGATE) ||\r
-         (transportCfg->rmRemoteInstType == Rm_instType_SERVER)) &&\r
+    if (((rmInst->instType == Rm_instType_CLIENT) &&\r
+         (transportCfg->remoteInstType == Rm_instType_CLIENT_DELEGATE)) || \r
+        ((rmInst->instType == Rm_instType_CLIENT_DELEGATE) &&\r
+         (transportCfg->remoteInstType == Rm_instType_SERVER)) &&\r
         rmInst->registeredWithDelegateOrServer)\r
     {\r
         Rm_osalLocalCsExit(key);\r
@@ -505,14 +505,6 @@ Rm_TransportResult Rm_transportUnregister (Rm_Handle rmHandle, Rm_TransportHandl
     return (retVal);\r
 }\r
 \r
-\r
-Rm_TransVerifyResult Rm_transportVerify (Rm_Handle rmHandle, uint32_t timeout, \r
-                                         Rm_TransFailData *failData)\r
-{\r
-\r
-}\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
@@ -587,34 +579,6 @@ int32_t Rm_receivePktIsr(Rm_Handle rmHandle, Rm_TransportHandle transportHandle,
              * request transaction's ID  */\r
             transaction = Rm_transactionQueueAdd(rmInst, resourceRespPkt->responseId);\r
 \r
-            /* Transfer the rest of the data into the transaction */\r
-            if (resourceRespPkt->resourceReqType = Rm_resReqPktType_ALLOCATE)\r
-            {\r
-                transaction->type = Rm_service_RESOURCE_ALLOCATE;\r
-            }\r
-            else if (resourceRespPkt->resourceReqType = Rm_resReqPktType_BLOCK_ALLOCATE)\r
-            {\r
-                transaction->type = Rm_service_RESOURCE_BLOCK_ALLOCATE;\r
-            }\r
-            else if (resourceRespPkt->resourceReqType = Rm_resReqPktType_ALLOCATE_NAMED)\r
-            {\r
-                transaction->type = Rm_service_RESOURCE_ALLOCATE_BY_NAME;\r
-            }\r
-            else if (resourceRespPkt->resourceReqType = Rm_resReqPktType_FREE)\r
-            {\r
-                transaction->type = Rm_service_RESOURCE_FREE;\r
-            }\r
-            else if (resourceRespPkt->resourceReqType = Rm_resReqPktType_BLOCK_FREE)\r
-            {\r
-                transaction->type = case Rm_service_RESOURCE_BLOCK_FREE;\r
-            }\r
-            else if (resourceRespPkt->resourceReqType = Rm_resReqPktType_FREE_NAMED)\r
-            {\r
-                transaction->type = Rm_service_RESOURCE_FREE_BY_NAME;\r
-            }\r
-\r
-            strcpy(transaction->sourceInstName, resourceReqPkt->instName);\r
-\r
             if (resourceRespPkt->requestResult = RM_SERVICE_APPROVED)\r
             {\r
                 transaction->state = Rm_transactionState_RESOURCE_APPROVED;\r
@@ -622,7 +586,7 @@ int32_t Rm_receivePktIsr(Rm_Handle rmHandle, Rm_TransportHandle transportHandle,
             else if ((resourceRespPkt->requestResult >= RM_SERVICE_DENIED_BEGIN) &&\r
                      (resourceRespPkt->requestResult <= RM_SERVICE_DENIED_END)\r
             {\r
-                transaction->state - Rm_transactionState_RESOURCE_DENIED;\r
+                transaction->state = Rm_transactionState_RESOURCE_DENIED;\r
             }            \r
             /* The result of the request should be placed in the details field of the \r
              * response transaction */\r
@@ -634,12 +598,65 @@ int32_t Rm_receivePktIsr(Rm_Handle rmHandle, Rm_TransportHandle transportHandle,
             Rm_transactionProcessor(rmInst, transaction, &receipt);\r
             break;\r
         case Rm_pktType_NAMESERVER_REQUEST:\r
+            Rm_NsRequestPkt *nsRequestPkt = (Rm_NsRequestPkt *)pkt->data;\r
+\r
+            transaction = Rm_transactionQueueAdd(rmInst, nsRequestPkt->requestId);\r
+\r
+            if (nsRequestPkt->nsRequestType == Rm_nsReqPktType_MAP_RESOURCE)\r
+            {\r
+                transaction->type = Rm_service_RESOURCE_MAP_TO_NAME;\r
+            }\r
+            else if (nsRequestPkt->nsRequestType == Rm_nsReqPktType_UNMAP_RESOURCE)\r
+            {\r
+                transaction->type = Rm_service_RESOURCE_UNMAP_NAME;\r
+            }\r
+\r
+            strcpy(transaction->sourceInstName, nsRequestPkt->instName);\r
+            transaction->state = Rm_transactionState_PROCESSING;\r
+            memcpy ((void *)&(transaction->resourceInfo), (void *)&(nsRequestPkt->resourceInfo),\r
+                    sizeof(Rm_ResourceInfo));\r
+\r
+            /* Process the transaction */\r
+            Rm_transactionProcessor(rmInst, transaction, &receipt);            \r
             break;\r
         case Rm_pktType_NAMESERVER_RESPONSE:\r
+            Rm_NsResponsePkt *nsResponsePkt = (Rm_NsResponsePkt *)pkt->data;\r
+\r
+            transaction = Rm_transactionQueueAdd(rmInst, nsResponsePkt->responseId);\r
+            transaction->details = nsResponsePkt->requestResult;\r
+\r
+            if (nsResponsePkt->requestResult = RM_SERVICE_APPROVED)\r
+            {\r
+                transaction->state = Rm_transactionState_RESOURCE_APPROVED;\r
+            }\r
+            else if ((nsResponsePkt->requestResult >= RM_SERVICE_DENIED_BEGIN) &&\r
+                     (nsResponsePkt->requestResult <= RM_SERVICE_DENIED_END)\r
+            {\r
+                transaction->state = Rm_transactionState_RESOURCE_DENIED;\r
+            }\r
+\r
+            /* Process the transaction */\r
+            Rm_transactionProcessor(rmInst, transaction, &receipt);\r
             break;\r
+        case Rm_pktType_POLICY_REQUEST:\r
+            Rm_PolicyRequestPkt *policyRequestPkt = (Rm_PolicyRequestPkt *)pkt->data;\r
+\r
+            /* FILL IN POLICY API INFORMATION */\r
+            break;            \r
         case Rm_pktType_POLICY_CHANGE:\r
+            Rm_PolicyChangePkt *policyChangePkt = (Rm_PolicyChangePkt *)pkt->data;\r
+\r
+            /* FILL IN POLICY API INFORMATION */\r
             break;\r
-        case Rm_pktType_POLICY_REQUEST:\r
+        case Rm_pktType_RESOURCE_POOL_MODIFICATION_REQUEST:\r
+            Rm_ResourcePoolModRequestPkt *resPoolModReqPkt = (Rm_ResourcePoolModRequestPkt *)pkt->data;\r
+\r
+            /* FILL IN RESOURCE POOL MODIFICATION API */\r
+            break;\r
+        case Rm_pktType_RESOURCE_POOL_MODIFICATION_RESPONSE:\r
+            Rm_ResourcePoolModResponsePkt *resPoolModRespPkt = (Rm_ResourcePoolModResponsePkt *)pkt->data;\r
+\r
+            /* FILL IN RESOURCE POOL MODIFICAITON API */\r
             break;\r
         default:\r
             /* Invalid packet type.  Free the packet and return */\r
@@ -647,6 +664,9 @@ int32_t Rm_receivePktIsr(Rm_Handle rmHandle, Rm_TransportHandle transportHandle,
             return (RM_TRANSPORT_ERROR_INVALID_PACKET_TYPE);\r
       }\r
 \r
+    /* Free the packet after it has been processed */\r
+    rmInst->transport.rmFreePkt(transportHandle, pkt);\r
+\r
     /* Return the receipt's service result which contains the result return code\r
      * for the receive packet */\r
     return (receipt->serviceResult);\r
@@ -654,61 +674,40 @@ int32_t Rm_receivePktIsr(Rm_Handle rmHandle, Rm_TransportHandle transportHandle,
 \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_receivePktPolling(Rm_Handle rmHandle, Rm_TransportHandle transHandle)\r
+int32_t Rm_receivePktPolling(Rm_Handle rmHandle, Rm_TransportHandle transportHandle)\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
+    Rm_Packet *pkt = NULL;\r
+    int32_t retVal = RM_SERVICE_ACTION_BASE;\r
 \r
-    if (transNode == NULL)\r
+    /* Make sure the transport handle is registered with the provided RM instance */\r
+    if (Rm_transportNodeFindTransportHandle(rmInst, transportHandle) == NULL)\r
     {\r
-        Rm_osalLocalCsExit(key);\r
-        return (-1) /* ERROR: THE TRANSPORT HANDLE IS NOT REGISTERED WITH THE RM HANDLE */\r
+        /* Transport is not registered with the RM instance.  Return an error.\r
+         * The packet cannot be freed since the transport handle is not valid. */\r
+        return (RM_TRANSPORT_ERROR_TRANSPORT_HANDLE_NOT_REGISTERED_WITH_INSTANCE);\r
     }\r
 \r
     /* Check to see if any RM packets are available.  Process any available packets. */\r
-    while (rmInst->transport.rmNumPktsReceived(transHandle))\r
+    while (rmInst->transport.rmNumPktsReceived(transportHandle))\r
     {\r
-        rmInst->transport.rmReceive(transHandle, rmPkt);\r
+        pkt = rmInst->transport.rmReceive(transportHandle);\r
 \r
-        if (rmPkt == NULL)\r
+        if (pkt == NULL)\r
         {\r
-            retVal = -1;  /* ERROR - PACKET RECEIVED FROM TRANSPORT IS NULL */\r
+            return (RM_TRANSPORT_ERROR_PACKET_RECEPTION_ERROR);\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
+        /* Pass the packet to RM.  The packet will be freed within the PktIsr API */\r
+        if (retVal = Rm_receivePktIsr(rmHandle, transportHandle, pkt) <= RM_SERVICE_ERROR_BASE)\r
         {\r
-            /* If retVal is not 0 (Okay) there was an error so break out of loop and return */\r
-            break;\r
+            /* Return if an error is encountered */\r
+            return (retVal);\r
         }\r
     }\r
-    \r
-    Rm_osalLocalCsExit(key);\r
     return (retVal); \r
 }\r
 \r
-\r
 /**\r
 @}\r
 */\r