]> Gitweb @ Texas Instruments - Open Source Git Repositories - git.TI.com/gitweb - keystone-rtos/rm-lld.git/blob - src/rm_transport.c
NOTICE OF RELOCATION
[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-2015, 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         } else {\r
86             rmInst->transports = newTransport;\r
87         }\r
88     }\r
89     return(newTransport);\r
90 }\r
91 \r
92 /* FUNCTION PURPOSE: Tests if a transport is registered to an instance\r
93  ***********************************************************************\r
94  * DESCRIPTION: Returns TRUE if the supplied transport is found in\r
95  *              the instance transport list.  Otherwise, returns FALSE\r
96  */\r
97 static int transportIsRegistered(Rm_Handle rmHandle, Rm_Transport *transport)\r
98 {\r
99     Rm_Inst      *rmInst = (Rm_Inst *)rmHandle;\r
100     Rm_Transport *transportList = (Rm_Transport *)rmInst->transports;\r
101 \r
102     while (transportList) {\r
103         if (transportList == transport) {\r
104             return(RM_TRUE);\r
105         }\r
106         transportList = transportList->nextTransport;\r
107     }\r
108     return(RM_FALSE);\r
109 }\r
110 \r
111 /* FUNCTION PURPOSE: Deletes a transport\r
112  ***********************************************************************\r
113  * DESCRIPTION: Removes a transport from an instance transport list\r
114  *              and then frees the memory associated with the transport\r
115  *              data structure\r
116  */\r
117 static void transportDelete(Rm_Transport *transport)\r
118 {\r
119     Rm_Inst      *rmInst = (Rm_Inst *)transport->rmHandle;\r
120     Rm_Transport *transportList = (Rm_Transport *)rmInst->transports;\r
121     Rm_Transport *prevTransport = NULL;\r
122 \r
123     /* Get previous transport in list */\r
124     while (transportList) {\r
125         if (transportList == transport) {\r
126             break;\r
127         }\r
128         prevTransport = transportList;\r
129         transportList = transportList->nextTransport;\r
130     }\r
131 \r
132     if (prevTransport == NULL) {\r
133          rmInst->transports = transport->nextTransport;\r
134     } else {\r
135          prevTransport->nextTransport = transport->nextTransport;\r
136     }\r
137     Rm_osalFree((void *)transport, sizeof(Rm_Transport));\r
138 }\r
139 \r
140 /* FUNCTION PURPOSE: Returns RM packet source instance\r
141  ***********************************************************************\r
142  * DESCRIPTION: Can return the RM instance name for one of two things:\r
143  *                  - RM instance from which provided RM packet originated\r
144  *                  - RM instance from which the service request contained\r
145  *                    in the provided RM packet originated\r
146  */\r
147 static int32_t getPktSrcNames(const Rm_Packet *pkt, char *pktSrc,\r
148                               char *serviceSrc, int32_t bufLen)\r
149 {\r
150     int32_t retVal = RM_OK;\r
151 \r
152     if (bufLen != RM_NAME_MAX_CHARS) {\r
153         retVal = RM_ERROR_SRC_NAME_BUF_INVALID_SIZE;\r
154     } else {\r
155         switch (pkt->pktType) {\r
156             case Rm_pktType_RESOURCE_REQUEST:\r
157             {\r
158                 Rm_ResourceRequestPkt *resourceReqPkt = (Rm_ResourceRequestPkt *)pkt->data;\r
159 \r
160                 if (pktSrc){\r
161                     rm_strncpy(pktSrc, resourceReqPkt->pktSrcInstName,\r
162                                RM_NAME_MAX_CHARS);\r
163                 }\r
164 \r
165                 if (serviceSrc) {\r
166                     rm_strncpy(serviceSrc, resourceReqPkt->serviceSrcInstName,\r
167                                RM_NAME_MAX_CHARS);\r
168                 }\r
169                 break;\r
170             }\r
171             case Rm_pktType_NAMESERVER_REQUEST:\r
172             {\r
173                 Rm_NsRequestPkt *nsRequestPkt = (Rm_NsRequestPkt *)pkt->data;\r
174 \r
175                 if (pktSrc){\r
176                     rm_strncpy(pktSrc, nsRequestPkt->pktSrcInstName,\r
177                                RM_NAME_MAX_CHARS);\r
178                 }\r
179 \r
180                 if (serviceSrc) {\r
181                     rm_strncpy(serviceSrc, nsRequestPkt->serviceSrcInstName,\r
182                                RM_NAME_MAX_CHARS);\r
183                 }\r
184                 break;\r
185             }\r
186             case Rm_pktType_RESOURCE_RESPONSE:\r
187             case Rm_pktType_NAMESERVER_RESPONSE:\r
188             default:\r
189                 retVal = RM_ERROR_PKT_AND_SERVICE_SRC_NOT_AVAIL;\r
190                 break;\r
191         }\r
192     }\r
193 \r
194     return(retVal);\r
195 }\r
196 \r
197 /**********************************************************************\r
198  ********************** Internal Functions ****************************\r
199  **********************************************************************/\r
200 \r
201 /* FUNCTION PURPOSE: Finds a transport based on remote inst type\r
202  ***********************************************************************\r
203  * DESCRIPTION: Returns a pointer to the transport within an instance's\r
204  *              transport list that matches the provided remote\r
205  *              instance type.  NULL is returned if no transports in \r
206  *              the list match the remote instance type.\r
207  */\r
208 Rm_Transport *rmTransportFindRemoteInstType(Rm_Transport *transports,\r
209                                             Rm_InstType remoteInstType)\r
210 {\r
211     while (transports) {\r
212         if (transports->remoteInstType == remoteInstType) {\r
213             break;\r
214         }\r
215         transports = transports->nextTransport;\r
216     }\r
217     return(transports);\r
218 }\r
219 \r
220 /**********************************************************************\r
221  ********************* Application visible APIs ***********************\r
222  **********************************************************************/\r
223 \r
224 /* FUNCTION PURPOSE: Registers an app transport with a RM instance\r
225  ***********************************************************************\r
226  * DESCRIPTION: Returns a transport handle to the application that\r
227  *              has been registered with an RM instance.  The handle\r
228  *              is used by the application to route packets to the\r
229  *              proper RM instance's based on the application\r
230  *              transport receive code.  The handle is also used\r
231  *              internally by RM to route request and response \r
232  *              packets to the correct application transports. NULL\r
233  *              is returned for the transport handle if any errors\r
234  *              are encountered.\r
235  */\r
236 Rm_TransportHandle Rm_transportRegister(const Rm_TransportCfg *transportCfg,\r
237                                         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     void         *mtKey;\r
243 \r
244     *result = RM_OK;\r
245 \r
246     RM_SS_INST_INV_ENTER_CS(rmInst, key);\r
247     if (rmInst->mtSemObj) {\r
248         mtKey = Rm_osalMtCsEnter(rmInst->mtSemObj);\r
249     }\r
250 \r
251     /* Shared servers and clients cannot connect to anyone */\r
252     if ((rmInst->instType == Rm_instType_SHARED_SERVER) ||\r
253         (rmInst->instType == Rm_instType_SHARED_CLIENT)){\r
254         *result = RM_ERROR_SHARED_INSTANCE_CANNOT_REG_TRANS;\r
255         goto errorExit;\r
256     }\r
257 \r
258     /* No one can connect to a shared server\r
259      * RM Servers cannot connect to other Servers.  \r
260      * RM Client Delegates cannot connect to other Client Delegates.\r
261      * RM Clients cannot connect to other Clients */\r
262     if ((transportCfg->remoteInstType == Rm_instType_SHARED_SERVER) ||\r
263         ((rmInst->instType == Rm_instType_SERVER) &&\r
264          (transportCfg->remoteInstType == Rm_instType_SERVER)) ||\r
265         ((rmInst->instType == Rm_instType_CLIENT_DELEGATE) &&\r
266          (transportCfg->remoteInstType == Rm_instType_CLIENT_DELEGATE)) ||\r
267         ((rmInst->instType == Rm_instType_CLIENT) &&\r
268          (transportCfg->remoteInstType == Rm_instType_CLIENT))) {\r
269         *result = RM_ERROR_INVALID_REMOTE_INST_TYPE;\r
270         goto errorExit;\r
271     }\r
272 \r
273     /* Verify Clients are not registering with more than one Client Delegate or\r
274      * Server. And that Client Delegate is not registering with more than one\r
275      * Server. */\r
276     if (rmInst->registeredWithDelegateOrServer &&\r
277         (((rmInst->instType == Rm_instType_CLIENT) &&\r
278           (transportCfg->remoteInstType == Rm_instType_CLIENT_DELEGATE)) ||\r
279          ((rmInst->instType == Rm_instType_CLIENT_DELEGATE) &&\r
280           (transportCfg->remoteInstType == Rm_instType_SERVER)))) {\r
281         *result = RM_ERROR_ALREADY_REGD_SERVER_OR_CD;\r
282         goto errorExit;\r
283     }\r
284 \r
285     if (!transportCfg->transportCallouts.rmAllocPkt) {\r
286         *result = RM_ERROR_TRANSPORT_ALLOC_PKT_NOT_REGD;\r
287         goto errorExit;\r
288     }\r
289     if (!transportCfg->transportCallouts.rmSendPkt) {\r
290         *result = RM_ERROR_TRANSPORT_SEND_NOT_REGD;\r
291         goto errorExit;\r
292     }\r
293 \r
294     transport = transportAdd(transportCfg);\r
295     if ((transport->remoteInstType == Rm_instType_CLIENT_DELEGATE) ||\r
296         (transport->remoteInstType == Rm_instType_SERVER)) {\r
297         rmInst->registeredWithDelegateOrServer = RM_TRUE;\r
298     }\r
299     \r
300 errorExit:\r
301     if (rmInst->mtSemObj) {\r
302         Rm_osalMtCsExit(rmInst->mtSemObj, mtKey);\r
303     }\r
304     RM_SS_INST_WB_EXIT_CS(rmInst, key);\r
305     return ((Rm_TransportHandle) transport);\r
306 }\r
307 \r
308 /* FUNCTION PURPOSE: Reconfigures an instance's transport handle\r
309  ***********************************************************************\r
310  * DESCRIPTION: Reconfigures a transport handle based on the provided\r
311  *              configuration parameters if it exists within the \r
312  *              instance.\r
313  */\r
314 int32_t Rm_transportReconfig(Rm_TransportHandle transportHandle,\r
315                              const Rm_TransportReCfg *reCfg)\r
316 {\r
317     Rm_Transport *transport = (Rm_Transport *)transportHandle;\r
318     Rm_Inst      *rmInst = (Rm_Inst *)transport->rmHandle;\r
319     void         *key;\r
320     void         *mtKey;\r
321     int32_t       retVal = RM_OK;\r
322 \r
323     RM_SS_INST_INV_ENTER_CS(rmInst, key);\r
324     if (rmInst->mtSemObj) {\r
325         mtKey = Rm_osalMtCsEnter(rmInst->mtSemObj);\r
326     }\r
327 \r
328     if (transportIsRegistered(transport->rmHandle, transport)) {\r
329         /* Reconfigure existing transport's appTransportHandle.  Used in cases\r
330          * where instances running on same core connected by function call. */\r
331         transport->appTransportHandle = reCfg->appTransportHandle;\r
332 \r
333         if (reCfg->transportCallouts.rmAllocPkt) {\r
334             transport->callouts.rmAllocPkt = reCfg->transportCallouts.rmAllocPkt;\r
335         }\r
336         if (reCfg->transportCallouts.rmSendPkt) {\r
337             transport->callouts.rmSendPkt = reCfg->transportCallouts.rmSendPkt;\r
338         }\r
339     } else {\r
340         retVal = RM_ERROR_TRANSPORT_HANDLE_DOES_NOT_EXIST;\r
341     }\r
342 \r
343     if (rmInst->mtSemObj) {\r
344         Rm_osalMtCsExit(rmInst->mtSemObj, mtKey);\r
345     }\r
346     RM_SS_INST_WB_EXIT_CS(rmInst, key);\r
347     return(retVal);\r
348 }\r
349 \r
350 /* FUNCTION PURPOSE: Unregisters an app transport from a RM instance\r
351  ***********************************************************************\r
352  * DESCRIPTION: Deletes a registered transport from the transport\r
353  *              list and cleans up the memory associated with the\r
354  *              transport data structure.\r
355  */\r
356 int32_t Rm_transportUnregister(Rm_TransportHandle transportHandle)\r
357 {\r
358     Rm_Transport *transport = (Rm_Transport *)transportHandle;\r
359     Rm_Inst      *rmInst = (Rm_Inst *)transport->rmHandle;\r
360     int32_t       retVal = RM_OK;\r
361 \r
362     if (transportIsRegistered(transport->rmHandle, transport)) {\r
363         if ((transport->remoteInstType == Rm_instType_CLIENT_DELEGATE) ||\r
364             (transport->remoteInstType == Rm_instType_SERVER)) {\r
365             rmInst->registeredWithDelegateOrServer = RM_FALSE;\r
366         }\r
367         transportDelete(transport);\r
368     } else {\r
369         retVal = RM_ERROR_TRANSPORT_HANDLE_DOES_NOT_EXIST;\r
370     }\r
371     return(retVal);\r
372 }\r
373 \r
374 /* FUNCTION PURPOSE: Returns a RM packet's service source instance name\r
375  ***********************************************************************\r
376  * DESCRIPTION: Returns the RM instance name from which the service\r
377  *              encapsulated in the RM packet originated.\r
378  */\r
379 int32_t Rm_receiveGetPktServiceSrcName(const Rm_Packet *pkt,\r
380                                        char *serviceInstName,\r
381                                        int32_t charBufLen)\r
382 {\r
383     return(getPktSrcNames(pkt, NULL, serviceInstName, charBufLen));\r
384 }\r
385 \r
386 /* FUNCTION PURPOSE: Returns a RM packet's source instance name\r
387  ***********************************************************************\r
388  * DESCRIPTION: Returns the RM instance name from which the RM packet\r
389  *              originated.\r
390  */\r
391 int32_t Rm_receiveGetPktSrcName(const Rm_Packet *pkt, char *pktInstName,\r
392                                 int32_t charBufLen)\r
393 {\r
394     return(getPktSrcNames(pkt, pktInstName, NULL, charBufLen));\r
395 }\r
396 \r
397 /* FUNCTION PURPOSE: Receives RM packets\r
398  ***********************************************************************\r
399  * DESCRIPTION: The application provides RM packets received on the\r
400  *              application transports to RM via this API.  Function\r
401  *              can be called from polling or ISR contexts.  Assume \r
402  *              invoking application will free packet after this\r
403  *              function returns.\r
404  */\r
405 int32_t Rm_receivePacket(Rm_TransportHandle transportHandle,\r
406                          const Rm_Packet *pkt)\r
407 {\r\r\r
408     Rm_Transport   *transport = (Rm_Transport *)transportHandle;\r
409     Rm_Inst        *rmInst = (Rm_Inst *)transport->rmHandle;\r
410     Rm_Transaction *transaction;\r
411     int32_t         retVal = RM_OK;\r
412 \r
413     if (!transportIsRegistered(transport->rmHandle, transport)) {\r
414         retVal = RM_ERROR_TRANSPORT_HANDLE_DOES_NOT_EXIST;\r
415         goto errorExit;\r
416     }\r
417 \r
418     switch (pkt->pktType) {\r
419         case Rm_pktType_RESOURCE_REQUEST:\r
420         {\r
421             Rm_ResourceRequestPkt *resourceReqPkt = (Rm_ResourceRequestPkt *)pkt->data;\r
422 \r
423             transaction = rmTransactionQueueAdd(rmInst);\r
424             transaction->remoteOriginatingId = resourceReqPkt->requestId;\r
425             transaction->u.respTrans = transport;\r
426             if (resourceReqPkt->resourceReqType ==\r
427                 Rm_resReqPktType_ALLOCATE_INIT) {\r
428                 transaction->type = Rm_service_RESOURCE_ALLOCATE_INIT;\r
429             } else if (resourceReqPkt->resourceReqType ==\r
430                        Rm_resReqPktType_ALLOCATE_USE) {\r
431                 transaction->type = Rm_service_RESOURCE_ALLOCATE_USE;\r
432             } else if (resourceReqPkt->resourceReqType ==\r
433                        Rm_resReqPktType_GET_STATUS) {\r
434                 transaction->type = Rm_service_RESOURCE_STATUS;\r
435             } else if (resourceReqPkt->resourceReqType ==\r
436                        Rm_resReqPktType_FREE) {\r
437                 transaction->type = Rm_service_RESOURCE_FREE;\r
438             } else if (resourceReqPkt->resourceReqType ==\r
439                        Rm_resReqPktType_GET_NAMED) {\r
440                 transaction->type = Rm_service_RESOURCE_GET_BY_NAME;\r
441             } else {\r
442                 retVal = RM_ERROR_RECEIVED_INVALID_PACKET_TYPE;\r
443                 goto errorExit;\r
444             }\r
445             rm_strncpy(transaction->serviceSrcInstName,\r
446                        resourceReqPkt->serviceSrcInstName, RM_NAME_MAX_CHARS);\r
447             transaction->state = RM_SERVICE_PROCESSING;\r
448             memcpy((void *)&(transaction->resourceInfo),\r
449                    (void *)&(resourceReqPkt->resourceInfo),\r
450                    sizeof(Rm_ResourceInfo));\r
451             break;\r
452         }\r
453         case Rm_pktType_RESOURCE_RESPONSE:\r
454         {\r
455             Rm_ResourceResponsePkt *resourceRespPkt = (Rm_ResourceResponsePkt *)pkt->data;\r
456 \r
457             if ((transaction = rmTransactionQueueFind(rmInst,\r
458                                                 resourceRespPkt->responseId))) {\r
459                 if ((transaction->state == RM_SERVICE_APPROVED_STATIC) &&\r
460                     (resourceRespPkt->requestState != RM_SERVICE_APPROVED)) {\r
461                     /* Lock the RM instance since service validated against\r
462                      * static policy failed against Server's global policy */\r
463                     rmInst->isLocked = RM_TRUE;\r
464                 }\r
465                 transaction->state = resourceRespPkt->requestState;\r
466 \r
467                 if ((transaction->state == RM_SERVICE_APPROVED) &&\r
468                     ((transaction->type == Rm_service_RESOURCE_ALLOCATE_INIT) ||\r
469                      (transaction->type == Rm_service_RESOURCE_ALLOCATE_USE) ||\r
470                      (transaction->type == Rm_service_RESOURCE_STATUS) ||\r
471                      (transaction->type == Rm_service_RESOURCE_GET_BY_NAME))) {\r
472                     memcpy((void *)&(transaction->resourceInfo),\r
473                            (void *)&(resourceRespPkt->resourceInfo),\r
474                            sizeof(Rm_ResourceInfo));\r
475                 } else {\r
476                     /* Always copy owner count and instance allocation count */\r
477                     transaction->resourceInfo.ownerCount = resourceRespPkt->resourceInfo.ownerCount;\r
478                     transaction->resourceInfo.instAllocCount = resourceRespPkt->resourceInfo.instAllocCount;\r
479                 }\r
480             } else {\r
481                 retVal = RM_ERROR_PKT_RESP_DOES_NOT_MATCH_ANY_REQ;\r
482                 goto errorExit;\r
483             }\r
484             break;\r
485         }\r
486         case Rm_pktType_NAMESERVER_REQUEST:\r
487         {\r
488             Rm_NsRequestPkt *nsRequestPkt = (Rm_NsRequestPkt *)pkt->data;\r
489 \r
490             transaction = rmTransactionQueueAdd(rmInst);\r
491             transaction->remoteOriginatingId = nsRequestPkt->requestId;\r
492             transaction->u.respTrans = transport;\r
493 \r
494             if (nsRequestPkt->nsRequestType == Rm_nsReqPktType_MAP_RESOURCE) {\r
495                 transaction->type = Rm_service_RESOURCE_MAP_TO_NAME;\r
496             } else if (nsRequestPkt->nsRequestType ==\r
497                        Rm_nsReqPktType_UNMAP_RESOURCE) {\r
498                 transaction->type = Rm_service_RESOURCE_UNMAP_NAME;\r
499             }\r
500 \r
501             rm_strncpy(transaction->serviceSrcInstName,\r
502                        nsRequestPkt->serviceSrcInstName, RM_NAME_MAX_CHARS);\r
503             transaction->state = RM_SERVICE_PROCESSING;\r
504             memcpy((void *)&(transaction->resourceInfo),\r
505                    (void *)&(nsRequestPkt->resourceInfo),\r
506                     sizeof(Rm_ResourceInfo));\r
507             break;\r
508         }\r
509         case Rm_pktType_NAMESERVER_RESPONSE:\r
510         {\r
511             Rm_NsResponsePkt *nsResponsePkt = (Rm_NsResponsePkt *)pkt->data;\r
512 \r
513             if ((transaction = rmTransactionQueueFind(rmInst,\r
514                                                   nsResponsePkt->responseId))) {\r
515                 if ((transaction->state == RM_SERVICE_APPROVED_STATIC) &&\r
516                     (nsResponsePkt->requestState != RM_SERVICE_APPROVED)) {\r
517                     /* Lock the RM instance since service validated against\r
518                      * static policy failed against Server's global policy */\r
519                     rmInst->isLocked = RM_TRUE;\r
520                 }\r
521                 transaction->state = nsResponsePkt->requestState;\r
522             } else {\r
523                 retVal = RM_ERROR_PKT_RESP_DOES_NOT_MATCH_ANY_REQ;\r
524                 goto errorExit;\r
525             }\r
526             break;\r
527         }\r
528         default:\r
529             retVal = RM_ERROR_RECEIVED_INVALID_PACKET_TYPE;\r
530             goto errorExit;\r
531     }\r
532 \r
533     /* Process received transaction */\r
534     rmProcessRouter(rmInst, transaction);\r
535 errorExit:\r
536     return(retVal);\r
537 }\r
538 \r