source: mainline/uspace/app/trace/ipcp.c@ 9eb1ff5

lfn serial ticket/834-toolchain-update topic/msim-upgrade topic/simplify-dev-export
Last change on this file since 9eb1ff5 was 40fd6f0, checked in by Jakub Jermar <jakub@…>, 8 years ago

Remove dead code

  • Property mode set to 100644
File size: 8.2 KB
Line 
1/*
2 * Copyright (c) 2008 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 trace
30 * @{
31 */
32/** @file
33 */
34
35#include <stdio.h>
36#include <stdlib.h>
37#include <inttypes.h>
38#include <adt/hash_table.h>
39#include <abi/ipc/methods.h>
40#include <macros.h>
41#include "ipc_desc.h"
42#include "proto.h"
43#include "trace.h"
44#include "ipcp.h"
45
46typedef struct {
47 sysarg_t phone_hash;
48 ipc_call_t question;
49 oper_t *oper;
50
51 ipc_callid_t call_hash;
52
53 ht_link_t link;
54} pending_call_t;
55
56typedef struct {
57 int server;
58 proto_t *proto;
59} connection_t;
60
61#define MAX_PHONE 64
62connection_t connections[MAX_PHONE];
63int have_conn[MAX_PHONE];
64
65static hash_table_t pending_calls;
66
67/*
68 * Pseudo-protocols
69 */
70proto_t *proto_system; /**< Protocol describing system IPC methods. */
71proto_t *proto_unknown; /**< Protocol with no known methods. */
72
73
74static size_t pending_call_key_hash(void *key)
75{
76 ipc_callid_t *call_id = (ipc_callid_t *)key;
77 return *call_id;
78}
79
80static size_t pending_call_hash(const ht_link_t *item)
81{
82 pending_call_t *hs = hash_table_get_inst(item, pending_call_t, link);
83 return hs->call_hash;
84}
85
86static bool pending_call_key_equal(void *key, const ht_link_t *item)
87{
88 ipc_callid_t *call_id = (ipc_callid_t *)key;
89 pending_call_t *hs = hash_table_get_inst(item, pending_call_t, link);
90
91 return *call_id == hs->call_hash;
92}
93
94static hash_table_ops_t pending_call_ops = {
95 .hash = pending_call_hash,
96 .key_hash = pending_call_key_hash,
97 .key_equal = pending_call_key_equal,
98 .equal = NULL,
99 .remove_callback = NULL
100};
101
102
103void ipcp_connection_set(int phone, int server, proto_t *proto)
104{
105 if (phone <0 || phone >= MAX_PHONE) return;
106 connections[phone].server = server;
107 connections[phone].proto = proto;
108 have_conn[phone] = 1;
109}
110
111void ipcp_connection_clear(int phone)
112{
113 have_conn[phone] = 0;
114 connections[phone].server = 0;
115 connections[phone].proto = NULL;
116}
117
118static void ipc_m_print(proto_t *proto, sysarg_t method)
119{
120 oper_t *oper;
121
122 /* Try system methods first */
123 oper = proto_get_oper(proto_system, method);
124
125 if (oper == NULL && proto != NULL) {
126 /* Not a system method, try the user protocol. */
127 oper = proto_get_oper(proto, method);
128 }
129
130 if (oper != NULL) {
131 printf("%s (%" PRIun ")", oper->name, method);
132 return;
133 }
134
135 printf("%" PRIun, method);
136}
137
138void ipcp_init(void)
139{
140 val_type_t arg_def[OPER_MAX_ARGS] = {
141 V_INTEGER,
142 V_INTEGER,
143 V_INTEGER,
144 V_INTEGER,
145 V_INTEGER
146 };
147
148 /*
149 * Create a pseudo-protocol 'unknown' that has no known methods.
150 */
151 proto_unknown = proto_new("unknown");
152
153 /*
154 * Create a pseudo-protocol 'system' defining names of system IPC
155 * methods.
156 */
157 proto_system = proto_new("system");
158
159 for (size_t i = 0; i < ipc_methods_len; i++) {
160 oper_t *oper = oper_new(ipc_methods[i].name, OPER_MAX_ARGS,
161 arg_def, V_INTEGER, OPER_MAX_ARGS, arg_def);
162 proto_add_oper(proto_system, ipc_methods[i].number, oper);
163 }
164
165 bool ok = hash_table_create(&pending_calls, 0, 0, &pending_call_ops);
166 assert(ok);
167}
168
169void ipcp_cleanup(void)
170{
171 proto_delete(proto_system);
172 hash_table_destroy(&pending_calls);
173}
174
175void ipcp_call_out(int phone, ipc_call_t *call, ipc_callid_t hash)
176{
177 pending_call_t *pcall;
178 proto_t *proto;
179 oper_t *oper;
180 sysarg_t *args;
181 int i;
182
183 if (have_conn[phone]) proto = connections[phone].proto;
184 else proto = NULL;
185
186 args = call->args;
187
188 if ((display_mask & DM_IPC) != 0) {
189 printf("Call ID: %d, phone: %d, proto: %s, method: ",
190 hash, phone,
191 (proto ? proto->name : "n/a"));
192 ipc_m_print(proto, IPC_GET_IMETHOD(*call));
193 printf(" args: (%" PRIun ", %" PRIun ", %" PRIun ", "
194 "%" PRIun ", %" PRIun ")\n",
195 args[1], args[2], args[3], args[4], args[5]);
196 }
197
198
199 if ((display_mask & DM_USER) != 0) {
200
201 if (proto != NULL) {
202 oper = proto_get_oper(proto, IPC_GET_IMETHOD(*call));
203 } else {
204 oper = NULL;
205 }
206
207 if (oper != NULL) {
208
209 printf("%s(%d).%s", (proto ? proto->name : "n/a"),
210 phone, (oper ? oper->name : "unknown"));
211
212 putchar('(');
213 for (i = 1; i <= oper->argc; ++i) {
214 if (i > 1) printf(", ");
215 val_print(args[i], oper->arg_type[i - 1]);
216 }
217 putchar(')');
218
219 if (oper->rv_type == V_VOID && oper->respc == 0) {
220 /*
221 * No response data (typically the task will
222 * not be interested in the response).
223 * We will not display response.
224 */
225 putchar('.');
226 }
227
228 putchar('\n');
229 }
230 } else {
231 oper = NULL;
232 }
233
234 /* Store call in hash table for response matching */
235
236 pcall = malloc(sizeof(pending_call_t));
237 pcall->phone_hash = phone;
238 pcall->question = *call;
239 pcall->call_hash = hash;
240 pcall->oper = oper;
241
242 hash_table_insert(&pending_calls, &pcall->link);
243}
244
245static void parse_answer(ipc_callid_t hash, pending_call_t *pcall,
246 ipc_call_t *answer)
247{
248 sysarg_t phone;
249 sysarg_t method;
250 sysarg_t service;
251 sysarg_t retval;
252 proto_t *proto;
253 int cphone;
254
255 sysarg_t *resp;
256 oper_t *oper;
257 int i;
258
259 phone = pcall->phone_hash;
260 method = IPC_GET_IMETHOD(pcall->question);
261 retval = IPC_GET_RETVAL(*answer);
262
263 resp = answer->args;
264
265 if ((display_mask & DM_IPC) != 0) {
266 printf("Response to %d: retval=%" PRIdn ", args = (%" PRIun ", "
267 "%" PRIun ", %" PRIun ", %" PRIun ", %" PRIun ")\n",
268 hash, retval, IPC_GET_ARG1(*answer),
269 IPC_GET_ARG2(*answer), IPC_GET_ARG3(*answer),
270 IPC_GET_ARG4(*answer), IPC_GET_ARG5(*answer));
271 }
272
273 if ((display_mask & DM_USER) != 0) {
274 oper = pcall->oper;
275
276 if ((oper != NULL) &&
277 ((oper->rv_type != V_VOID) || (oper->respc > 0))) {
278 printf("->");
279
280 if (oper->rv_type != V_VOID) {
281 putchar(' ');
282 val_print(retval, oper->rv_type);
283 }
284
285 if (oper->respc > 0) {
286 putchar(' ');
287 putchar('(');
288 for (i = 1; i <= oper->respc; ++i) {
289 if (i > 1)
290 printf(", ");
291 val_print(resp[i], oper->resp_type[i - 1]);
292 }
293 putchar(')');
294 }
295
296 putchar('\n');
297 }
298 }
299
300 if ((phone == PHONE_NS) && (method == IPC_M_CONNECT_ME_TO) &&
301 (retval == 0)) {
302 /* Connected to a service (through NS) */
303 service = IPC_GET_ARG2(pcall->question);
304 proto = proto_get_by_srv(service);
305 if (proto == NULL)
306 proto = proto_unknown;
307
308 cphone = IPC_GET_ARG5(*answer);
309 if ((display_mask & DM_SYSTEM) != 0) {
310 printf("Registering connection (phone %d, protocol: %s)\n", cphone,
311 proto->name);
312 }
313
314 ipcp_connection_set(cphone, 0, proto);
315 }
316}
317
318void ipcp_call_in(ipc_call_t *call, ipc_callid_t hash)
319{
320 ht_link_t *item;
321 pending_call_t *pcall;
322
323 if ((call->flags & IPC_CALL_ANSWERED) == 0) {
324 /* Not a response */
325 if ((display_mask & DM_IPC) != 0) {
326 printf("Not a response (hash %d)\n", hash);
327 }
328 return;
329 }
330
331 item = hash_table_find(&pending_calls, &hash);
332 if (item == NULL)
333 return; /* No matching question found */
334
335 /*
336 * Response matched to question.
337 */
338
339 pcall = hash_table_get_inst(item, pending_call_t, link);
340 hash_table_remove(&pending_calls, &hash);
341
342 parse_answer(hash, pcall, call);
343 free(pcall);
344}
345
346void ipcp_hangup(int phone, int rc)
347{
348 if ((display_mask & DM_SYSTEM) != 0) {
349 printf("Hang phone %d up -> %d\n", phone, rc);
350 ipcp_connection_clear(phone);
351 }
352}
353
354/** @}
355 */
Note: See TracBrowser for help on using the repository browser.