Rev 1086 | Rev 1090 | Go to most recent revision | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed
| Rev 1086 | Rev 1088 | ||
|---|---|---|---|
| Line 73... | Line 73... | ||
| 73 | /* Functions that preprocess answer before sending |
73 | /* Functions that preprocess answer before sending |
| 74 | * it to the recepient |
74 | * it to the recepient |
| 75 | */ |
75 | */ |
| 76 | 76 | ||
| 77 | /** Return true if the caller (ipc_answer) should save |
77 | /** Return true if the caller (ipc_answer) should save |
| 78 | * the old call contents and call answer_preprocess |
78 | * the old call contents for answer_preprocess |
| 79 | */ |
79 | */ |
| 80 | static inline int answer_will_preprocess(call_t *call) |
80 | static inline int answer_need_old(call_t *call) |
| 81 | { |
81 | { |
| 82 | if (IPC_GET_METHOD(call->data) == IPC_M_CONNECT_TO_ME) |
82 | if (IPC_GET_METHOD(call->data) == IPC_M_CONNECT_TO_ME) |
| 83 | return 1; |
83 | return 1; |
| 84 | if (IPC_GET_METHOD(call->data) == IPC_M_CONNECT_ME_TO) |
84 | if (IPC_GET_METHOD(call->data) == IPC_M_CONNECT_ME_TO) |
| 85 | return 1; |
85 | return 1; |
| Line 89... | Line 89... | ||
| 89 | /** Interpret process answer as control information */ |
89 | /** Interpret process answer as control information */ |
| 90 | static inline void answer_preprocess(call_t *answer, ipc_data_t *olddata) |
90 | static inline void answer_preprocess(call_t *answer, ipc_data_t *olddata) |
| 91 | { |
91 | { |
| 92 | int phoneid; |
92 | int phoneid; |
| 93 | 93 | ||
| - | 94 | if (IPC_GET_RETVAL(answer->data) == EHANGUP) { |
|
| - | 95 | /* Atomic operation */ |
|
| - | 96 | answer->data.phone->callee = NULL; |
|
| - | 97 | } |
|
| - | 98 | ||
| - | 99 | if (!olddata) |
|
| - | 100 | return; |
|
| - | 101 | ||
| 94 | if (IPC_GET_METHOD(*olddata) == IPC_M_CONNECT_TO_ME) { |
102 | if (IPC_GET_METHOD(*olddata) == IPC_M_CONNECT_TO_ME) { |
| 95 | phoneid = IPC_GET_ARG3(*olddata); |
103 | phoneid = IPC_GET_ARG3(*olddata); |
| 96 | if (IPC_GET_RETVAL(answer->data)) { |
104 | if (IPC_GET_RETVAL(answer->data)) { |
| 97 | /* The connection was not accepted */ |
105 | /* The connection was not accepted */ |
| 98 | phone_dealloc(phoneid); |
106 | phone_dealloc(phoneid); |
| 99 | } else { |
107 | } else { |
| 100 | /* The connection was accepted */ |
108 | /* The connection was accepted */ |
| 101 | phone_connect(phoneid,&answer->sender->answerbox); |
109 | phone_connect(phoneid,&answer->sender->answerbox); |
| 102 | } |
110 | } |
| 103 | } else if (IPC_GET_METHOD(*olddata) == IPC_M_CONNECT_ME_TO) { |
111 | } else if (IPC_GET_METHOD(*olddata) == IPC_M_CONNECT_ME_TO) { |
| 104 | /* If the users accepted call, connect */ |
112 | /* If the users accepted call, connect */ |
| 105 | if (!IPC_GET_RETVAL(answer->data)) { |
113 | if (!IPC_GET_RETVAL(answer->data)) { |
| Line 115... | Line 123... | ||
| 115 | */ |
123 | */ |
| 116 | 124 | ||
| 117 | /** Do basic kernel processing of received call answer */ |
125 | /** Do basic kernel processing of received call answer */ |
| 118 | static int process_answer(answerbox_t *box,call_t *call) |
126 | static int process_answer(answerbox_t *box,call_t *call) |
| 119 | { |
127 | { |
| - | 128 | if (IPC_GET_RETVAL(call->data) == EHANGUP && \ |
|
| - | 129 | call->flags & IPC_CALL_FORWARDED) |
|
| - | 130 | IPC_SET_RETVAL(call->data, EFORWARD); |
|
| 120 | return 0; |
131 | return 0; |
| 121 | } |
132 | } |
| 122 | 133 | ||
| 123 | /** Do basic kernel processing of received call request |
134 | /** Do basic kernel processing of received call request |
| 124 | * |
135 | * |
| Line 273... | Line 284... | ||
| 273 | 284 | ||
| 274 | call = get_call(callid); |
285 | call = get_call(callid); |
| 275 | if (!call) |
286 | if (!call) |
| 276 | return ENOENT; |
287 | return ENOENT; |
| 277 | 288 | ||
| - | 289 | call->flags |= IPC_CALL_FORWARDED; |
|
| - | 290 | ||
| 278 | GET_CHECK_PHONE(phone, phoneid, { |
291 | GET_CHECK_PHONE(phone, phoneid, { |
| 279 | IPC_SET_RETVAL(call->data, EFORWARD); |
292 | IPC_SET_RETVAL(call->data, EFORWARD); |
| 280 | ipc_answer(&TASK->answerbox, call); |
293 | ipc_answer(&TASK->answerbox, call); |
| 281 | return ENOENT; |
294 | return ENOENT; |
| 282 | }); |
295 | }); |
| Line 296... | Line 309... | ||
| 296 | } else { |
309 | } else { |
| 297 | IPC_SET_METHOD(call->data, method); |
310 | IPC_SET_METHOD(call->data, method); |
| 298 | IPC_SET_ARG1(call->data, arg1); |
311 | IPC_SET_ARG1(call->data, arg1); |
| 299 | } |
312 | } |
| 300 | 313 | ||
| 301 | ipc_forward(call, phone, &TASK->answerbox); |
314 | return ipc_forward(call, phone, &TASK->answerbox); |
| 302 | - | ||
| 303 | return 0; |
- | |
| 304 | } |
315 | } |
| 305 | 316 | ||
| 306 | /** Send IPC answer */ |
317 | /** Send IPC answer */ |
| 307 | __native sys_ipc_answer_fast(__native callid, __native retval, |
318 | __native sys_ipc_answer_fast(__native callid, __native retval, |
| 308 | __native arg1, __native arg2) |
319 | __native arg1, __native arg2) |
| 309 | { |
320 | { |
| 310 | call_t *call; |
321 | call_t *call; |
| 311 | ipc_data_t saved_data; |
322 | ipc_data_t saved_data; |
| 312 | int preprocess = 0; |
323 | int saveddata = 0; |
| 313 | 324 | ||
| 314 | call = get_call(callid); |
325 | call = get_call(callid); |
| 315 | if (!call) |
326 | if (!call) |
| 316 | return ENOENT; |
327 | return ENOENT; |
| 317 | 328 | ||
| 318 | if (answer_will_preprocess(call)) { |
329 | if (answer_need_old(call)) { |
| 319 | memcpy(&saved_data, &call->data, sizeof(call->data)); |
330 | memcpy(&saved_data, &call->data, sizeof(call->data)); |
| 320 | preprocess = 1; |
331 | saveddata = 1; |
| 321 | } |
332 | } |
| 322 | 333 | ||
| 323 | IPC_SET_RETVAL(call->data, retval); |
334 | IPC_SET_RETVAL(call->data, retval); |
| 324 | IPC_SET_ARG1(call->data, arg1); |
335 | IPC_SET_ARG1(call->data, arg1); |
| 325 | IPC_SET_ARG2(call->data, arg2); |
336 | IPC_SET_ARG2(call->data, arg2); |
| 326 | - | ||
| 327 | if (preprocess) |
- | |
| 328 | answer_preprocess(call, &saved_data); |
337 | answer_preprocess(call, saveddata ? &saved_data : NULL); |
| 329 | 338 | ||
| 330 | ipc_answer(&TASK->answerbox, call); |
339 | ipc_answer(&TASK->answerbox, call); |
| 331 | return 0; |
340 | return 0; |
| 332 | } |
341 | } |
| 333 | 342 | ||
| 334 | /** Send IPC answer */ |
343 | /** Send IPC answer */ |
| 335 | __native sys_ipc_answer(__native callid, ipc_data_t *data) |
344 | __native sys_ipc_answer(__native callid, ipc_data_t *data) |
| 336 | { |
345 | { |
| 337 | call_t *call; |
346 | call_t *call; |
| 338 | ipc_data_t saved_data; |
347 | ipc_data_t saved_data; |
| 339 | int preprocess = 0; |
348 | int saveddata = 0; |
| 340 | 349 | ||
| 341 | call = get_call(callid); |
350 | call = get_call(callid); |
| 342 | if (!call) |
351 | if (!call) |
| 343 | return ENOENT; |
352 | return ENOENT; |
| 344 | 353 | ||
| 345 | if (answer_will_preprocess(call)) { |
354 | if (answer_need_old(call)) { |
| 346 | memcpy(&saved_data, &call->data, sizeof(call->data)); |
355 | memcpy(&saved_data, &call->data, sizeof(call->data)); |
| 347 | preprocess = 1; |
356 | saveddata = 1; |
| 348 | } |
357 | } |
| 349 | copy_from_uspace(&call->data.args, &data->args, |
358 | copy_from_uspace(&call->data.args, &data->args, |
| 350 | sizeof(call->data.args)); |
359 | sizeof(call->data.args)); |
| 351 | 360 | ||
| 352 | if (preprocess) |
- | |
| 353 | answer_preprocess(call, &saved_data); |
361 | answer_preprocess(call, saveddata ? &saved_data : NULL); |
| 354 | 362 | ||
| 355 | ipc_answer(&TASK->answerbox, call); |
363 | ipc_answer(&TASK->answerbox, call); |
| 356 | 364 | ||
| 357 | return 0; |
365 | return 0; |
| 358 | } |
366 | } |
| Line 446... | Line 454... | ||
| 446 | { |
454 | { |
| 447 | call_t *call; |
455 | call_t *call; |
| 448 | 456 | ||
| 449 | restart: |
457 | restart: |
| 450 | call = ipc_wait_for_call(&TASK->answerbox, flags); |
458 | call = ipc_wait_for_call(&TASK->answerbox, flags); |
| - | 459 | if (!call) |
|
| - | 460 | return 0; |
|
| 451 | 461 | ||
| 452 | if (call->flags & IPC_CALL_ANSWERED) { |
462 | if (call->flags & IPC_CALL_ANSWERED) { |
| 453 | if (process_answer(&TASK->answerbox, call)) |
463 | if (process_answer(&TASK->answerbox, call)) |
| 454 | goto restart; |
464 | goto restart; |
| 455 | 465 | ||