Coverity bug fixes
[keystone-rtos/rm-lld.git] / src / rm_transport.c
1 /**\r
2  *   @file  rm_transport.c\r
3  *\r
4  *   @brief   \r
5  *      This is the Resource Manager transport source.\r
6  *\r
7  *  \par\r
8  *  ============================================================================\r
9  *  @n   (C) Copyright 2012-2014, Texas Instruments, Inc.\r
10  * \r
11  *  Redistribution and use in source and binary forms, with or without \r
12  *  modification, are permitted provided that the following conditions \r
13  *  are met:\r
14  *\r
15  *    Redistributions of source code must retain the above copyright \r
16  *    notice, this list of conditions and the following disclaimer.\r
17  *\r
18  *    Redistributions in binary form must reproduce the above copyright\r
19  *    notice, this list of conditions and the following disclaimer in the \r
20  *    documentation and/or other materials provided with the   \r
21  *    distribution.\r
22  *\r
23  *    Neither the name of Texas Instruments Incorporated nor the names of\r
24  *    its contributors may be used to endorse or promote products derived\r
25  *    from this software without specific prior written permission.\r
26  *\r
27  *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \r
28  *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT \r
29  *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\r
30  *  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT \r
31  *  OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, \r
32  *  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT \r
33  *  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\r
34  *  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\r
35  *  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT \r
36  *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE \r
37  *  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\r
38  *\r
39  *  \par\r
40 */\r
41 \r
42 /* RM external includes */\r
43 #include <ti/drv/rm/rm.h>\r
44 #include <ti/drv/rm/rm_transport.h>\r
45 \r
46 /* RM internal includes */\r
47 #include <ti/drv/rm/include/rm_loc.h>\r
48 #include <ti/drv/rm/include/rm_transportloc.h>\r
49 \r
50 /* RM OSAL layer */\r
51 #include <rm_osal.h>\r
52 \r
53 /**********************************************************************\r
54  ************************ Local Functions *****************************\r
55  **********************************************************************/\r
56 \r
57 /* FUNCTION PURPOSE: Adds a transport\r
58  ***********************************************************************\r
59  * DESCRIPTION: Returns a pointer to a transport structure that\r
60  *              was created, initialized, and added to the \r
61  *              instance transport list.\r
62  */\r
63 static Rm_Transport *transportAdd(const Rm_TransportCfg *transportCfg)\r
64 {\r
65     Rm_Inst      *rmInst = (Rm_Inst *) transportCfg->rmHandle;\r
66     Rm_Transport *transports = rmInst->transports;\r
67     Rm_Transport *newTransport = NULL;\r
68 \r
69     newTransport = Rm_osalMalloc (sizeof(Rm_Transport));\r
70     memset((void *)newTransport, 0, sizeof(Rm_Transport));\r
71 \r
72     if (newTransport) {\r
73         newTransport->rmHandle = transportCfg->rmHandle;\r
74         newTransport->appTransportHandle = transportCfg->appTransportHandle;\r
75         newTransport->remoteInstType = transportCfg->remoteInstType;\r
76         newTransport->callouts.rmAllocPkt = transportCfg->transportCallouts.rmAllocPkt;\r
77         newTransport->callouts.rmSendPkt = transportCfg->transportCallouts.rmSendPkt;\r
78         newTransport->nextTransport = NULL;\r
79 \r
80         if (transports) {\r
81             while (transports->nextTransport) {\r
82                 transports = transports->nextTransport;\r
83             }\r
84             transports->nextTransport = newTransport;\r
85         }\r
86         else {\r
87             rmInst->transports = newTransport;\r
88         }\r
89     }\r
90     return (newTransport);\r
91 }\r
92 \r
93 /* FUNCTION PURPOSE: Tests if a transport is registered to an instance\r
94  ***********************************************************************\r
95  * DESCRIPTION: Returns TRUE if the supplied transport is found in\r
96  *              the instance transport list.  Otherwise, returns FALSE\r
97  */\r
98 static int transportIsRegistered(Rm_Handle rmHandle, Rm_Transport *transport)\r
99 {\r
100     Rm_Inst      *rmInst = (Rm_Inst *)rmHandle;\r
101     Rm_Transport *transportList = (Rm_Transport *)rmInst->transports;\r
102     \r
103     while (transportList) {\r
104         if (transportList == transport) {\r
105             return(RM_TRUE);             \r
106         }\r
107         transportList = transportList->nextTransport;\r
108     }\r
109     return (RM_FALSE);\r
110 }\r
111 \r
112 /* FUNCTION PURPOSE: Deletes a transport\r
113  ***********************************************************************\r
114  * DESCRIPTION: Removes a transport from an instance transport list\r
115  *              and then frees the memory associated with the transport\r
116  *              data structure\r
117  */\r
118 static void transportDelete(Rm_Transport *transport)\r
119 {\r
120     Rm_Inst      *rmInst = (Rm_Inst *)transport->rmHandle;\r
121     Rm_Transport *transportList = (Rm_Transport *)rmInst->transports;\r
122     Rm_Transport *prevTransport = NULL;\r
123 \r
124     /* Get previous transport in list */\r
125     while (transportList) {\r
126         if (transportList == transport) {\r
127             break;             \r
128         }\r
129         prevTransport = transportList;\r
130         transportList = transportList->nextTransport;\r
131     }\r
132 \r
133     if (prevTransport == NULL) {\r
134          rmInst->transports = transport->nextTransport;\r
135     }\r
136     else {\r
137          prevTransport->nextTransport = transport->nextTransport;\r
138     }\r
139     Rm_osalFree((void *)transport, sizeof(Rm_Transport));\r
140 }\r
141 \r
142 /**********************************************************************\r
143  ********************** Internal Functions ****************************\r
144  **********************************************************************/\r
145 \r
146 /* FUNCTION PURPOSE: Finds a transport based on remote inst type\r
147  ***********************************************************************\r
148  * DESCRIPTION: Returns a pointer to the transport within an instance's\r
149  *              transport list that matches the provided remote\r
150  *              instance type.  NULL is returned if no transports in \r
151  *              the list match the remote instance type.\r
152  */\r
153 Rm_Transport *rmTransportFindRemoteInstType(Rm_Transport *transports, Rm_InstType remoteInstType)\r
154 {\r
155     while (transports) {\r
156         if (transports->remoteInstType == remoteInstType) {\r
157             break;             \r
158         }\r
159         transports = transports->nextTransport;\r
160     }\r
161     return (transports);\r
162 }\r
163 \r
164 /* FUNCTION PURPOSE: Returns RM packet source instance\r
165  ***********************************************************************\r
166  * DESCRIPTION: Can return the RM instance name for one of two things:\r
167  *                  - RM instance from which provided RM packet originated\r
168  *                  - RM instance from which the service request contained\r
169  *                    in the provided RM packet originated\r
170  */\r
171 int32_t getPktSrcNames(const Rm_Packet *pkt, char *pktSrc, char *serviceSrc, int32_t bufLen)\r
172 {\r
173     int32_t retVal = RM_OK;\r
174 \r
175     if (bufLen != RM_NAME_MAX_CHARS) {\r
176         retVal = RM_ERROR_SRC_NAME_BUF_INVALID_SIZE;\r
177     }\r
178     else {\r
179         switch (pkt->pktType) {\r
180             case Rm_pktType_RESOURCE_REQUEST:\r
181             {\r
182                 Rm_ResourceRequestPkt *resourceReqPkt = (Rm_ResourceRequestPkt *)pkt->data;\r
183 \r
184                 if (pktSrc){\r
185                     rm_strncpy(pktSrc, resourceReqPkt->pktSrcInstName, RM_NAME_MAX_CHARS);\r
186                 }\r
187 \r
188                 if (serviceSrc) {\r
189                     rm_strncpy(serviceSrc, resourceReqPkt->serviceSrcInstName, RM_NAME_MAX_CHARS);\r
190                 }\r
191 \r
192                 break;\r
193             }\r
194             case Rm_pktType_NAMESERVER_REQUEST:\r
195             {\r
196                 Rm_NsRequestPkt *nsRequestPkt = (Rm_NsRequestPkt *)pkt->data;\r
197 \r
198                 if (pktSrc){\r
199                     rm_strncpy(pktSrc, nsRequestPkt->pktSrcInstName, RM_NAME_MAX_CHARS);\r
200                 }\r
201 \r
202                 if (serviceSrc) {\r
203                     rm_strncpy(serviceSrc, nsRequestPkt->serviceSrcInstName, RM_NAME_MAX_CHARS);\r
204                 }\r
205 \r
206                 break;\r
207             }\r
208             case Rm_pktType_RESOURCE_RESPONSE:\r
209             case Rm_pktType_NAMESERVER_RESPONSE:\r
210             default:\r
211             {\r
212                 retVal = RM_ERROR_PKT_AND_SERVICE_SRC_NOT_AVAIL;\r
213                 break;\r
214             }\r
215         }\r
216     }\r
217 \r
218     return (retVal);\r
219 }\r
220 \r
221 /**********************************************************************\r
222  ********************* Application visible APIs ***********************\r
223  **********************************************************************/\r
224 \r
225 /* FUNCTION PURPOSE: Registers an app transport with a RM instance\r
226  ***********************************************************************\r
227  * DESCRIPTION: Returns a transport handle to the application that\r
228  *              has been registered with an RM instance.  The handle\r
229  *              is used by the application to route packets to the\r
230  *              proper RM instance's based on the application\r
231  *              transport receive code.  The handle is also used\r
232  *              internally by RM to route request and response \r
233  *              packets to the correct application transports. NULL\r
234  *              is returned for the transport handle if any errors\r
235  *              are encountered.\r
236  */\r
237 Rm_TransportHandle Rm_transportRegister (const Rm_TransportCfg *transportCfg, int32_t *result)\r
238 {\r
239     Rm_Inst      *rmInst = (Rm_Inst *) transportCfg->rmHandle;\r
240     Rm_Transport *transport = NULL;\r
241     void         *key;\r
242 \r
243     *result = RM_OK;\r
244 \r
245     RM_SS_INST_INV_ENTER_CS(key);\r
246 \r
247     /* Shared servers and clients cannot connect to anyone */\r
248     if ((rmInst->instType == Rm_instType_SHARED_SERVER) ||\r
249         (rmInst->instType == Rm_instType_SHARED_CLIENT)){\r
250         *result = RM_ERROR_SHARED_INSTANCE_CANNOT_REG_TRANS;\r
251         goto errorExit;\r
252     }\r
253 \r
254     /* No one can connect to a shared server\r
255      * RM Servers cannot connect to other Servers.  \r
256      * RM Client Delegates cannot connect to other Client Delegates.\r
257      * RM Clients cannot connect to other Clients */\r
258     if ((transportCfg->remoteInstType == Rm_instType_SHARED_SERVER) ||\r
259         ((rmInst->instType == Rm_instType_SERVER) &&\r
260          (transportCfg->remoteInstType == Rm_instType_SERVER)) ||\r
261         ((rmInst->instType == Rm_instType_CLIENT_DELEGATE) &&\r
262          (transportCfg->remoteInstType == Rm_instType_CLIENT_DELEGATE)) ||\r
263         ((rmInst->instType == Rm_instType_CLIENT) &&\r
264          (transportCfg->remoteInstType == Rm_instType_CLIENT))) {\r
265         *result = RM_ERROR_INVALID_REMOTE_INST_TYPE;\r
266         goto errorExit;\r
267     }\r
268 \r
269     /* Verify Clients are not registering with more than one Client Delegate or Server. And\r
270      * that Client Delegate is not registering with more than one Server. */\r
271     if (rmInst->registeredWithDelegateOrServer &&\r
272         (((rmInst->instType == Rm_instType_CLIENT) &&\r
273           (transportCfg->remoteInstType == Rm_instType_CLIENT_DELEGATE)) || \r
274          ((rmInst->instType == Rm_instType_CLIENT_DELEGATE) &&\r
275           (transportCfg->remoteInstType == Rm_instType_SERVER)))) {\r
276         *result = RM_ERROR_ALREADY_REGD_SERVER_OR_CD;\r
277         goto errorExit;\r
278     }         \r
279     \r
280     if (!transportCfg->transportCallouts.rmAllocPkt) {\r
281         *result = RM_ERROR_TRANSPORT_ALLOC_PKT_NOT_REGD;\r
282         goto errorExit;\r
283     }\r
284     else if (!transportCfg->transportCallouts.rmSendPkt) {\r
285         *result = RM_ERROR_TRANSPORT_SEND_NOT_REGD;\r
286         goto errorExit;\r
287     }\r
288 \r
289     transport = transportAdd(transportCfg);\r
290     if ((transport->remoteInstType == Rm_instType_CLIENT_DELEGATE) ||\r
291         (transport->remoteInstType == Rm_instType_SERVER)) {\r
292         rmInst->registeredWithDelegateOrServer = RM_TRUE;\r
293     }\r
294 errorExit:\r
295     RM_SS_INST_WB_EXIT_CS(key);    \r
296     return ((Rm_TransportHandle) transport);\r
297 }\r
298 \r
299 /* FUNCTION PURPOSE: Reconfigures an instance's transport handle\r
300  ***********************************************************************\r
301  * DESCRIPTION: Reconfigures a transport handle based on the provided\r
302  *              configuration parameters if it exists within the \r
303  *              instance.\r
304  */\r
305 int32_t Rm_transportReconfig (Rm_TransportHandle transportHandle, const Rm_TransportReCfg *reCfg)\r
306 {\r
307     Rm_Transport *transport = (Rm_Transport *)transportHandle;\r
308     Rm_Inst      *rmInst = (Rm_Inst *)transport->rmHandle;\r
309     void         *key;\r
310     int32_t       retVal = RM_OK;\r
311 \r
312     RM_SS_INST_INV_ENTER_CS(key);\r
313 \r
314     if (transportIsRegistered(transport->rmHandle, transport)) {\r
315         /* Reconfigure existing transport's appTransportHandle.  Used in cases where instances\r
316          * running on same core connected by function call. */\r
317         transport->appTransportHandle = reCfg->appTransportHandle;\r
318 \r
319         if (reCfg->transportCallouts.rmAllocPkt) {\r
320             transport->callouts.rmAllocPkt = reCfg->transportCallouts.rmAllocPkt;\r
321         }\r
322         if (reCfg->transportCallouts.rmSendPkt) {\r
323             transport->callouts.rmSendPkt = reCfg->transportCallouts.rmSendPkt;\r
324         }\r
325     }\r
326     else {\r
327         retVal = RM_ERROR_TRANSPORT_HANDLE_DOES_NOT_EXIST;\r
328     }        \r
329 \r
330     RM_SS_INST_WB_EXIT_CS(key);    \r
331     return (retVal);\r
332 }\r
333 \r
334 /* FUNCTION PURPOSE: Unregisters an app transport from a RM instance\r
335  ***********************************************************************\r
336  * DESCRIPTION: Deletes a registered transport from the transport\r
337  *              list and cleans up the memory associated with the\r
338  *              transport data structure.\r
339  */\r
340 int32_t Rm_transportUnregister(Rm_TransportHandle transportHandle)\r
341 {\r
342     Rm_Transport *transport = (Rm_Transport *)transportHandle;\r
343     Rm_Inst      *rmInst = (Rm_Inst *)transport->rmHandle;\r
344     int32_t       retVal = RM_OK;\r
345 \r
346     if (transportIsRegistered(transport->rmHandle, transport)) {\r
347         if ((transport->remoteInstType == Rm_instType_CLIENT_DELEGATE) ||\r
348             (transport->remoteInstType == Rm_instType_SERVER)) {\r
349             rmInst->registeredWithDelegateOrServer = RM_FALSE;\r
350         }\r
351         transportDelete(transport);\r
352     }\r
353     else {\r
354         retVal = RM_ERROR_TRANSPORT_HANDLE_DOES_NOT_EXIST;\r
355     }\r
356     return (retVal);\r
357 }\r
358 \r
359 /* FUNCTION PURPOSE: Returns a RM packet's service source instance name\r
360  ***********************************************************************\r
361  * DESCRIPTION: Returns the RM instance name from which the service\r
362  *              encapsulated in the RM packet originated.\r
363  */\r
364 int32_t Rm_receiveGetPktServiceSrcName(const Rm_Packet *pkt, char *serviceInstName, \r
365                                          int32_t charBufLen)\r
366 {\r
367     return(getPktSrcNames(pkt, NULL, serviceInstName, charBufLen));\r
368 }\r
369 \r
370 /* FUNCTION PURPOSE: Returns a RM packet's source instance name\r
371  ***********************************************************************\r
372  * DESCRIPTION: Returns the RM instance name from which the RM packet\r
373  *              originated.\r
374  */\r
375 int32_t Rm_receiveGetPktSrcName(const Rm_Packet *pkt, char *pktInstName, \r
376                                   int32_t charBufLen)\r
377 {\r
378     return(getPktSrcNames(pkt, pktInstName, NULL, charBufLen));\r
379 }\r
380 \r
381 /* FUNCTION PURPOSE: Receives RM packets\r
382  ***********************************************************************\r
383  * DESCRIPTION: The application provides RM packets received on the\r
384  *              application transports to RM via this API.  Function\r
385  *              can be called from polling or ISR contexts.  Assume \r
386  *              invoking application will free packet after this\r
387  *              function returns.\r
388  */\r
389 int32_t Rm_receivePacket(Rm_TransportHandle transportHandle, const Rm_Packet *pkt)\r
390 {\r\r\r
391     Rm_Transport   *transport = (Rm_Transport *)transportHandle;\r
392     Rm_Inst        *rmInst = (Rm_Inst *)transport->rmHandle;\r
393     Rm_Transaction *transaction;\r
394     int32_t         retVal = RM_OK;\r
395 \r
396     if (!transportIsRegistered(transport->rmHandle, transport)) {\r
397         retVal = RM_ERROR_TRANSPORT_HANDLE_DOES_NOT_EXIST;\r
398         goto errorExit;\r
399     }\r
400 \r
401     switch (pkt->pktType) {\r
402         case Rm_pktType_RESOURCE_REQUEST:\r
403         {\r
404             Rm_ResourceRequestPkt *resourceReqPkt = (Rm_ResourceRequestPkt *)pkt->data;\r
405 \r
406             transaction = rmTransactionQueueAdd(rmInst);\r
407             transaction->remoteOriginatingId = resourceReqPkt->requestId;\r
408             transaction->u.respTrans = transport;\r
409             if (resourceReqPkt->resourceReqType == Rm_resReqPktType_ALLOCATE_INIT) {\r
410                 transaction->type = Rm_service_RESOURCE_ALLOCATE_INIT;\r
411             }\r
412             else if (resourceReqPkt->resourceReqType == Rm_resReqPktType_ALLOCATE_USE) {\r
413                 transaction->type = Rm_service_RESOURCE_ALLOCATE_USE;\r
414             }\r
415             else if (resourceReqPkt->resourceReqType == Rm_resReqPktType_GET_STATUS) {\r
416                 transaction->type = Rm_service_RESOURCE_STATUS;\r
417             }\r
418             else if (resourceReqPkt->resourceReqType == Rm_resReqPktType_FREE) {\r
419                 transaction->type = Rm_service_RESOURCE_FREE;\r
420             }\r
421             else if (resourceReqPkt->resourceReqType == Rm_resReqPktType_GET_NAMED) {\r
422                 transaction->type = Rm_service_RESOURCE_GET_BY_NAME;\r
423             }            \r
424             rm_strncpy(transaction->serviceSrcInstName, resourceReqPkt->serviceSrcInstName, RM_NAME_MAX_CHARS);\r
425             transaction->state = RM_SERVICE_PROCESSING;\r
426             memcpy ((void *)&(transaction->resourceInfo), (void *)&(resourceReqPkt->resourceInfo),\r
427                     sizeof(Rm_ResourceInfo));\r
428             break;\r
429         }\r
430         case Rm_pktType_RESOURCE_RESPONSE:\r
431         {\r
432             Rm_ResourceResponsePkt *resourceRespPkt = (Rm_ResourceResponsePkt *)pkt->data;\r
433 \r
434             if (transaction = rmTransactionQueueFind(rmInst,resourceRespPkt->responseId)) {\r
435                 if ((transaction->state == RM_SERVICE_APPROVED_STATIC) &&\r
436                     (resourceRespPkt->requestState != RM_SERVICE_APPROVED)) {\r
437                     /* Lock the RM instance since service validated against static policy failed against \r
438                      * Server's global policy */\r
439                     rmInst->isLocked = RM_TRUE;\r
440                 }\r
441                 transaction->state = resourceRespPkt->requestState;\r
442 \r
443                 if ((transaction->state == RM_SERVICE_APPROVED) &&\r
444                     ((transaction->type == Rm_service_RESOURCE_ALLOCATE_INIT) ||\r
445                      (transaction->type == Rm_service_RESOURCE_ALLOCATE_USE) ||\r
446                      (transaction->type == Rm_service_RESOURCE_STATUS) ||\r
447                      (transaction->type == Rm_service_RESOURCE_GET_BY_NAME))) {\r
448                     memcpy ((void *)&(transaction->resourceInfo), (void *)&(resourceRespPkt->resourceInfo),\r
449                             sizeof(Rm_ResourceInfo));\r
450                 }\r
451                 else {\r
452                     /* Always copy owner count and instance allocation count */\r
453                     transaction->resourceInfo.ownerCount = resourceRespPkt->resourceInfo.ownerCount;\r
454                     transaction->resourceInfo.instAllocCount = resourceRespPkt->resourceInfo.instAllocCount;\r
455                 }\r
456             }\r
457             else {\r
458                 retVal = RM_ERROR_PKT_RESP_DOES_NOT_MATCH_ANY_REQ;\r
459                 goto errorExit;\r
460             }\r
461             break;\r
462         }\r
463         case Rm_pktType_NAMESERVER_REQUEST:\r
464         {\r
465             Rm_NsRequestPkt *nsRequestPkt = (Rm_NsRequestPkt *)pkt->data;\r
466 \r
467             transaction = rmTransactionQueueAdd(rmInst);\r
468             transaction->remoteOriginatingId = nsRequestPkt->requestId;\r
469             transaction->u.respTrans = transport;\r
470 \r
471             if (nsRequestPkt->nsRequestType == Rm_nsReqPktType_MAP_RESOURCE) {\r
472                 transaction->type = Rm_service_RESOURCE_MAP_TO_NAME;\r
473             }\r
474             else if (nsRequestPkt->nsRequestType == Rm_nsReqPktType_UNMAP_RESOURCE) {\r
475                 transaction->type = Rm_service_RESOURCE_UNMAP_NAME;\r
476             }\r
477 \r
478             rm_strncpy(transaction->serviceSrcInstName, nsRequestPkt->serviceSrcInstName, RM_NAME_MAX_CHARS);\r
479             transaction->state = RM_SERVICE_PROCESSING;\r
480             memcpy ((void *)&(transaction->resourceInfo), (void *)&(nsRequestPkt->resourceInfo),\r
481                     sizeof(Rm_ResourceInfo));           \r
482             break;\r
483         }\r
484         case Rm_pktType_NAMESERVER_RESPONSE:\r
485         {\r
486             Rm_NsResponsePkt *nsResponsePkt = (Rm_NsResponsePkt *)pkt->data;\r
487 \r
488             if (transaction = rmTransactionQueueFind(rmInst, nsResponsePkt->responseId)) {\r
489                 if ((transaction->state == RM_SERVICE_APPROVED_STATIC) &&\r
490                     (nsResponsePkt->requestState != RM_SERVICE_APPROVED)) {\r
491                     /* Lock the RM instance since service validated against static policy failed against \r
492                      * Server's global policy */                    \r
493                     rmInst->isLocked = RM_TRUE;\r
494                 }                \r
495                 transaction->state = nsResponsePkt->requestState;            \r
496             }\r
497             else {\r
498                 retVal = RM_ERROR_PKT_RESP_DOES_NOT_MATCH_ANY_REQ;\r
499                 goto errorExit;\r
500             }\r
501             break;\r
502         }\r
503         default:\r
504             retVal = RM_ERROR_RECEIVED_INVALID_PACKET_TYPE;\r
505             goto errorExit;\r
506     }\r
507 \r
508     /* Process received transaction */\r
509     rmProcessRouter(rmInst, transaction);   \r
510 errorExit:\r
511     return(retVal);\r
512 }\r
513 \r