d54fa50da8da245bdd3a0846a8dffb8b78b3fbcd
1 /*
2 * Copyright (c) 2012-2013, Texas Instruments Incorporated
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 *
9 * * Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 *
12 * * Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 *
16 * * Neither the name of Texas Instruments Incorporated nor the names of
17 * its contributors may be used to endorse or promote products derived
18 * from this software without specific prior written permission.
19 *
20 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
21 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
22 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
23 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
24 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
25 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
26 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
27 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
28 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
29 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
30 * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31 */
32 /*
33 * ======== rm_dsp_client_test.c ========
34 *
35 * Works with the dspClientTest DSP application over the rpmsg-proto socket.
36 */
38 /* Standard headers */
39 #include <stdio.h>
40 #include <stdlib.h>
42 /* IPC Headers */
43 #include <Std.h>
44 #include <ti/ipc/Ipc.h>
45 #include <ti/ipc/MessageQ.h>
47 /* Socket Includes */
48 #include "sockutils.h"
49 #include "sockrmmsg.h"
51 /* RM includes */
52 #include <ti/drv/rm/rm_transport.h>
54 /* App defines: Must match on remote proc side: */
55 #define HEAPID 0u
56 #define CLIENT_MESSAGEQ_NAME "RM_CLIENT"
57 #define SERVER_MESSAGEQ_NAME "RM_SERVER"
59 #define PROC_ID_DEFAULT 1 /* Host is zero, remote cores start at 1 */
61 /* IPC MessageQ RM packet encapsulation structure */
62 typedef struct {
63 /* IPC MessageQ header (must be first element in structure) */
64 MessageQ_MsgHeader msgQHeader;
65 /* Pointer to RM packet */
66 Rm_Packet rmPkt;
67 } MsgQ_RmPacket;
69 Int rmServerExchange_execute(UInt16 procId)
70 {
71 int32_t status = 0;
72 int err;
73 MessageQ_Msg msg = NULL;
74 MessageQ_Params msgParams;
75 MessageQ_QueueId queueId = MessageQ_INVALIDMESSAGEQ;
76 MessageQ_Handle msgqHandle;
77 char remoteQueueName[64];
78 MessageQ_Msg rmMsg;
79 Rm_Packet *rmPkt;
80 int rm_pkt_len;
81 sock_h sock_to_server;
82 sock_name_t local_sock_name;
83 sock_name_t server_sock;
84 sock_name_t server_sock_addr;
85 struct sockaddr_un server_addr;
86 char client_ex_sock_name[] = "/tmp/var/run/rm/rm_dsp_client_exchange";
87 char server_sock_name[] = RM_SERVER_SOCKET_NAME;
89 printf("Entered rmServerExchange_execute\n");
91 /* Create the local Message Queue for receiving from DSP Client. */
92 MessageQ_Params_init(&msgParams);
93 msgqHandle = MessageQ_create(SERVER_MESSAGEQ_NAME, &msgParams);
94 if (msgqHandle == NULL) {
95 printf("Error in MessageQ_create\n");
96 goto exit;
97 }
98 else {
99 printf("Local MessageQId: 0x%x\n", MessageQ_getQueueId(msgqHandle));
100 }
102 sprintf(remoteQueueName, "%s_%s", CLIENT_MESSAGEQ_NAME,
103 MultiProc_getName(procId));
105 /* Poll until remote side has it's messageQ created before we send: */
106 do {
107 status = MessageQ_open(remoteQueueName, &queueId);
108 sleep (1);
109 } while (status == MessageQ_E_NOTFOUND);
111 if (status < 0) {
112 printf("Error in MessageQ_open [%d]\n", status);
113 goto cleanup;
114 }
115 else {
116 printf("Remote queueId [0x%x]\n", queueId);
117 }
119 msg = MessageQ_alloc(HEAPID, sizeof(MessageQ_MsgHeader));
120 if (msg == NULL) {
121 printf("Error in MessageQ_alloc\n");
122 MessageQ_close(&queueId);
123 goto cleanup;
124 }
126 /* handshake with DSP client so that it knows Linux's receive Q */
127 MessageQ_setReplyQueue(msgqHandle, msg);
128 MessageQ_put(queueId, msg);
129 MessageQ_get(msgqHandle, &msg, MessageQ_FOREVER);
130 MessageQ_free(msg);
132 printf("Setting up socket connection with RM Server\n");
134 /* open local sock for communication to RM Server */
135 local_sock_name.type = sock_name_e;
136 local_sock_name.s.name = client_ex_sock_name;
137 sock_to_server = sock_open(&local_sock_name);
138 if (!sock_to_server) {
139 printf("Local socket to RM Server open failed\n");
140 return -1;
141 }
142 /* RM Server sock */
143 server_sock.type = sock_name_e;
144 server_sock.s.name = server_sock_name;
146 printf("Waiting for RM messages from DSP Client\n");
148 while(1) {
149 status = MessageQ_get(msgqHandle, &rmMsg, MessageQ_FOREVER);
150 if (status < 0) {
151 printf("Error in MessageQ_get [%d]\n", status);
152 break;
153 }
155 rmPkt = &(((MsgQ_RmPacket *)rmMsg)->rmPkt);
156 printf("Received RM pkt of size %d from DSP client\n", rmPkt->pktLenBytes);
158 /* Send received data to RM Server */
159 if (sock_send(sock_to_server, (char *)rmPkt, sizeof(*rmPkt), &server_sock)) {
160 printf("Failed to send data to RM Server\n");
161 }
163 /* Wait for response from RM Server */
164 rm_pkt_len = 0;
165 err = sock_wait(sock_to_server, &rm_pkt_len, NULL, -1);
166 if (err == -2) {
167 /* Timeout */
168 printf("Error socket timeout\n");
169 return -1;
170 }
171 else if (err < 0) {
172 printf("Error in reading from socket, error %d\n", err);
173 return -1;
174 }
176 server_sock_addr.type = sock_addr_e;
177 server_sock_addr.s.addr = &server_addr;
178 err = sock_recv(sock_to_server, (char *)rmPkt, rm_pkt_len, &server_sock_addr);
179 if (err != rm_pkt_len) {
180 printf("recv RM pkt failed from socket, received = %d, expected = %d\n",
181 err, rm_pkt_len);
182 return;
183 }
185 /* send back to DSP */
186 status = MessageQ_put(queueId, rmMsg);
187 if (status < 0) {
188 printf("Error in MessageQ_put [%d]\n", status);
189 break;
190 }
191 }
193 cleanup:
194 /* Clean-up */
195 status = MessageQ_delete(&msgqHandle);
196 if (status < 0) {
197 printf("Error in MessageQ_delete [%d]\n", status);
198 }
200 exit:
201 printf("Leaving rmServerExchange_execute\n\n");
203 return 0;
204 }
206 int main (int argc, char ** argv)
207 {
208 Int32 status = 0;
209 UInt16 procId = PROC_ID_DEFAULT;
211 /* Parse Args: */
212 switch (argc) {
213 case 1:
214 /* use defaults */
215 break;
216 case 2:
217 procId = atoi(argv[2]);
218 break;
219 default:
220 printf("Usage: %s [<ProcId>]\n", argv[0]);
221 printf("\tDefaults: ProcId: %d\n", PROC_ID_DEFAULT);
222 exit(0);
223 }
224 if (procId >= MultiProc_getNumProcessors()) {
225 printf("ProcId must be less than %d\n", MultiProc_getNumProcessors());
226 exit(0);
227 }
228 printf("Using procId : %d\n", procId);
230 status = Ipc_start();
232 if (status >= 0) {
233 rmServerExchange_execute(procId);
234 Ipc_stop();
235 }
236 else {
237 printf("Ipc_start failed: status = %d\n", status);
238 }
240 return(0);
241 }