1 /**************************************************************
2 * FILE PURPOSE : NETAPI Resource Manager Configuration
3 *
4 **************************************************************
5 * @file netapi_rm.c
6 *
7 * @brief DESCRIPTION: netapi resource manager file used for user space
8 * transport library
9 *
10 * REVISION HISTORY:
11 *
12 * Copyright (c) Texas Instruments Incorporated 2014
13 *
14 * Redistribution and use in source and binary forms, with or without
15 * modification, are permitted provided that the following conditions
16 * are met:
17 *
18 * Redistributions of source code must retain the above copyright
19 * notice, this list of conditions and the following disclaimer.
20 *
21 * Redistributions in binary form must reproduce the above copyright
22 * notice, this list of conditions and the following disclaimer in the
23 * documentation and/or other materials provided with the
24 * distribution.
25 *
26 * Neither the name of Texas Instruments Incorporated nor the names of
27 * its contributors may be used to endorse or promote products derived
28 * from this software without specific prior written permission.
29 *
30 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
31 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
32 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
33 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
34 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
35 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
36 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
37 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
38 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
39 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
40 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
41 *****************************************************************************/
43 #include <stdlib.h>
44 #include <stdio.h>
45 #include <stdarg.h>
47 #include "ti/runtime/netapi/netapi.h"
50 uint32_t Osal_rm_MallocCounter = 0;
51 uint32_t Osal_rm_FreeCounter = 0;
54 /* Socket Includes */
55 #include "sockutils.h"
56 #include "sockrmmsg.h"
58 /* RM Includes */
59 #include <ti/drv/rm/rm.h>
60 #include <ti/drv/rm/rm_transport.h>
61 #include <ti/drv/rm/rm_services.h>
63 /* Socket timeout */
64 #define CLIENT_SOCK_TIMEOUT_USEC (500)
66 /* Application's registered RM transport indices */
67 #define SERVER_TO_CLIENT_MAP_ENTRY 0
68 /* Maximum number of registered RM transports */
69 #define MAX_MAPPING_ENTRIES 1
71 /* Error checking macro */
72 #define RM_ERROR_CHECK(checkVal, resultVal, rmInstName, printMsg) \
73 if (resultVal != checkVal) { \
74 char errorMsgToPrint[] = printMsg; \
75 printf("RM Inst : %s : ", rmInstName); \
76 printf("%s with error code : %d, exiting\n", errorMsgToPrint, resultVal); \
77 return(-1); \
78 }
80 /* RM registered transport mapping structure */
81 typedef struct trans_map_entry_s {
82 /* Registered RM transport handle */
83 Rm_TransportHandle transportHandle;
84 /* Remote socket tied to the transport handle */
85 sock_name_t *remote_sock;
86 } Transport_MapEntry;
92 /* RM Client Vars */
93 Rm_Handle rmClientHandle = NULL;
94 Rm_ServiceHandle *rmClientServiceHandle = NULL;
95 sock_h rmClientSocket;
97 /* Client instance name (must match with RM Global Resource List (GRL) and policies */
98 char rmClientName[RM_NAME_MAX_CHARS] = "RM_Client_NETAPI";
100 /* Client socket name */
101 char rmClientSockName[] = "/tmp/var/run/rm/rm_client_netapi";
103 /* Transport map stores the RM transport handle to IPC MessageQ queue mapping */
104 Transport_MapEntry rmTransportMap[MAX_MAPPING_ENTRIES];
107 hplib_spinLock_T net_test_rm_lock;
111 void *Osal_rmMalloc (uint32_t num_bytes)
112 {
113 /* Increment the allocation counter. */
114 Osal_rm_MallocCounter++;
116 /* Allocate memory. */
117 return calloc(1, num_bytes);
118 }
120 void Osal_rmFree (void *ptr, uint32_t size)
121 {
122 /* Increment the free counter. */
123 Osal_rm_FreeCounter++;
124 free(ptr);
125 }
127 void *Osal_rmCsEnter(void)
128 {
129 return NULL;
130 }
132 void Osal_rmCsExit(void *CsHandle)
133 {
135 }
137 void Osal_rmBeginMemAccess(void *ptr, uint32_t size)
138 {
139 return;
140 }
142 void Osal_rmEndMemAccess(void *ptr, uint32_t size)
143 {
144 return;
145 }
147 void *Osal_rmTaskBlockCreate(void)
148 {
149 return(NULL);
150 }
152 void Osal_rmTaskBlock(void *handle)
153 {
155 }
157 void Osal_rmTaskUnblock(void *handle)
158 {
160 }
162 void Osal_rmTaskBlockDelete(void *handle)
163 {
165 }
167 void Osal_rmLog (char *fmt, ... )
168 {
169 va_list ap;
171 va_start(ap, fmt);
172 vprintf(fmt, ap);
173 va_end(ap);
174 }
176 void *Osal_rmMtCsEnter(void *mtSemObj)
177 {
178 return NULL;
179 }
182 void Osal_rmMtCsExit(void *mtSemObj, void *CsHandle)
183 {
185 }
186 Rm_Packet *transportAlloc(Rm_AppTransportHandle appTransport, uint32_t pktSize, Rm_PacketHandle *pktHandle)
187 {
188 Rm_Packet *rm_pkt = NULL;
190 rm_pkt = calloc(1, sizeof(*rm_pkt));
191 if (!rm_pkt) {
192 printf("can't malloc for RM send message (err: %s)\n", strerror(errno));
193 return (NULL);
194 }
195 rm_pkt->pktLenBytes = pktSize;
196 *pktHandle = rm_pkt;
198 return(rm_pkt);
199 }
201 void transportFree (Rm_Packet *rm_pkt)
202 {
203 if (rm_pkt) {
204 free (rm_pkt);
205 }
206 }
208 void transportReceive (void)
209 {
210 int32_t rm_result;
211 int retval;
212 int length = 0;
213 sock_name_t server_sock_addr;
214 Rm_Packet *rm_pkt = NULL;
215 struct sockaddr_un server_addr;
217 retval = sock_wait(rmClientSocket, &length, NULL, -1);
218 if (retval == -2) {
219 /* Timeout */
220 printf("Error socket timeout\n");
221 return;
222 }
223 else if (retval < 0) {
224 printf("Error in reading from socket, error %d\n", retval);
225 return;
226 }
228 if (length < sizeof(*rm_pkt)) {
229 printf("invalid RM message length %d\n", length);
230 return;
231 }
232 rm_pkt = calloc(1, length);
233 if (!rm_pkt) {
234 printf("can't malloc for recv'd RM message (err: %s)\n",
235 strerror(errno));
236 return;
237 }
239 server_sock_addr.type = sock_addr_e;
240 server_sock_addr.s.addr = &server_addr;
241 retval = sock_recv(rmClientSocket, (char *)rm_pkt, length, &server_sock_addr);
242 if (retval != length) {
243 printf("recv RM pkt failed from socket, received = %d, expected = %d\n",
244 retval, length);
245 return;
246 }
249 /* Provide packet to RM Client for processing */
250 if ((rm_result = Rm_receivePacket(rmTransportMap[SERVER_TO_CLIENT_MAP_ENTRY].transportHandle, rm_pkt))) {
251 printf("RM failed to process received packet !!: %d\n", rm_result);
252 }
254 transportFree(rm_pkt);
255 }
257 int32_t transportSendRcv (Rm_AppTransportHandle appTransport, Rm_PacketHandle pktHandle)
258 {
259 sock_name_t *server_sock_name = (sock_name_t *)appTransport;
260 Rm_Packet *rm_pkt = (Rm_Packet *)pktHandle;
262 hplib_mSpinLockLock(&net_test_rm_lock);
263 if (sock_send(rmClientSocket, (char *)rm_pkt, (int) rm_pkt->pktLenBytes, server_sock_name))
264 {
265 hplib_mSpinLockUnlock(&net_test_rm_lock);
266 return (-1);
267 }
268 /* Wait for response from Server */
269 transportReceive();
270 hplib_mSpinLockUnlock(&net_test_rm_lock);
272 return (0);
273 }
275 int connection_setup(void)
276 {
277 Rm_TransportCfg rmTransCfg;
278 int32_t rm_result;
279 int i;
280 sock_name_t sock_name;
281 char server_sock_name[] = RM_SERVER_SOCKET_NAME;
283 /* Initialize the transport map */
284 for (i = 0; i < MAX_MAPPING_ENTRIES; i++) {
285 rmTransportMap[i].transportHandle = NULL;
286 }
288 sock_name.type = sock_name_e;
289 sock_name.s.name = rmClientSockName;
291 rmClientSocket = sock_open(&sock_name);
292 if (!rmClientSocket) {
293 printf("connection_setup: Client socket open failed\n");
294 return (-1);
295 }
297 rmTransportMap[SERVER_TO_CLIENT_MAP_ENTRY].remote_sock = calloc(1, sizeof(sock_name_t));
298 rmTransportMap[SERVER_TO_CLIENT_MAP_ENTRY].remote_sock->type = sock_name_e;
299 rmTransportMap[SERVER_TO_CLIENT_MAP_ENTRY].remote_sock->s.name = calloc(1, strlen(server_sock_name)+1);
300 strncpy(rmTransportMap[SERVER_TO_CLIENT_MAP_ENTRY].remote_sock->s.name, server_sock_name, strlen(server_sock_name)+1);
302 /* Register the Server with the Client instance */
303 rmTransCfg.rmHandle = rmClientHandle;
304 rmTransCfg.appTransportHandle = (Rm_AppTransportHandle) rmTransportMap[SERVER_TO_CLIENT_MAP_ENTRY].remote_sock;
305 rmTransCfg.remoteInstType = Rm_instType_SERVER;
306 rmTransCfg.transportCallouts.rmAllocPkt = transportAlloc;
307 rmTransCfg.transportCallouts.rmSendPkt = transportSendRcv;
308 rmTransportMap[SERVER_TO_CLIENT_MAP_ENTRY].transportHandle = Rm_transportRegister(&rmTransCfg, &rm_result);
309 printf("connection_setup: complete !!!!!!!!!!!!!!!!!!!!!!!!!!\n");
310 return(0);
311 }
313 /** ============================================================================
314 * @n@b initRm
315 *
316 * @b Description
317 * @n This API initializes the RM Client for the QMSS test establishing
318 * a socket connection with the RM Server
319 *
320 * @return int32_t
321 * -1 - Error
322 * 0 - Success
323 * =============================================================================
324 */
325 int initRm (void)
326 {
327 Rm_InitCfg rmInitCfg;
328 int32_t result;
331 //net_test_rm_lock = hplib_spinLock_UNLOCKED_INITIALIZER;
332 hplib_mSpinLockInit(&net_test_rm_lock );
334 /* Initialize the RM Client - RM must be initialized before anything else in the system */
335 memset(&rmInitCfg, 0, sizeof(rmInitCfg));
336 rmInitCfg.instName = rmClientName;
337 rmInitCfg.instType = Rm_instType_CLIENT;
338 rmClientHandle = Rm_init(&rmInitCfg, &result);
339 RM_ERROR_CHECK(RM_OK, result, rmClientName, "Initialization failed");
342 /* Open Client service handle */
343 rmClientServiceHandle = Rm_serviceOpenHandle(rmClientHandle, &result);
344 RM_ERROR_CHECK(RM_OK, result, rmClientName, "Service handle open failed");
346 return(connection_setup());
347 }
349 int32_t closeRm(void)
350 {
351 int32_t result = 0;
353 if(rmClientHandle)
354 {
355 result = Rm_serviceCloseHandle(rmClientServiceHandle);
356 RM_ERROR_CHECK(RM_OK, result, rmClientName, "Service handle close failed");
358 result = Rm_transportUnregister(rmTransportMap[SERVER_TO_CLIENT_MAP_ENTRY].transportHandle);
359 RM_ERROR_CHECK(RM_OK, result, rmClientName, "Unregister of CD transport failed");
361 result = Rm_delete(rmClientHandle, 1);
362 RM_ERROR_CHECK(RM_OK, result, rmClientName, "Instance delete failed");
363 }
364 return (result);
365 }