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-2013, 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 /* Standard includes */\r
43 #include <string.h>\r
44 #include <stdbool.h>\r
45 \r
46 /* RM external includes */\r
47 #include <ti/drv/rm/rm.h>\r
48 #include <ti/drv/rm/rm_transport.h>\r
49 \r
50 /* RM internal includes */\r
51 #include <ti/drv/rm/include/rm_loc.h>\r
52 #include <ti/drv/rm/include/rm_transportloc.h>\r
53 \r
54 /* RM OSAL layer */\r
55 #include <rm_osal.h>\r
56 \r
57 /**********************************************************************\r
58 ************************ Local Functions *****************************\r
59 **********************************************************************/\r
60 \r
61 /* FUNCTION PURPOSE: Adds a transport\r
62 ***********************************************************************\r
63 * DESCRIPTION: Returns a pointer to a transport structure that\r
64 * was created, initialized, and added to the \r
65 * instance transport list.\r
66 */\r
67 static Rm_Transport *transportAdd(const Rm_TransportCfg *transportCfg)\r
68 {\r
69 Rm_Inst *rmInst = (Rm_Inst *) transportCfg->rmHandle;\r
70 Rm_Transport *transports = rmInst->transports;\r
71 Rm_Transport *newTransport = NULL;\r
72 \r
73 newTransport = Rm_osalMalloc (sizeof(Rm_Transport));\r
74 memset((void *)newTransport, 0, sizeof(Rm_Transport));\r
75 \r
76 if (newTransport) {\r
77 newTransport->rmHandle = transportCfg->rmHandle;\r
78 newTransport->appTransportHandle = transportCfg->appTransportHandle;\r
79 newTransport->remoteInstType = transportCfg->remoteInstType;\r
80 strncpy(newTransport->remoteInstName, transportCfg->remoteInstName, RM_NAME_MAX_CHARS);\r
81 newTransport->nextTransport = NULL;\r
82 \r
83 if (transports) {\r
84 while (transports->nextTransport) {\r
85 transports = transports->nextTransport;\r
86 }\r
87 transports->nextTransport = newTransport;\r
88 }\r
89 else {\r
90 rmInst->transports = (void *)newTransport;\r
91 }\r
92 }\r
93 return (newTransport);\r
94 }\r
95 \r
96 /* FUNCTION PURPOSE: Tests if a transport is registered to an instance\r
97 ***********************************************************************\r
98 * DESCRIPTION: Returns TRUE if the supplied transport is found in\r
99 * the instance transport list. Otherwise, returns FALSE\r
100 */\r
101 static bool transportIsRegistered(Rm_Handle rmHandle, Rm_Transport *transport)\r
102 {\r
103 Rm_Inst *rmInst = (Rm_Inst *)rmHandle;\r
104 Rm_Transport *transportList = (Rm_Transport *)rmInst->transports;\r
105 \r
106 while (transportList) {\r
107 if (transportList == transport) {\r
108 return(true); \r
109 }\r
110 transportList = transportList->nextTransport;\r
111 }\r
112 return (false);\r
113 }\r
114 \r
115 /* FUNCTION PURPOSE: Deletes a transport\r
116 ***********************************************************************\r
117 * DESCRIPTION: Removes a transport from an instance transport list\r
118 * and then frees the memory associated with the transport\r
119 * data structure\r
120 */\r
121 static void transportDelete(Rm_Transport *transport)\r
122 {\r
123 Rm_Inst *rmInst = (Rm_Inst *)transport->rmHandle;\r
124 Rm_Transport *transportList = (Rm_Transport *)rmInst->transports;\r
125 Rm_Transport *prevTransport = NULL;\r
126 \r
127 /* Get previous transport in list */\r
128 while (transportList) {\r
129 if (transportList == transport) {\r
130 break; \r
131 }\r
132 prevTransport = transportList;\r
133 transportList = transportList->nextTransport;\r
134 }\r
135 \r
136 if (prevTransport == NULL) {\r
137 rmInst->transports = (void *)transport->nextTransport;\r
138 }\r
139 else {\r
140 prevTransport->nextTransport = transport->nextTransport;\r
141 }\r
142 Rm_osalFree((void *)transport, sizeof(Rm_Transport));\r
143 }\r
144 \r
145 /**********************************************************************\r
146 ********************** Internal Functions ****************************\r
147 **********************************************************************/\r
148 \r
149 /* FUNCTION PURPOSE: Finds a transport based on remote inst name\r
150 ***********************************************************************\r
151 * DESCRIPTION: Returns a pointer to the transport within an instance's\r
152 * transport list that matches the provided remote\r
153 * instance name. NULL is returned if no transports in \r
154 * the list match the remote instance name.\r
155 */\r
156 Rm_Transport *rmTransportFindRemoteName(Rm_Transport *transports, char *remoteName)\r
157 {\r
158 while (transports) {\r
159 if (strncmp(transports->remoteInstName, remoteName, RM_NAME_MAX_CHARS) == 0) {\r
160 break; \r
161 }\r
162 transports = transports->nextTransport;\r
163 }\r
164 return (transports);\r
165 }\r
166 \r
167 /* FUNCTION PURPOSE: Finds a transport based on remote inst type\r
168 ***********************************************************************\r
169 * DESCRIPTION: Returns a pointer to the transport within an instance's\r
170 * transport list that matches the provided remote\r
171 * instance type. NULL is returned if no transports in \r
172 * the list match the remote instance type.\r
173 */\r
174 Rm_Transport *rmTransportFindRemoteInstType(Rm_Transport *transports, Rm_InstType remoteInstType)\r
175 {\r
176 while (transports) {\r
177 if (transports->remoteInstType == remoteInstType) {\r
178 break; \r
179 }\r
180 transports = transports->nextTransport;\r
181 }\r
182 return (transports);\r
183 }\r
184 \r
185 /* FUNCTION PURPOSE: Creates a resource request packet\r
186 ***********************************************************************\r
187 * DESCRIPTION: Returns a RM packet handle that points to a RM\r
188 * resource request packet that has been prepared\r
189 * for sending to another RM instance. The packet\r
190 * is allocated via the rmAllocPkt API using the\r
191 * appTransport handle provided by the application\r
192 */\r
193 Rm_PacketHandle rmTransportCreateResourceReqPkt(Rm_Inst *rmInst, Rm_AppTransportHandle appTransport,\r
194 Rm_Transaction *transaction)\r
195 {\r
196 Rm_Packet *rmPkt = NULL;\r
197 Rm_PacketHandle pktHandle = NULL;\r
198 Rm_ResourceRequestPkt *resourceReqPkt = NULL;\r
199 \r
200 if (rmInst->transportCallouts.rmAllocPkt) {\r
201 if ((rmPkt = rmInst->transportCallouts.rmAllocPkt(appTransport, \r
202 sizeof(Rm_Packet),\r
203 &pktHandle)) == NULL) {\r
204 transaction->state = RM_ERROR_TRANSPORT_ALLOC_PKT_ERROR;\r
205 return (NULL);\r
206 }\r
207 \r
208 rmPkt->pktType = Rm_pktType_RESOURCE_REQUEST;\r
209 resourceReqPkt = (Rm_ResourceRequestPkt *) rmPkt->data;\r
210 resourceReqPkt->requestId = transaction->localId;\r
211 if (transaction->type == Rm_service_RESOURCE_ALLOCATE_INIT) {\r
212 resourceReqPkt->resourceReqType = Rm_resReqPktType_ALLOCATE_INIT;\r
213 }\r
214 else if (transaction->type == Rm_service_RESOURCE_ALLOCATE_USE) {\r
215 resourceReqPkt->resourceReqType = Rm_resReqPktType_ALLOCATE_USE;\r
216 } \r
217 else if (transaction->type == Rm_service_RESOURCE_FREE) {\r
218 resourceReqPkt->resourceReqType = Rm_resReqPktType_FREE;\r
219 }\r
220 else if (transaction->type == Rm_service_RESOURCE_GET_BY_NAME) {\r
221 resourceReqPkt->resourceReqType = Rm_resReqPktType_GET_NAMED;\r
222 }\r
223 strncpy(resourceReqPkt->pktSrcInstName, rmInst->instName, RM_NAME_MAX_CHARS);\r
224 strncpy(resourceReqPkt->serviceSrcInstName, transaction->serviceSrcInstName, RM_NAME_MAX_CHARS);\r
225 memcpy ((void *)&(resourceReqPkt->resourceInfo), (void *)&(transaction->resourceInfo),\r
226 sizeof(Rm_ResourceInfo));\r
227 }\r
228 else {\r
229 transaction->state = RM_ERROR_TRANSPORT_ALLOC_PKT_NOT_REGD;\r
230 } \r
231 \r
232 return (pktHandle);\r
233 }\r
234 \r
235 /* FUNCTION PURPOSE: Creates a resource response packet\r
236 ***********************************************************************\r
237 * DESCRIPTION: Returns a RM packet handle that points to a RM\r
238 * resource response packet that has been prepared\r
239 * for sending to another RM instance. The packet\r
240 * is allocated via the rmAllocPkt API using the\r
241 * appTransport handle provided by the application\r
242 */\r
243 Rm_PacketHandle rmTransportCreateResourceResponsePkt(Rm_Inst *rmInst, Rm_AppTransportHandle appTransport,\r
244 Rm_Transaction *transaction)\r
245 {\r
246 Rm_Packet *rmPkt = NULL;\r
247 Rm_PacketHandle pktHandle = NULL;\r
248 Rm_ResourceResponsePkt *resourceRespPkt = NULL;\r
249 \r
250 if (rmInst->transportCallouts.rmAllocPkt) {\r
251 if ((rmPkt = rmInst->transportCallouts.rmAllocPkt(appTransport, \r
252 sizeof(Rm_Packet),\r
253 &pktHandle)) == NULL) {\r
254 transaction->state = RM_ERROR_TRANSPORT_ALLOC_PKT_ERROR;\r
255 return (NULL);\r
256 }\r
257 \r
258 rmPkt->pktType = Rm_pktType_RESOURCE_RESPONSE; \r
259 resourceRespPkt = (Rm_ResourceResponsePkt *)rmPkt->data;\r
260 resourceRespPkt->responseId = transaction->remoteOriginatingId;\r
261 resourceRespPkt->requestState = transaction->state;\r
262 memcpy ((void *)&(resourceRespPkt->resourceInfo), (void *)&(transaction->resourceInfo),\r
263 sizeof(Rm_ResourceInfo));\r
264 }\r
265 else {\r
266 transaction->state = RM_ERROR_TRANSPORT_ALLOC_PKT_NOT_REGD;\r
267 } \r
268 \r
269 return (pktHandle);\r
270 }\r
271 \r
272 /* FUNCTION PURPOSE: Creates a NameServer request packet\r
273 ***********************************************************************\r
274 * DESCRIPTION: Returns a RM packet handle that points to a RM\r
275 * NameServer request packet that has been prepared\r
276 * for sending to another RM instance. The packet\r
277 * is allocated via the rmAllocPkt API using the\r
278 * appTransport handle provided by the application\r
279 */\r
280 Rm_PacketHandle rmTransportCreateNsRequestPkt(Rm_Inst *rmInst, Rm_AppTransportHandle appTransport,\r
281 Rm_Transaction *transaction)\r
282 {\r
283 Rm_Packet *rmPkt = NULL;\r
284 Rm_PacketHandle pktHandle = NULL; \r
285 Rm_NsRequestPkt *nsReqPkt = NULL;\r
286 \r
287 if (rmInst->transportCallouts.rmAllocPkt) {\r
288 if ((rmPkt = rmInst->transportCallouts.rmAllocPkt(appTransport, \r
289 sizeof(Rm_Packet),\r
290 &pktHandle)) == NULL) {\r
291 transaction->state = RM_ERROR_TRANSPORT_ALLOC_PKT_ERROR;\r
292 return (NULL);\r
293 }\r
294 \r
295 rmPkt->pktType = Rm_pktType_NAMESERVER_REQUEST; \r
296 nsReqPkt = (Rm_NsRequestPkt *)rmPkt->data;\r
297 nsReqPkt->requestId = transaction->localId;\r
298 if (transaction->type == Rm_service_RESOURCE_MAP_TO_NAME) {\r
299 nsReqPkt->nsRequestType = Rm_nsReqPktType_MAP_RESOURCE;\r
300 }\r
301 else if (transaction->type == Rm_service_RESOURCE_UNMAP_NAME) {\r
302 nsReqPkt->nsRequestType = Rm_nsReqPktType_UNMAP_RESOURCE;\r
303 }\r
304 strncpy(nsReqPkt->pktSrcInstName, rmInst->instName, RM_NAME_MAX_CHARS);\r
305 strncpy(nsReqPkt->serviceSrcInstName, transaction->serviceSrcInstName, RM_NAME_MAX_CHARS);\r
306 memcpy ((void *)&(nsReqPkt->resourceInfo), (void *)&(transaction->resourceInfo),\r
307 sizeof(Rm_ResourceInfo));\r
308 }\r
309 else {\r
310 transaction->state = RM_ERROR_TRANSPORT_ALLOC_PKT_NOT_REGD;\r
311 } \r
312 \r
313 return (pktHandle);\r
314 }\r
315 \r
316 /* FUNCTION PURPOSE: Creates a NameServer response packet\r
317 ***********************************************************************\r
318 * DESCRIPTION: Returns a RM packet handle that points to a RM\r
319 * NameServer response packet that has been prepared\r
320 * for sending to another RM instance. The packet\r
321 * is allocated via the rmAllocPkt API using the\r
322 * appTransport handle provided by the application\r
323 */\r
324 Rm_PacketHandle rmTransportCreateNsResponsePkt(Rm_Inst *rmInst, Rm_AppTransportHandle appTransport,\r
325 Rm_Transaction *transaction)\r
326 {\r
327 Rm_Packet *rmPkt = NULL;\r
328 Rm_PacketHandle pktHandle = NULL;\r
329 Rm_NsResponsePkt *nsRespPkt = NULL;\r
330 \r
331 if (rmInst->transportCallouts.rmAllocPkt) {\r
332 if ((rmPkt = rmInst->transportCallouts.rmAllocPkt(appTransport, \r
333 sizeof(Rm_Packet),\r
334 &pktHandle)) == NULL) {\r
335 transaction->state = RM_ERROR_TRANSPORT_ALLOC_PKT_ERROR;\r
336 return (NULL);\r
337 }\r
338 \r
339 rmPkt->pktType = Rm_pktType_NAMESERVER_RESPONSE; \r
340 nsRespPkt = (Rm_NsResponsePkt *)rmPkt->data;\r
341 nsRespPkt->responseId = transaction->remoteOriginatingId;\r
342 nsRespPkt->requestState = transaction->state;\r
343 }\r
344 else {\r
345 transaction->state = RM_ERROR_TRANSPORT_ALLOC_PKT_NOT_REGD;\r
346 }\r
347 \r
348 return (pktHandle);\r
349 }\r
350 \r
351 /**********************************************************************\r
352 ********************* Application visible APIs ***********************\r
353 **********************************************************************/\r
354 \r
355 /* FUNCTION PURPOSE: Registers an app transport with a RM instance\r
356 ***********************************************************************\r
357 * DESCRIPTION: Returns a transport handle to the application that\r
358 * has been registered with an RM instance. The handle\r
359 * is used by the application to route packets to the\r
360 * proper RM instance's based on the application\r
361 * transport receive code. The handle is also used\r
362 * internally by RM to route request and response \r
363 * packets to the correct application transports. NULL\r
364 * is returned for the transport handle if any errors\r
365 * are encountered.\r
366 */\r
367 Rm_TransportHandle Rm_transportRegister (const Rm_TransportCfg *transportCfg, int32_t *result)\r
368 {\r
369 Rm_Inst *rmInst = (Rm_Inst *) transportCfg->rmHandle;\r
370 Rm_Transport *transport = NULL;\r
371 \r
372 /* RM Servers cannot connect to other Servers. \r
373 * RM Client Delegates cannot connect to other Client Delegates.\r
374 * RM Clients cannot connect to other Clients */\r
375 if (((rmInst->instType == Rm_instType_SERVER) &&\r
376 (transportCfg->remoteInstType == Rm_instType_SERVER)) ||\r
377 ((rmInst->instType == Rm_instType_CLIENT_DELEGATE) &&\r
378 (transportCfg->remoteInstType == Rm_instType_CLIENT_DELEGATE)) ||\r
379 ((rmInst->instType == Rm_instType_CLIENT) &&\r
380 (transportCfg->remoteInstType == Rm_instType_CLIENT))) {\r
381 *result = RM_ERROR_INVALID_REMOTE_INST_TYPE;\r
382 return(NULL);\r
383 }\r
384 \r
385 /* Verify Clients are not registering with more than one Client Delegate or Server. And\r
386 * that Client Delegate is not registering with more than one Server. */\r
387 if (rmInst->registeredWithDelegateOrServer &&\r
388 (((rmInst->instType == Rm_instType_CLIENT) &&\r
389 (transportCfg->remoteInstType == Rm_instType_CLIENT_DELEGATE)) || \r
390 ((rmInst->instType == Rm_instType_CLIENT_DELEGATE) &&\r
391 (transportCfg->remoteInstType == Rm_instType_SERVER)))) {\r
392 *result = RM_ERROR_ALREADY_REGD_SERVER_OR_CD;\r
393 return(NULL);\r
394 } \r
395 \r
396 if (transportCfg->transportCalloutsValid &&\r
397 ((transportCfg->transportCallouts.rmAllocPkt == NULL) ||\r
398 (transportCfg->transportCallouts.rmSendPkt == NULL))) {\r
399 *result = RM_ERROR_NULL_CALLOUTS_WHEN_VALID;\r
400 return(NULL);\r
401 }\r
402 else {\r
403 rmInst->transportCallouts.rmAllocPkt = transportCfg->transportCallouts.rmAllocPkt;\r
404 rmInst->transportCallouts.rmSendPkt = transportCfg->transportCallouts.rmSendPkt;\r
405 }\r
406 \r
407 transport = transportAdd(transportCfg);\r
408 \r
409 if ((transport->remoteInstType == Rm_instType_CLIENT_DELEGATE) ||\r
410 (transport->remoteInstType == Rm_instType_SERVER)) {\r
411 rmInst->registeredWithDelegateOrServer = true;\r
412 }\r
413 \r
414 *result = RM_OK;\r
415 return ((Rm_TransportHandle) transport);\r
416 }\r
417 \r
418 /* FUNCTION PURPOSE: Unregisters an app transport from a RM instance\r
419 ***********************************************************************\r
420 * DESCRIPTION: Deletes a registered transport from the transport\r
421 * list and cleans up the memory associated with the\r
422 * transport data structure.\r
423 */\r
424 int32_t Rm_transportUnregister(Rm_TransportHandle transportHandle)\r
425 {\r
426 Rm_Transport *transport = (Rm_Transport *)transportHandle;\r
427 Rm_Inst *rmInst = (Rm_Inst *)transport->rmHandle;\r
428 int32_t retVal = RM_OK; \r
429 \r
430 if (transportIsRegistered(transport->rmHandle, transport)) {\r
431 if ((transport->remoteInstType == Rm_instType_CLIENT_DELEGATE) ||\r
432 (transport->remoteInstType == Rm_instType_SERVER)) {\r
433 rmInst->registeredWithDelegateOrServer = false;\r
434 }\r
435 transportDelete(transport);\r
436 }\r
437 else {\r
438 retVal = RM_ERROR_TRANSPORT_HANDLE_DOES_NOT_EXIST;\r
439 }\r
440 return (retVal);\r
441 }\r
442 \r
443 /* FUNCTION PURPOSE: Receives RM packets\r
444 ***********************************************************************\r
445 * DESCRIPTION: The application provides RM packets received on the\r
446 * application transports to RM via this API. Function\r
447 * can be called from polling or ISR contexts. */\r
448 int32_t Rm_receivePacket(Rm_TransportHandle transportHandle, const Rm_Packet *pkt)\r
450 Rm_Transport *transport = (Rm_Transport *)transportHandle;\r
451 Rm_Inst *rmInst = (Rm_Inst *)transport->rmHandle;\r
452 Rm_Transaction *transaction;\r
453 \r
454 if (!transportIsRegistered(transport->rmHandle, transport)) {\r
455 return (RM_ERROR_TRANSPORT_HANDLE_DOES_NOT_EXIST);\r
456 }\r
457 \r
458 switch (pkt->pktType) {\r
459 case Rm_pktType_RESOURCE_REQUEST:\r
460 {\r
461 Rm_ResourceRequestPkt *resourceReqPkt = (Rm_ResourceRequestPkt *)pkt->data;\r
462 \r
463 transaction = rmTransactionQueueAdd(rmInst);\r
464 transaction->remoteOriginatingId = resourceReqPkt->requestId;\r
465 if (resourceReqPkt->resourceReqType == Rm_resReqPktType_ALLOCATE_INIT) {\r
466 transaction->type = Rm_service_RESOURCE_ALLOCATE_INIT;\r
467 }\r
468 else if (resourceReqPkt->resourceReqType == Rm_resReqPktType_ALLOCATE_USE) {\r
469 transaction->type = Rm_service_RESOURCE_ALLOCATE_USE;\r
470 } \r
471 else if (resourceReqPkt->resourceReqType == Rm_resReqPktType_FREE) {\r
472 transaction->type = Rm_service_RESOURCE_FREE;\r
473 }\r
474 else if (resourceReqPkt->resourceReqType == Rm_resReqPktType_GET_NAMED) {\r
475 transaction->type = Rm_service_RESOURCE_GET_BY_NAME;\r
476 } \r
477 strncpy(transaction->pktSrcInstName, resourceReqPkt->pktSrcInstName, RM_NAME_MAX_CHARS);\r
478 strncpy(transaction->serviceSrcInstName, resourceReqPkt->serviceSrcInstName, RM_NAME_MAX_CHARS);\r
479 transaction->state = RM_SERVICE_PROCESSING;\r
480 memcpy ((void *)&(transaction->resourceInfo), (void *)&(resourceReqPkt->resourceInfo),\r
481 sizeof(Rm_ResourceInfo));\r
482 rmTransactionProcessor(rmInst, transaction);\r
483 break;\r
484 }\r
485 case Rm_pktType_RESOURCE_RESPONSE:\r
486 {\r
487 Rm_ResourceResponsePkt *resourceRespPkt = (Rm_ResourceResponsePkt *)pkt->data;\r
488 \r
489 if (transaction = rmTransactionQueueFind(rmInst,resourceRespPkt->responseId)) {\r
490 if ((transaction->state == RM_SERVICE_APPROVED_STATIC) &&\r
491 (resourceRespPkt->requestState != RM_SERVICE_APPROVED)) {\r
492 /* Lock the RM instance since service validated against static policy failed against \r
493 * Server's global policy */\r
494 rmInst->isLocked = true;\r
495 }\r
496 transaction->state = resourceRespPkt->requestState;\r
497 \r
498 if ((transaction->state == RM_SERVICE_APPROVED) &&\r
499 ((transaction->type == Rm_service_RESOURCE_ALLOCATE_INIT) ||\r
500 (transaction->type == Rm_service_RESOURCE_ALLOCATE_USE) ||\r
501 (transaction->type == Rm_service_RESOURCE_GET_BY_NAME))) {\r
502 memcpy ((void *)&(transaction->resourceInfo), (void *)&(resourceRespPkt->resourceInfo),\r
503 sizeof(Rm_ResourceInfo));\r
504 }\r
505 rmTransactionProcessor(rmInst, transaction);\r
506 }\r
507 else {\r
508 return (RM_ERROR_PKT_RESP_DOES_NOT_MATCH_ANY_REQ);\r
509 }\r
510 break;\r
511 }\r
512 case Rm_pktType_NAMESERVER_REQUEST:\r
513 {\r
514 Rm_NsRequestPkt *nsRequestPkt = (Rm_NsRequestPkt *)pkt->data;\r
515 \r
516 transaction = rmTransactionQueueAdd(rmInst);\r
517 transaction->remoteOriginatingId = nsRequestPkt->requestId;\r
518 \r
519 if (nsRequestPkt->nsRequestType == Rm_nsReqPktType_MAP_RESOURCE) {\r
520 transaction->type = Rm_service_RESOURCE_MAP_TO_NAME;\r
521 }\r
522 else if (nsRequestPkt->nsRequestType == Rm_nsReqPktType_UNMAP_RESOURCE) {\r
523 transaction->type = Rm_service_RESOURCE_UNMAP_NAME;\r
524 }\r
525 \r
526 strncpy(transaction->pktSrcInstName, nsRequestPkt->pktSrcInstName, RM_NAME_MAX_CHARS);\r
527 strncpy(transaction->serviceSrcInstName, nsRequestPkt->serviceSrcInstName, RM_NAME_MAX_CHARS);\r
528 transaction->state = RM_SERVICE_PROCESSING;\r
529 memcpy ((void *)&(transaction->resourceInfo), (void *)&(nsRequestPkt->resourceInfo),\r
530 sizeof(Rm_ResourceInfo));\r
531 rmTransactionProcessor(rmInst, transaction); \r
532 break;\r
533 }\r
534 case Rm_pktType_NAMESERVER_RESPONSE:\r
535 {\r
536 Rm_NsResponsePkt *nsResponsePkt = (Rm_NsResponsePkt *)pkt->data;\r
537 \r
538 if (transaction = rmTransactionQueueFind(rmInst, nsResponsePkt->responseId)) {\r
539 if ((transaction->state == RM_SERVICE_APPROVED_STATIC) &&\r
540 (nsResponsePkt->requestState != RM_SERVICE_APPROVED)) {\r
541 /* Lock the RM instance since service validated against static policy failed against \r
542 * Server's global policy */ \r
543 rmInst->isLocked = true;\r
544 } \r
545 transaction->state = nsResponsePkt->requestState; \r
546 rmTransactionProcessor(rmInst, transaction);\r
547 }\r
548 else {\r
549 return (RM_ERROR_PKT_RESP_DOES_NOT_MATCH_ANY_REQ);\r
550 }\r
551 break;\r
552 }\r
553 default:\r
554 return (RM_ERROR_RECEIVED_INVALID_PACKET_TYPE);\r
555 }\r
556 \r
557 return (RM_OK);\r
558 }\r
559 \r