/** * @file rm.c * * @brief * This is the Resource Manager source. * * \par * ============================================================================ * @n (C) Copyright 2012, Texas Instruments, Inc. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the * distribution. * * Neither the name of Texas Instruments Incorporated nor the names of * its contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * * \par */ /* RM Types */ #include /* RM external includes */ #include #include /* RM internal includes */ #include #include /* RM OSAL layer */ #include /********************************************************************** ********************** Internal Functions **************************** **********************************************************************/ Rm_TransportNode *Rm_transportNodeAdd(Rm_Inst *rmInst, Rm_TransportCfg *transportCfg) { Rm_TransportNode *routeMap = (Rm_TransportNode *)rmInst->routeMap; Rm_TransportNode *newTransportNode = NULL; void *key; /* Lock access to the RM instance's route map */ key = Rm_osalCsEnter(); /* Get memory for a new transport node from local memory */ newTransportNode = Rm_osalMalloc (sizeof(Rm_TransportNode), false); /* Return if the memory allocated for the transport node is NULL */ if (newTransportNode != NULL) { /* Populate the new entry */ newTransportNode->rmHandle = (Rm_Handle) rmInst; newTransportNode->remoteInstType = transportCfg->remoteInstType; strcpy(&(newTransportNode->remoteInstName)[0], transportCfg->remoteInstName); newTransportNode->nextNode = NULL; /* New node will always be NULL */ /* Check if there are any nodes in the transport routing map */ if (routeMap) { /* At least one node in the routing map. Add the new node to the end of the * routing map */ while (routeMap->nextNode != NULL) { /* Traverse the list until arriving at the last node */ routeMap = (Rm_TransportNode *)routeMap->nextNode; } /* Add the new node to the end of the list */ routeMap->nextNode = (void *)newTransportNode; } else { /* The transport routing map does not currently exist. The new node is the first node */ rmInst->routeMap = (void *)newTransportNode; } } Rm_osalCsExit(key); return (newTransportNode); } Rm_TransportNode *Rm_transportNodeFindTransportHandle(Rm_Inst *rmInst, Rm_TransportHandle transportHandle) { Rm_TransportNode *transportNode = (Rm_TransportNode *)rmInst->routeMap; /* Make sure there is at least one node in the route map */ if (transportNode != NULL) { /* Find the transport node with the transport handle within the RM instance's * route map. If the end of the route map is reached without finding the node the * node pointer will be NULL */ while (transportNode != NULL) { /* The transport handle is the address of the transport node */ if (transportNode == ((Rm_TransportNode *)transportHandle)) { /* Match: break out of loop and return the node */ break; } transportNode = (Rm_TransportNode *)transportNode->nextNode; } } return (transportNode); } Rm_TransportNode *Rm_transportNodeFindRemoteName(Rm_Inst *rmInst, char *remoteName) { Rm_TransportNode *transportNode = (Rm_TransportNode *)rmInst->routeMap; /* Make sure there is at least one node in the route map */ if (transportNode != NULL) { /* Find the transport node with the provided remote instance name. * If the end of the route map is reached without finding the node the * node pointer will be NULL */ while (transportNode != NULL) { /* The transport handle is the address of the transport node */ if (strcmp(&(transportNode->remoteInstName)[0], remoteName) == 0) { /* Match: break out of loop and return the node */ break; } transportNode = (Rm_TransportNode *)transportNode->nextNode; } } return (transportNode); } Rm_TransportNode *Rm_transportNodeFindRemoteInstType(Rm_Inst *rmInst, Rm_InstType remoteInstType) { Rm_TransportNode *transportNode = (Rm_TransportNode *)rmInst->routeMap; /* Make sure there is at least one node in the route map */ if (transportNode != NULL) { /* Find the transport node with the provided remote instance type. * If the end of the route map is reached without finding the node the * node pointer will be NULL */ while (transportNode != NULL) { if (transportNode->remoteInstType == remoteInstType) { /* Match: break out of loop and return the node */ break; } transportNode = (Rm_TransportNode *)transportNode->nextNode; } } return (transportNode); } Rm_TransportResult Rm_transportNodeDelete(Rm_Inst *rmInst, Rm_TransportHandle transportHandle) { Rm_TransportNode *transportNode = (Rm_TransportNode *)rmInst->routeMap; Rm_TransportNode *prevNode = NULL; void *key; /* Lock access to the RM instance's route map */ key = Rm_osalCsEnter(); /* Make sure there is at least one entry in the transaction queue */ if (transportNode == NULL) { Rm_osalCsExit(key); return (RM_TRANSPORT_ERROR_NO_TRANSPORTS_REGISTERED); } /* Find the transport handle within the RM instance's route map. */ while (transportNode != NULL) { if (transportNode == (Rm_TransportNode *) transportHandle) { /* Match: break out of loop and delete the entry */ break; } prevNode = transportNode; transportNode = (Rm_TransportNode *)transportNode->nextNode; } /* Traversed entire queue but did not find transaction */ if (transportNode == NULL) { Rm_osalCsExit(key); return (RM_TRANSPORT_ERROR_HANDLE_HAS_NOT_BEEN_REGISTERED); } else { /* Delete the transport node */ if ((prevNode == NULL) && transportNode->nextNode) { /* Node to be deleted exists at start of route map. Map second * node to be start of route map as long as there are more than * one nodes */ rmInst->routeMap = transportNode->nextNode; } else { /* Node to be deleted is in the middle or at end of the route map. Adjust adjacent * node pointers. This covers the case where the node to be removed is at the * end of the route map. */ prevNode->nextNode = transportNode->nextNode; } /* Free the memory associated with the node. */ Rm_osalFree((void *) transportNode, sizeof(Rm_TransportNode), false); } Rm_osalCsExit(key); return (RM_TRANSPORT_SUCCESSFUL); } Rm_Packet *Rm_transportCreateResourceReqPkt(Rm_Inst *rmInst, Rm_TransportNode *dstTransportNode, Rm_Transaction *transaction, Rm_TransactionReceipt *receipt) { Rm_Packet *rmPkt = NULL; Rm_ResourceRequestPkt *resourceReqPkt = NULL; /* Make sure a buffer for the packet was allocated */ if ((rmPkt = rmInst->transport.rmAllocPkt((Rm_TransportHandle)dstTransportNode, sizeof(Rm_Packet))) == NULL) { receipt->serviceResult = RM_SERVICE_ERROR_TRANSPORT_ALLOC_PKT_ERROR; return (NULL); } /* Make sure allocated buffer is large enough to fit the request packet plus the * rmPktLen and Rm_PktType fields */ if (rmPkt->pktLenBytes < (sizeof(Rm_ResourceRequestPkt) + sizeof(uint32_t) + sizeof(Rm_pktType))) { receipt->serviceResult = RM_SERVICE_ERROR_TRANSPORT_PKT_BUF_TOO_SMALL; return (NULL); } /* Set the Rm Packet type */ rmPkt->pktType = Rm_pktType_RESOURCE_REQUEST; /* Assign the packet's data field to be the start of the resource request packet */ resourceReqPkt = (Rm_ResourceRequestPkt *) rmPkt->data; /* Populate the resource request packet using the transaction information */ resourceReqPkt->requestId = transaction->id; if (transaction->type == Rm_service_RESOURCE_ALLOCATE) { resourceReqPkt->resourceReqType = Rm_resReqPktType_ALLOCATE; } else if (transaction->type == Rm_service_RESOURCE_BLOCK_ALLOCATE) { resourceReqPkt->resourceReqType = Rm_resReqPktType_BLOCK_ALLOCATE; } else if (transaction->type == Rm_service_RESOURCE_ALLOCATE_BY_NAME) { resourceReqPkt->resourceReqType = Rm_resReqPktType_ALLOCATE_NAMED; } else if (transaction->type == Rm_service_RESOURCE_FREE) { resourceReqPkt->resourceReqType = Rm_resReqPktType_FREE; } else if (transaction->type == Rm_service_RESOURCE_BLOCK_FREE) { resourceReqPkt->resourceReqType = Rm_resReqPktType_BLOCK_FREE; } else if (transaction->type == Rm_service_RESOURCE_FREE_BY_NAME) { resourceReqPkt->resourceReqType = Rm_resReqPktType_FREE_NAMED; } strcpy(&(resourceReqPkt->instName)[0], rmInst->name); /* Copy the resource data */ memcpy ((void *)&(resourceReqPkt->resourceInfo), (void *)&(transaction->resourceInfo), sizeof(Rm_ResourceInfo)); return (rmPkt); } Rm_Packet *Rm_transportCreateResourceResponsePkt(Rm_Inst *rmInst, Rm_TransportNode *dstTransportNode, Rm_Transaction *transaction, Rm_TransactionReceipt *receipt) { Rm_Packet *rmPkt = NULL; Rm_ResourceResponsePkt *resourceRespPkt = NULL; /* Make sure a buffer for the packet was allocated */ if ((rmPkt = rmInst->transport.rmAllocPkt((Rm_TransportHandle)dstTransportNode, sizeof(Rm_Packet))) == NULL) { receipt->serviceResult = RM_SERVICE_ERROR_TRANSPORT_ALLOC_PKT_ERROR; return (NULL); } /* Make sure allocated buffer is large enough to fit the request packet plus the * rmPktLen and Rm_PktType fields */ if (rmPkt->pktLenBytes < (sizeof(Rm_ResourceResponsePkt) + sizeof(uint32_t) + sizeof(Rm_pktType))) { receipt->serviceResult = RM_SERVICE_ERROR_TRANSPORT_PKT_BUF_TOO_SMALL; return (NULL); } /* Set the Rm Packet type */ rmPkt->pktType = Rm_pktType_RESOURCE_RESPONSE; /* Assign the packet's data field to be the start of the resource response packet */ resourceRespPkt = (Rm_ResourceResponsePkt *)rmPkt->data; /* Populate the resource response packet using the transaction information */ resourceRespPkt->responseId = transaction->id; resourceRespPkt->requestResult = transaction->details; /* Copy the resource data */ memcpy ((void *)&(resourceRespPkt->resourceInfo), (void *)&(transaction->resourceInfo), sizeof(Rm_ResourceInfo)); return (rmPkt); } Rm_Packet *Rm_transportCreateNsRequestPkt(Rm_Inst *rmInst, Rm_TransportNode *dstTransportNode, Rm_Transaction *transaction, Rm_TransactionReceipt *receipt) { Rm_Packet *rmPkt = NULL; Rm_NsRequestPkt *nsReqPkt = NULL; /* Make sure a buffer for the packet was allocated */ if ((rmPkt = rmInst->transport.rmAllocPkt((Rm_TransportHandle)dstTransportNode, sizeof(Rm_Packet))) == NULL) { receipt->serviceResult = RM_SERVICE_ERROR_TRANSPORT_ALLOC_PKT_ERROR; return (NULL); } /* Make sure allocated buffer is large enough to fit the request packet plus the * rmPktLen and Rm_PktType fields */ if (rmPkt->pktLenBytes < (sizeof(Rm_NsRequestPkt) + sizeof(uint32_t) + sizeof(Rm_pktType))) { receipt->serviceResult = RM_SERVICE_ERROR_TRANSPORT_PKT_BUF_TOO_SMALL; return (NULL); } /* Set the Rm Packet type */ rmPkt->pktType = Rm_pktType_NAMESERVER_REQUEST; /* Assign the packet's data field to be the start of the NameServer request packet */ nsReqPkt = (Rm_NsRequestPkt *)rmPkt->data; /* Populate the NameServer request packet using the transaction information */ nsReqPkt->requestId = transaction->id; if (transaction->type == Rm_service_RESOURCE_MAP_TO_NAME) { nsReqPkt->nsRequestType = Rm_nsReqPktType_MAP_RESOURCE; } else if (transaction->type == Rm_service_RESOURCE_UNMAP_NAME) { nsReqPkt->nsRequestType = Rm_nsReqPktType_UNMAP_RESOURCE; } strcpy(&(nsReqPkt->instName)[0], rmInst->name); /* Copy the NameServer request data */ memcpy ((void *)&(nsReqPkt->resourceInfo), (void *)&(transaction->resourceInfo), sizeof(Rm_ResourceInfo)); return (rmPkt); } Rm_Packet *Rm_transportCreateNsResponsePkt(Rm_Inst *rmInst, Rm_TransportNode *dstTransportNode, Rm_Transaction *transaction, Rm_TransactionReceipt *receipt) { Rm_Packet *rmPkt = NULL; Rm_NsResponsePkt *nsRespPkt = NULL; /* Make sure a buffer for the packet was allocated */ if ((rmPkt = rmInst->transport.rmAllocPkt((Rm_TransportHandle)dstTransportNode, sizeof(Rm_Packet))) == NULL) { receipt->serviceResult = RM_SERVICE_ERROR_TRANSPORT_ALLOC_PKT_ERROR; return (NULL); } /* Make sure allocated buffer is large enough to fit the response packet plus the * rmPktLen and Rm_PktType fields */ if (rmPkt->pktLenBytes < (sizeof(Rm_NsResponsePkt) + sizeof(uint32_t) + sizeof(Rm_pktType))) { receipt->serviceResult = RM_SERVICE_ERROR_TRANSPORT_PKT_BUF_TOO_SMALL; return (NULL); } /* Set the Rm Packet type */ rmPkt->pktType = Rm_pktType_NAMESERVER_RESPONSE; /* Assign the packet's data field to be the start of the NameServer response packet */ nsRespPkt = (Rm_NsResponsePkt *)rmPkt->data; /* Populate the NameServer response packet using the transaction information */ nsRespPkt->responseId = transaction->id; nsRespPkt->requestResult = transaction->details; return (rmPkt); } /********************************************************************** ********************* Application visible APIs *********************** **********************************************************************/ Rm_TransportHandle Rm_transportRegister (Rm_Handle rmHandle, Rm_TransportCfg *transportCfg) { Rm_Inst *rmInst = (Rm_Inst *) rmHandle; Rm_TransportNode *transportNode = NULL; void *key; /* Lock access to the RM instance */ key = Rm_osalCsEnter(); /* RM Servers cannot connect to other Servers. RM Client Delegates cannot * connect to other Client Delegates. */ if (((rmInst->instType == Rm_instType_SERVER) && (transportCfg->remoteInstType == Rm_instType_SERVER)) || ((rmInst->instType == Rm_instType_CLIENT_DELEGATE) && (transportCfg->remoteInstType == Rm_instType_CLIENT_DELEGATE))) { Rm_osalCsExit(key); 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) && (transportCfg->remoteInstType == Rm_instType_CLIENT_DELEGATE)) || ((rmInst->instType == Rm_instType_CLIENT_DELEGATE) && (transportCfg->remoteInstType == Rm_instType_SERVER)) && rmInst->registeredWithDelegateOrServer) { Rm_osalCsExit(key); return (NULL); /* Error - return null */ } /* Copy the transport callout function pointers into the RM instance as long as they're * valid or not NULL */ if (transportCfg->transportCalloutsValid) { /* The transport APIs must not be NULL */ if ((transportCfg->transportCallouts.rmAllocPkt == NULL) || (transportCfg->transportCallouts.rmFreePkt == NULL) || (transportCfg->transportCallouts.rmSend == NULL) || (transportCfg->transportCallouts.rmReceive == NULL) || (transportCfg->transportCallouts.rmNumPktsReceived == NULL)) { Rm_osalCsExit(key); return (NULL); /* Error - return null */ } /* Populate the instance transport callouts */ rmInst->transport.rmAllocPkt = transportCfg->transportCallouts.rmAllocPkt; rmInst->transport.rmFreePkt = transportCfg->transportCallouts.rmFreePkt; rmInst->transport.rmSend = transportCfg->transportCallouts.rmSend; rmInst->transport.rmReceive = transportCfg->transportCallouts.rmReceive; rmInst->transport.rmNumPktsReceived = transportCfg->transportCallouts.rmNumPktsReceived; } /* Error checks passed - Create a new transport handle for the specified RM instance and * create a new node in the RM instance's routing map. */ transportNode = Rm_transportNodeAdd(rmInst, transportCfg); /* Specify RM instance has registered with a higher level agent */ if ((transportNode->remoteInstType == Rm_instType_CLIENT_DELEGATE) || (transportNode->remoteInstType == Rm_instType_SERVER)) { rmInst->registeredWithDelegateOrServer = true; } Rm_osalCsExit(key); return ((Rm_TransportHandle) transportNode); } Rm_TransportResult Rm_transportUnregister (Rm_Handle rmHandle, Rm_TransportHandle transportHandle) { Rm_Inst *rmInst = (Rm_Inst *) rmHandle; Rm_TransportNode *transportNode = NULL; Rm_TransportResult retVal = RM_TRANSPORT_SUCCESSFUL; void *key; /* Lock access to the RM instance */ key = Rm_osalCsEnter(); /* Check if the transportHandle exists in the RM instance's route map */ transportNode = Rm_transportNodeFindTransportHandle(rmInst, transportHandle); if (transportNode == NULL) { /* Error - transport node does not exist in RM instance route map */ Rm_osalCsExit(key); return (RM_TRANSPORT_ERROR_HANDLE_HAS_NOT_BEEN_REGISTERED); } /* Remove specification that RM instance 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 ((transportNode->remoteInstType == Rm_instType_CLIENT_DELEGATE) || (transportNode->remoteInstType == Rm_instType_SERVER)) { rmInst->registeredWithDelegateOrServer = false; } /* Delete the transport node */ retVal = Rm_transportNodeDelete(rmInst, transportHandle); Rm_osalCsExit(key); return (retVal); } /* Used by the application to pass RM packets received from a transport to RM. * CODE THE FUNCTION SUCH THAT IT CAN BE CALLED DIRECTLY BY APP OR BE PLUGGED * AS PART OF AN ISR HANDLER FOR THE TRANSACTION RECEIVE */ int32_t Rm_receivePktIsr(Rm_TransportHandle transportHandle, Rm_Packet *pkt) { Rm_Inst *rmInst = (Rm_Inst *)((Rm_TransportNode *)transportHandle)->rmHandle; Rm_Transaction *transaction; Rm_TransactionReceipt receipt; /* Make sure the transport handle is registered with the provided RM instance */ if (Rm_transportNodeFindTransportHandle(rmInst, transportHandle) == NULL) { /* Transport is not registered with the RM instance. Return an error. * The packet cannot be freed since the transport handle is not valid. */ return (RM_TRANSPORT_ERROR_HANDLE_HAS_NOT_BEEN_REGISTERED); } /* Clear the transaction receipt */ memset((void *)&receipt, 0, sizeof(Rm_TransactionReceipt)); /* Based on packet type transfer the data to a transaction or a policy structure */ switch (pkt->pktType) { case Rm_pktType_RESOURCE_REQUEST: { Rm_ResourceRequestPkt *resourceReqPkt = (Rm_ResourceRequestPkt *)pkt->data; /* The transaction ID will be the request ID. The request ID * will become the response packet's ID so the requesting RM instance * can filter received resource responses */ transaction = Rm_transactionQueueAdd(rmInst, resourceReqPkt->requestId); /* Transfer the rest of the data into the transaction */ if (resourceReqPkt->resourceReqType == Rm_resReqPktType_ALLOCATE) { transaction->type = Rm_service_RESOURCE_ALLOCATE; } else if (resourceReqPkt->resourceReqType == Rm_resReqPktType_BLOCK_ALLOCATE) { transaction->type = Rm_service_RESOURCE_BLOCK_ALLOCATE; } else if (resourceReqPkt->resourceReqType == Rm_resReqPktType_ALLOCATE_NAMED) { transaction->type = Rm_service_RESOURCE_ALLOCATE_BY_NAME; } else if (resourceReqPkt->resourceReqType == Rm_resReqPktType_FREE) { transaction->type = Rm_service_RESOURCE_FREE; } else if (resourceReqPkt->resourceReqType == Rm_resReqPktType_BLOCK_FREE) { transaction->type = Rm_service_RESOURCE_BLOCK_FREE; } else if (resourceReqPkt->resourceReqType == Rm_resReqPktType_FREE_NAMED) { transaction->type = Rm_service_RESOURCE_FREE_BY_NAME; } strcpy(transaction->sourceInstName, resourceReqPkt->instName); transaction->state = Rm_transactionState_PROCESSING; memcpy ((void *)&(transaction->resourceInfo), (void *)&(resourceReqPkt->resourceInfo), sizeof(Rm_ResourceInfo)); /* Process the transaction */ Rm_transactionProcessor(rmInst, transaction, &receipt); break; } case Rm_pktType_RESOURCE_RESPONSE: { Rm_ResourceResponsePkt *resourceRespPkt = (Rm_ResourceResponsePkt *)pkt->data; /* If the packet is a response packet the transaction ID should match a queued * request transaction's ID */ transaction = Rm_transactionQueueAdd(rmInst, resourceRespPkt->responseId); if (resourceRespPkt->requestResult == RM_SERVICE_APPROVED) { transaction->state = Rm_transactionState_RESOURCE_APPROVED; } else if ((resourceRespPkt->requestResult >= RM_SERVICE_DENIED_BEGIN) && (resourceRespPkt->requestResult <= RM_SERVICE_DENIED_END)) { transaction->state = Rm_transactionState_RESOURCE_DENIED; } /* The result of the request should be placed in the details field of the * response transaction */ transaction->details = resourceRespPkt->requestResult; memcpy ((void *)&(transaction->resourceInfo), (void *)&(resourceRespPkt->resourceInfo), sizeof(Rm_ResourceInfo)); /* Process the transaction */ Rm_transactionProcessor(rmInst, transaction, &receipt); break; } case Rm_pktType_NAMESERVER_REQUEST: { Rm_NsRequestPkt *nsRequestPkt = (Rm_NsRequestPkt *)pkt->data; transaction = Rm_transactionQueueAdd(rmInst, nsRequestPkt->requestId); if (nsRequestPkt->nsRequestType == Rm_nsReqPktType_MAP_RESOURCE) { transaction->type = Rm_service_RESOURCE_MAP_TO_NAME; } else if (nsRequestPkt->nsRequestType == Rm_nsReqPktType_UNMAP_RESOURCE) { transaction->type = Rm_service_RESOURCE_UNMAP_NAME; } strcpy(transaction->sourceInstName, nsRequestPkt->instName); transaction->state = Rm_transactionState_PROCESSING; memcpy ((void *)&(transaction->resourceInfo), (void *)&(nsRequestPkt->resourceInfo), sizeof(Rm_ResourceInfo)); /* Process the transaction */ Rm_transactionProcessor(rmInst, transaction, &receipt); break; } case Rm_pktType_NAMESERVER_RESPONSE: { Rm_NsResponsePkt *nsResponsePkt = (Rm_NsResponsePkt *)pkt->data; transaction = Rm_transactionQueueAdd(rmInst, nsResponsePkt->responseId); transaction->details = nsResponsePkt->requestResult; if (nsResponsePkt->requestResult == RM_SERVICE_APPROVED) { transaction->state = Rm_transactionState_RESOURCE_APPROVED; } else if ((nsResponsePkt->requestResult >= RM_SERVICE_DENIED_BEGIN) && (nsResponsePkt->requestResult <= RM_SERVICE_DENIED_END)) { transaction->state = Rm_transactionState_RESOURCE_DENIED; } /* Process the transaction */ Rm_transactionProcessor(rmInst, transaction, &receipt); break; } case Rm_pktType_POLICY_REQUEST: { Rm_PolicyRequestPkt *policyRequestPkt = (Rm_PolicyRequestPkt *)pkt->data; /* FILL IN POLICY API INFORMATION */ break; } case Rm_pktType_POLICY_CHANGE: { Rm_PolicyChangePkt *policyChangePkt = (Rm_PolicyChangePkt *)pkt->data; /* FILL IN POLICY API INFORMATION */ break; } case Rm_pktType_RESOURCE_POOL_MODIFICATION_REQUEST: { Rm_ResourcePoolModRequestPkt *resPoolModReqPkt = (Rm_ResourcePoolModRequestPkt *)pkt->data; /* FILL IN RESOURCE POOL MODIFICATION API */ /* Rm_resourcePoolModRequestHandler(...); Server only - needs to allocate resources to * the Client Delegate based on the policy and return those resources to the Client Delegate */ break; } case Rm_pktType_RESOURCE_POOL_MODIFICATION_RESPONSE: { Rm_ResourcePoolModResponsePkt *resPoolModRespPkt = (Rm_ResourcePoolModResponsePkt *)pkt->data; /* FILL IN RESOURCE POOL MODIFICAITON API */ /* Rm_resourcePoolModResponseHandler(...); Handler needs to populate allocator with * new resources provided in the response and then handle any request transactions waiting on * the resource pool modification */ break; } default: /* Invalid packet type. Free the packet and return */ rmInst->transport.rmFreePkt(transportHandle, pkt); return (RM_TRANSPORT_ERROR_INVALID_PACKET_TYPE); } /* Free the packet after it has been processed */ rmInst->transport.rmFreePkt(transportHandle, pkt); /* Return the receipt's service result which contains the result return code * for the receive packet */ return (receipt.serviceResult); } /* Application can call this API so that RM handles reception of packets based on * the RM handle and transport handle provided */ int32_t Rm_receivePktPolling(Rm_TransportHandle transportHandle) { Rm_Inst *rmInst = (Rm_Inst *)((Rm_TransportNode *)transportHandle)->rmHandle; Rm_Packet *pkt = NULL; int32_t retVal = RM_SERVICE_ACTION_BASE; /* Make sure the transport handle is registered with the provided RM instance */ if (Rm_transportNodeFindTransportHandle(rmInst, transportHandle) == NULL) { /* Transport is not registered with the RM instance. Return an error. * The packet cannot be freed since the transport handle is not valid. */ return (RM_TRANSPORT_ERROR_HANDLE_HAS_NOT_BEEN_REGISTERED); } /* Check to see if any RM packets are available. Process any available packets. */ while (rmInst->transport.rmNumPktsReceived(transportHandle) > 0) { pkt = rmInst->transport.rmReceive(transportHandle); if (pkt == NULL) { return (RM_TRANSPORT_ERROR_PACKET_RECEPTION_ERROR); } /* Pass the packet to RM. The packet will be freed within the PktIsr API */ if (retVal = Rm_receivePktIsr(transportHandle, pkt) <= RM_SERVICE_ERROR_BASE) { /* Return if an error is encountered */ return (retVal); } } return (retVal); } /** @} */