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 |