Subversion Repositories HelenOS

Rev

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