source: mainline/uspace/srv/test/ipc-test/main.c@ 4c6fd56

ticket/834-toolchain-update topic/msim-upgrade topic/simplify-dev-export
Last change on this file since 4c6fd56 was 4c6fd56, checked in by Jiri Svoboda <jiri@…>, 22 months ago

loc_server_register() should be callable more than once (API only)

Now loc_server_register() returns a pointer to a loc_srv_t object,
that is then passed to loc_service_register() and
loc_service_add_to_cat().

Added loc_server_unregister() that unregisters the server
and frees the loc_srv_t object.

Updated all callers. The implementation, however, is a stub.
It is not actually possible to call loc_server_register() more
than once, yet.

  • Property mode set to 100644
File size: 6.3 KB
Line 
1/*
2 * Copyright (c) 2023 Jiri Svoboda
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 * - Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
14 * - The name of the author may not be used to endorse or promote products
15 * derived from this software without specific prior written permission.
16 *
17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
18 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
19 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
21 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
22 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 */
28
29/** @addtogroup ipc-test
30 * @{
31 */
32/**
33 * @file
34 * @brief IPC test service
35 *
36 * If run as an initial task, this can be used to test sharing areas
37 * backed by the ELF backend.
38 */
39
40#include <as.h>
41#include <async.h>
42#include <errno.h>
43#include <str_error.h>
44#include <io/log.h>
45#include <ipc/ipc_test.h>
46#include <ipc/services.h>
47#include <loc.h>
48#include <mem.h>
49#include <stdio.h>
50#include <task.h>
51
52#define NAME "ipc-test"
53
54static service_id_t svc_id;
55
56/** Object in read-only memory area that will be shared.
57 *
58 * If the server is run as an initial task, the area should be backed
59 * by ELF backend.
60 */
61static const char *ro_data = "Hello, world!";
62
63/** Object in read-write memory area that will be shared.
64 *
65 * If the server is run as an initial task, the area should be backed
66 * by ELF backend.
67 */
68static char rw_data[] = "Hello, world!";
69
70static void ipc_test_get_ro_area_size_srv(ipc_call_t *icall)
71{
72 errno_t rc;
73 as_area_info_t info;
74
75 log_msg(LOG_DEFAULT, LVL_DEBUG, "ipc_test_get_ro_area_size_srv");
76
77 rc = as_area_get_info((void *)ro_data, &info);
78 if (rc != EOK) {
79 async_answer_0(icall, EIO);
80 log_msg(LOG_DEFAULT, LVL_ERROR, "as_area_get_info failed");
81 return;
82 }
83
84 async_answer_1(icall, EOK, info.size);
85}
86
87static void ipc_test_get_rw_area_size_srv(ipc_call_t *icall)
88{
89 errno_t rc;
90 as_area_info_t info;
91
92 log_msg(LOG_DEFAULT, LVL_DEBUG, "ipc_test_get_rw_area_size_srv");
93
94 rc = as_area_get_info(rw_data, &info);
95 if (rc != EOK) {
96 async_answer_0(icall, EIO);
97 log_msg(LOG_DEFAULT, LVL_ERROR, "as_area_get_info failed");
98 return;
99 }
100
101 async_answer_1(icall, EOK, info.size);
102}
103
104static void ipc_test_share_in_ro_srv(ipc_call_t *icall)
105{
106 ipc_call_t call;
107 errno_t rc;
108 size_t size;
109 as_area_info_t info;
110
111 log_msg(LOG_DEFAULT, LVL_DEBUG, "ipc_test_share_in_ro_srv");
112 if (!async_share_in_receive(&call, &size)) {
113 async_answer_0(icall, EINVAL);
114 log_msg(LOG_DEFAULT, LVL_ERROR, "share_in_receive failed");
115 return;
116 }
117
118 rc = as_area_get_info((void *)ro_data, &info);
119 if (rc != EOK) {
120 async_answer_0(icall, EINVAL);
121 log_msg(LOG_DEFAULT, LVL_ERROR, "as_area_get_info failed");
122 return;
123 }
124
125 if (size != info.size) {
126 log_msg(LOG_DEFAULT, LVL_ERROR, "size(%zu) != %zu",
127 size, info.size);
128 async_answer_0(icall, EINVAL);
129 return;
130 }
131
132 rc = async_share_in_finalize(&call, (void *) info.start_addr,
133 AS_AREA_READ);
134 if (rc != EOK) {
135 log_msg(LOG_DEFAULT, LVL_ERROR,
136 " - async_share_in_finalize failed");
137 async_answer_0(icall, EINVAL);
138 return;
139 }
140
141 async_answer_0(icall, EOK);
142}
143
144static void ipc_test_share_in_rw_srv(ipc_call_t *icall)
145{
146 ipc_call_t call;
147 errno_t rc;
148 size_t size;
149 as_area_info_t info;
150
151 log_msg(LOG_DEFAULT, LVL_DEBUG, "ipc_test_share_in_ro_srv");
152 if (!async_share_in_receive(&call, &size)) {
153 async_answer_0(icall, EINVAL);
154 log_msg(LOG_DEFAULT, LVL_ERROR, "share_in_receive failed");
155 return;
156 }
157
158 rc = as_area_get_info(rw_data, &info);
159 if (rc != EOK) {
160 async_answer_0(icall, EINVAL);
161 log_msg(LOG_DEFAULT, LVL_ERROR, "as_area_get_info failed");
162 return;
163 }
164
165 if (size != info.size) {
166 log_msg(LOG_DEFAULT, LVL_ERROR, " size(%zu) != %zu",
167 size, info.size);
168 async_answer_0(icall, EINVAL);
169 return;
170 }
171
172 rc = async_share_in_finalize(&call, (void *) info.start_addr,
173 AS_AREA_READ | AS_AREA_WRITE);
174 if (rc != EOK) {
175 log_msg(LOG_DEFAULT, LVL_ERROR,
176 "async_share_in_finalize failed");
177 async_answer_0(icall, EINVAL);
178 return;
179 }
180
181 async_answer_0(icall, EOK);
182}
183
184static void ipc_test_connection(ipc_call_t *icall, void *arg)
185{
186 /* Accept connection */
187 async_accept_0(icall);
188
189 while (true) {
190 ipc_call_t call;
191 async_get_call(&call);
192
193 if (!ipc_get_imethod(&call)) {
194 async_answer_0(&call, EOK);
195 break;
196 }
197
198 switch (ipc_get_imethod(&call)) {
199 case IPC_TEST_PING:
200 async_answer_0(&call, EOK);
201 break;
202 case IPC_TEST_GET_RO_AREA_SIZE:
203 ipc_test_get_ro_area_size_srv(&call);
204 break;
205 case IPC_TEST_GET_RW_AREA_SIZE:
206 ipc_test_get_rw_area_size_srv(&call);
207 break;
208 case IPC_TEST_SHARE_IN_RO:
209 ipc_test_share_in_ro_srv(&call);
210 break;
211 case IPC_TEST_SHARE_IN_RW:
212 ipc_test_share_in_rw_srv(&call);
213 break;
214 default:
215 async_answer_0(&call, ENOTSUP);
216 break;
217 }
218 }
219}
220
221int main(int argc, char *argv[])
222{
223 errno_t rc;
224 loc_srv_t *srv;
225
226 printf("%s: IPC test service\n", NAME);
227 async_set_fallback_port_handler(ipc_test_connection, NULL);
228
229 rc = log_init(NAME);
230 if (rc != EOK) {
231 printf(NAME ": Failed to initialize log.\n");
232 return rc;
233 }
234
235 rc = loc_server_register(NAME, &srv);
236 if (rc != EOK) {
237 log_msg(LOG_DEFAULT, LVL_ERROR, "Failed registering server. (%s)\n",
238 str_error(rc));
239 return rc;
240 }
241
242 rc = loc_service_register(srv, SERVICE_NAME_IPC_TEST, &svc_id);
243 if (rc != EOK) {
244 loc_server_unregister(srv);
245 log_msg(LOG_DEFAULT, LVL_ERROR, "Failed registering service. (%s)\n",
246 str_error(rc));
247 return rc;
248 }
249
250 printf("%s: Accepting connections\n", NAME);
251 task_retval(0);
252 async_manager();
253
254 /* Not reached */
255 return 0;
256}
257
258/**
259 * @}
260 */
Note: See TracBrowser for help on using the repository browser.