Changes to ARM-DSP test project based on IPC update
[keystone-rtos/rm-lld.git] / test / k2k / armv7 / linux / rm_dsp_client_test.c
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 <ti/ipc/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");
90  
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;
206 int main (int argc, char ** argv)
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     }
225     status = Ipc_start();
227     if (procId >= MultiProc_getNumProcessors()) {
228         printf("ProcId must be less than %d\n", MultiProc_getNumProcessors());
229         Ipc_stop();
230         exit(0);
231     }
232     printf("Using procId : %d\n", procId);
234     if (status >= 0) {
235         rmServerExchange_execute(procId);
236         Ipc_stop();
237     }
238     else {
239         printf("Ipc_start failed: status = %d\n", status);
240     }
242     return(0);