Rev 3448 | Go to most recent revision | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed
| Rev 3448 | Rev 3474 | ||
|---|---|---|---|
| Line 42... | Line 42... | ||
| 42 | #include "ipcp.h" |
42 | #include "ipcp.h" |
| 43 | 43 | ||
| 44 | #define IPCP_CALLID_SYNC 0 |
44 | #define IPCP_CALLID_SYNC 0 |
| 45 | 45 | ||
| 46 | typedef struct { |
46 | typedef struct { |
| 47 | int phone_hash; |
47 | ipcarg_t phone_hash; |
| 48 | ipc_call_t question; |
48 | ipc_call_t question; |
| - | 49 | oper_t *oper; |
|
| 49 | 50 | ||
| 50 | int call_hash; |
51 | ipc_callid_t call_hash; |
| 51 | 52 | ||
| 52 | link_t link; |
53 | link_t link; |
| 53 | } pending_call_t; |
54 | } pending_call_t; |
| 54 | 55 | ||
| 55 | typedef struct { |
56 | typedef struct { |
| Line 94... | Line 95... | ||
| 94 | pending_call_t *hs; |
95 | pending_call_t *hs; |
| 95 | 96 | ||
| 96 | // printf("pending_call_compare\n"); |
97 | // printf("pending_call_compare\n"); |
| 97 | hs = hash_table_get_instance(item, pending_call_t, link); |
98 | hs = hash_table_get_instance(item, pending_call_t, link); |
| 98 | 99 | ||
| - | 100 | // FIXME: this will fail if sizeof(long) < sizeof(void *). |
|
| 99 | return key[0] == hs->call_hash; |
101 | return key[0] == hs->call_hash; |
| 100 | } |
102 | } |
| 101 | 103 | ||
| 102 | static void pending_call_remove_callback(link_t *item) |
104 | static void pending_call_remove_callback(link_t *item) |
| 103 | { |
105 | { |
| Line 131... | Line 133... | ||
| 131 | /* Not a system method, try the user protocol. */ |
133 | /* Not a system method, try the user protocol. */ |
| 132 | oper = proto_get_oper(proto, method); |
134 | oper = proto_get_oper(proto, method); |
| 133 | } |
135 | } |
| 134 | 136 | ||
| 135 | if (oper != NULL) { |
137 | if (oper != NULL) { |
| 136 | printf("%s (%d)", oper->name, method); |
138 | printf("%s (%ld)", oper->name, method); |
| 137 | return; |
139 | return; |
| 138 | } |
140 | } |
| 139 | 141 | ||
| 140 | printf("%d", method); |
142 | printf("%ld", method); |
| 141 | } |
143 | } |
| 142 | 144 | ||
| 143 | void ipcp_init(void) |
145 | void ipcp_init(void) |
| 144 | { |
146 | { |
| 145 | ipc_m_desc_t *desc; |
147 | ipc_m_desc_t *desc; |
| 146 | oper_t *oper; |
148 | oper_t *oper; |
| 147 | 149 | ||
| - | 150 | val_type_t arg_def[OPER_MAX_ARGS] = { |
|
| - | 151 | V_INTEGER, |
|
| - | 152 | V_INTEGER, |
|
| - | 153 | V_INTEGER, |
|
| - | 154 | V_INTEGER, |
|
| - | 155 | V_INTEGER |
|
| - | 156 | }; |
|
| - | 157 | ||
| 148 | /* |
158 | /* |
| 149 | * Create a pseudo-protocol 'unknown' that has no known methods. |
159 | * Create a pseudo-protocol 'unknown' that has no known methods. |
| 150 | */ |
160 | */ |
| 151 | proto_unknown = proto_new("unknown"); |
161 | proto_unknown = proto_new("unknown"); |
| 152 | 162 | ||
| Line 156... | Line 166... | ||
| 156 | */ |
166 | */ |
| 157 | proto_system = proto_new("system"); |
167 | proto_system = proto_new("system"); |
| 158 | 168 | ||
| 159 | desc = ipc_methods; |
169 | desc = ipc_methods; |
| 160 | while (desc->number != 0) { |
170 | while (desc->number != 0) { |
| 161 | oper = oper_new(desc->name); |
171 | oper = oper_new(desc->name, OPER_MAX_ARGS, arg_def, V_INTEGER, |
| - | 172 | OPER_MAX_ARGS, arg_def); |
|
| 162 | proto_add_oper(proto_system, desc->number, oper); |
173 | proto_add_oper(proto_system, desc->number, oper); |
| 163 | 174 | ||
| 164 | ++desc; |
175 | ++desc; |
| 165 | } |
176 | } |
| 166 | 177 | ||
| Line 177... | Line 188... | ||
| 177 | { |
188 | { |
| 178 | pending_call_t *pcall; |
189 | pending_call_t *pcall; |
| 179 | proto_t *proto; |
190 | proto_t *proto; |
| 180 | unsigned long key[1]; |
191 | unsigned long key[1]; |
| 181 | oper_t *oper; |
192 | oper_t *oper; |
| - | 193 | ipcarg_t *args; |
|
| - | 194 | int i; |
|
| 182 | 195 | ||
| 183 | if (have_conn[phone]) proto = connections[phone].proto; |
196 | if (have_conn[phone]) proto = connections[phone].proto; |
| 184 | else proto = NULL; |
197 | else proto = NULL; |
| 185 | 198 | ||
| - | 199 | args = call->args; |
|
| - | 200 | ||
| 186 | if ((display_mask & DM_IPC) != 0) { |
201 | if ((display_mask & DM_IPC) != 0) { |
| 187 | printf("Call ID: 0x%x, phone: %d, proto: %s, method: ", hash, |
202 | printf("Call ID: 0x%lx, phone: %d, proto: %s, method: ", hash, |
| 188 | phone, (proto ? proto->name : "n/a")); |
203 | phone, (proto ? proto->name : "n/a")); |
| 189 | ipc_m_print(proto, IPC_GET_METHOD(*call)); |
204 | ipc_m_print(proto, IPC_GET_METHOD(*call)); |
| 190 | printf(" args: (%u, %u, %u, %u, %u)\n", |
205 | printf(" args: (%lu, %lu, %lu, %lu, %lu)\n", args[1], args[2], |
| 191 | IPC_GET_ARG1(*call), |
- | |
| 192 | IPC_GET_ARG2(*call), |
- | |
| 193 | IPC_GET_ARG3(*call), |
- | |
| 194 | IPC_GET_ARG4(*call), |
206 | args[3], args[4], args[5]); |
| 195 | IPC_GET_ARG5(*call) |
- | |
| 196 | ); |
- | |
| 197 | } |
207 | } |
| 198 | 208 | ||
| 199 | 209 | ||
| 200 | if ((display_mask & DM_USER) != 0) { |
210 | if ((display_mask & DM_USER) != 0) { |
| 201 | 211 | ||
| Line 208... | Line 218... | ||
| 208 | if (oper != NULL) { |
218 | if (oper != NULL) { |
| 209 | 219 | ||
| 210 | printf("%s(%d).%s", (proto ? proto->name : "n/a"), |
220 | printf("%s(%d).%s", (proto ? proto->name : "n/a"), |
| 211 | phone, (oper ? oper->name : "unknown")); |
221 | phone, (oper ? oper->name : "unknown")); |
| 212 | 222 | ||
| - | 223 | putchar('('); |
|
| 213 | printf("(%u, %u, %u, %u, %u)\n", |
224 | for (i = 1; i <= oper->argc; ++i) { |
| 214 | IPC_GET_ARG1(*call), |
225 | if (i > 1) printf(", "); |
| - | 226 | val_print(args[i], oper->arg_type[i - 1]); |
|
| - | 227 | } |
|
| 215 | IPC_GET_ARG2(*call), |
228 | putchar(')'); |
| - | 229 | ||
| - | 230 | if (oper->rv_type == V_VOID && oper->respc == 0) { |
|
| - | 231 | /* |
|
| - | 232 | * No response data (typically the task will |
|
| 216 | IPC_GET_ARG3(*call), |
233 | * not be interested in the response). |
| 217 | IPC_GET_ARG4(*call), |
234 | * We will not display response. |
| - | 235 | */ |
|
| 218 | IPC_GET_ARG5(*call) |
236 | putchar('.'); |
| 219 | ); |
237 | } |
| - | 238 | ||
| - | 239 | putchar('\n'); |
|
| 220 | } |
240 | } |
| - | 241 | } else { |
|
| - | 242 | oper = NULL; |
|
| 221 | } |
243 | } |
| 222 | 244 | ||
| 223 | /* Store call in hash table for response matching */ |
245 | /* Store call in hash table for response matching */ |
| 224 | 246 | ||
| 225 | pcall = malloc(sizeof(pending_call_t)); |
247 | pcall = malloc(sizeof(pending_call_t)); |
| 226 | pcall->phone_hash = phone; |
248 | pcall->phone_hash = phone; |
| 227 | pcall->question = *call; |
249 | pcall->question = *call; |
| 228 | pcall->call_hash = hash; |
250 | pcall->call_hash = hash; |
| - | 251 | pcall->oper = oper; |
|
| 229 | 252 | ||
| 230 | key[0] = hash; |
253 | key[0] = hash; |
| 231 | 254 | ||
| 232 | hash_table_insert(&pending_calls, key, &pcall->link); |
255 | hash_table_insert(&pending_calls, key, &pcall->link); |
| 233 | } |
256 | } |
| 234 | 257 | ||
| 235 | static void parse_answer(ipc_callid_t hash, pending_call_t *pcall, |
258 | static void parse_answer(ipc_callid_t hash, pending_call_t *pcall, |
| 236 | ipc_call_t *answer) |
259 | ipc_call_t *answer) |
| 237 | { |
260 | { |
| 238 | int phone; |
261 | ipcarg_t phone; |
| 239 | ipcarg_t method; |
262 | ipcarg_t method; |
| 240 | ipcarg_t service; |
263 | ipcarg_t service; |
| 241 | int retval; |
264 | ipcarg_t retval; |
| 242 | proto_t *proto; |
265 | proto_t *proto; |
| 243 | int cphone; |
266 | int cphone; |
| 244 | 267 | ||
| - | 268 | ipcarg_t *resp; |
|
| - | 269 | oper_t *oper; |
|
| - | 270 | int i; |
|
| - | 271 | ||
| 245 | // printf("parse_answer\n"); |
272 | // printf("parse_answer\n"); |
| 246 | 273 | ||
| 247 | phone = pcall->phone_hash; |
274 | phone = pcall->phone_hash; |
| 248 | method = IPC_GET_METHOD(pcall->question); |
275 | method = IPC_GET_METHOD(pcall->question); |
| 249 | retval = IPC_GET_RETVAL(*answer); |
276 | retval = IPC_GET_RETVAL(*answer); |
| 250 | 277 | ||
| - | 278 | resp = answer->args; |
|
| - | 279 | ||
| 251 | if ((display_mask & DM_IPC) != 0) { |
280 | if ((display_mask & DM_IPC) != 0) { |
| 252 | printf("Response to 0x%x: retval=%d, args = (%u, %u, %u, %u, %u)\n", |
281 | printf("Response to 0x%lx: retval=%ld, args = (%lu, %lu, %lu, %lu, %lu)\n", |
| 253 | hash, retval, IPC_GET_ARG1(*answer), |
282 | hash, retval, IPC_GET_ARG1(*answer), |
| 254 | IPC_GET_ARG2(*answer), IPC_GET_ARG3(*answer), |
283 | IPC_GET_ARG2(*answer), IPC_GET_ARG3(*answer), |
| 255 | IPC_GET_ARG4(*answer), IPC_GET_ARG5(*answer)); |
284 | IPC_GET_ARG4(*answer), IPC_GET_ARG5(*answer)); |
| 256 | } |
285 | } |
| 257 | 286 | ||
| 258 | if ((display_mask & DM_USER) != 0) { |
287 | if ((display_mask & DM_USER) != 0) { |
| - | 288 | oper = pcall->oper; |
|
| - | 289 | ||
| - | 290 | if (oper != NULL && (oper->rv_type != V_VOID || oper->respc > 0)) { |
|
| 259 | printf("-> %d\n", retval); |
291 | printf("->"); |
| - | 292 | ||
| - | 293 | if (oper->rv_type != V_VOID) { |
|
| - | 294 | putchar(' '); |
|
| - | 295 | val_print(retval, oper->rv_type); |
|
| - | 296 | } |
|
| - | 297 | ||
| - | 298 | if (oper->respc > 0) { |
|
| - | 299 | putchar(' '); |
|
| - | 300 | putchar('('); |
|
| - | 301 | for (i = 1; i <= oper->respc; ++i) { |
|
| - | 302 | if (i > 1) printf(", "); |
|
| - | 303 | val_print(resp[i], oper->resp_type[i - 1]); |
|
| - | 304 | } |
|
| - | 305 | putchar(')'); |
|
| - | 306 | } |
|
| - | 307 | ||
| - | 308 | putchar('\n'); |
|
| - | 309 | } |
|
| 260 | } |
310 | } |
| 261 | 311 | ||
| 262 | if (phone == 0 && method == IPC_M_CONNECT_ME_TO && retval == 0) { |
312 | if (phone == 0 && method == IPC_M_CONNECT_ME_TO && retval == 0) { |
| 263 | /* Connected to a service (through NS) */ |
313 | /* Connected to a service (through NS) */ |
| 264 | service = IPC_GET_ARG1(pcall->question); |
314 | service = IPC_GET_ARG1(pcall->question); |
| Line 279... | Line 329... | ||
| 279 | link_t *item; |
329 | link_t *item; |
| 280 | pending_call_t *pcall; |
330 | pending_call_t *pcall; |
| 281 | unsigned long key[1]; |
331 | unsigned long key[1]; |
| 282 | 332 | ||
| 283 | // printf("ipcp_call_in()\n"); |
333 | // printf("ipcp_call_in()\n"); |
| 284 | /* printf("phone: %d, method: ", call->in_phone_hash); |
- | |
| 285 | ipc_m_print(IPC_GET_METHOD(*call)); |
- | |
| 286 | printf(" args: (%u, %u, %u, %u, %u)\n", |
- | |
| 287 | IPC_GET_ARG1(*call), |
- | |
| 288 | IPC_GET_ARG2(*call), |
- | |
| 289 | IPC_GET_ARG3(*call), |
- | |
| 290 | IPC_GET_ARG4(*call), |
- | |
| 291 | IPC_GET_ARG5(*call) |
- | |
| 292 | );*/ |
- | |
| 293 | 334 | ||
| 294 | if ((hash & IPC_CALLID_ANSWERED) == 0 && hash != IPCP_CALLID_SYNC) { |
335 | if ((hash & IPC_CALLID_ANSWERED) == 0 && hash != IPCP_CALLID_SYNC) { |
| 295 | /* Not a response */ |
336 | /* Not a response */ |
| 296 | if ((display_mask & DM_IPC) != 0) { |
337 | if ((display_mask & DM_IPC) != 0) { |
| 297 | printf("Not a response (hash %d)\n", hash); |
338 | printf("Not a response (hash 0x%lx)\n", hash); |
| 298 | } |
339 | } |
| 299 | return; |
340 | return; |
| 300 | } |
341 | } |
| 301 | 342 | ||
| 302 | hash = hash & ~IPC_CALLID_ANSWERED; |
343 | hash = hash & ~IPC_CALLID_ANSWERED; |