Subversion Repositories HelenOS-historic

Rev

Rev 1297 | Rev 1346 | Go to most recent revision | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 1297 Rev 1329
Line 38... Line 38...
38
#include <ipc/ipcrsc.h>
38
#include <ipc/ipcrsc.h>
39
#include <arch/interrupt.h>
39
#include <arch/interrupt.h>
40
#include <print.h>
40
#include <print.h>
41
#include <syscall/copy.h>
41
#include <syscall/copy.h>
42
#include <security/cap.h>
42
#include <security/cap.h>
-
 
43
#include <mm/as.h>
43
 
44
 
44
#define GET_CHECK_PHONE(phone,phoneid,err) { \
45
#define GET_CHECK_PHONE(phone,phoneid,err) { \
45
      if (phoneid > IPC_MAX_PHONES) { err; } \
46
      if (phoneid > IPC_MAX_PHONES) { err; } \
46
      phone = &TASK->phones[phoneid]; \
47
      phone = &TASK->phones[phoneid]; \
47
}
48
}
Line 80... Line 81...
80
{
81
{
81
    if (IPC_GET_METHOD(call->data) == IPC_M_CONNECT_TO_ME)
82
    if (IPC_GET_METHOD(call->data) == IPC_M_CONNECT_TO_ME)
82
        return 1;
83
        return 1;
83
    if (IPC_GET_METHOD(call->data) == IPC_M_CONNECT_ME_TO)
84
    if (IPC_GET_METHOD(call->data) == IPC_M_CONNECT_ME_TO)
84
        return 1;
85
        return 1;
-
 
86
    if (IPC_GET_METHOD(call->data) == IPC_M_AS_SEND)
-
 
87
        return 1;
85
    return 0;
88
    return 0;
86
}
89
}
87
 
90
 
88
/** Interpret process answer as control information */
91
/** Interpret process answer as control information */
89
static inline void answer_preprocess(call_t *answer, ipc_data_t *olddata)
92
static inline int answer_preprocess(call_t *answer, ipc_data_t *olddata)
90
{
93
{
91
    int phoneid;
94
    int phoneid;
92
 
95
 
93
    if (IPC_GET_RETVAL(answer->data) == EHANGUP) {
96
    if (IPC_GET_RETVAL(answer->data) == EHANGUP) {
94
        /* In case of forward, hangup the forwared phone,
97
        /* In case of forward, hangup the forwared phone,
Line 103... Line 106...
103
        spinlock_unlock(&TASK->answerbox.lock);
106
        spinlock_unlock(&TASK->answerbox.lock);
104
        spinlock_unlock(&answer->data.phone->lock);
107
        spinlock_unlock(&answer->data.phone->lock);
105
    }
108
    }
106
 
109
 
107
    if (!olddata)
110
    if (!olddata)
108
        return;
111
        return 0;
109
 
112
 
110
    if (IPC_GET_METHOD(*olddata) == IPC_M_CONNECT_TO_ME) {
113
    if (IPC_GET_METHOD(*olddata) == IPC_M_CONNECT_TO_ME) {
111
        phoneid = IPC_GET_ARG3(*olddata);
114
        phoneid = IPC_GET_ARG3(*olddata);
112
        if (IPC_GET_RETVAL(answer->data)) {
115
        if (IPC_GET_RETVAL(answer->data)) {
113
            /* The connection was not accepted */
116
            /* The connection was not accepted */
Line 122... Line 125...
122
        /* If the users accepted call, connect */
125
        /* If the users accepted call, connect */
123
        if (!IPC_GET_RETVAL(answer->data)) {
126
        if (!IPC_GET_RETVAL(answer->data)) {
124
            ipc_phone_connect((phone_t *)IPC_GET_ARG3(*olddata),
127
            ipc_phone_connect((phone_t *)IPC_GET_ARG3(*olddata),
125
                      &TASK->answerbox);
128
                      &TASK->answerbox);
126
        }
129
        }
-
 
130
    } else if (IPC_GET_METHOD(*olddata) == IPC_M_AS_SEND) {
-
 
131
        if (!IPC_GET_RETVAL(answer->data)) { /* Accepted, handle As_area receival */
-
 
132
            return as_area_steal(answer->sender,
-
 
133
                         IPC_GET_ARG2(*olddata),IPC_GET_ARG3(*olddata),
-
 
134
                         IPC_GET_ARG1(answer->data));
-
 
135
        }
127
    }
136
    }
-
 
137
    return 0;
128
}
138
}
129
 
139
 
130
/** Called before the request is sent
140
/** Called before the request is sent
131
 *
141
 *
132
 * @return 0 - no error, -1 - report error to user
142
 * @return 0 - no error, -1 - report error to user
133
 */
143
 */
134
static int request_preprocess(call_t *call)
144
static int request_preprocess(call_t *call)
135
{
145
{
136
    int newphid;
146
    int newphid;
-
 
147
    size_t size;
137
 
148
 
138
    switch (IPC_GET_METHOD(call->data)) {
149
    switch (IPC_GET_METHOD(call->data)) {
139
    case IPC_M_CONNECT_ME_TO:
150
    case IPC_M_CONNECT_ME_TO:
140
        newphid = phone_alloc();
151
        newphid = phone_alloc();
141
        if (newphid < 0)
152
        if (newphid < 0)
Line 143... Line 154...
143
        /* Set arg3 for server */
154
        /* Set arg3 for server */
144
        IPC_SET_ARG3(call->data, (__native)&TASK->phones[newphid]);
155
        IPC_SET_ARG3(call->data, (__native)&TASK->phones[newphid]);
145
        call->flags |= IPC_CALL_CONN_ME_TO;
156
        call->flags |= IPC_CALL_CONN_ME_TO;
146
        call->private = newphid;
157
        call->private = newphid;
147
        break;
158
        break;
-
 
159
    case IPC_M_AS_SEND:
-
 
160
        size = as_get_size(IPC_GET_ARG2(call->data));
-
 
161
        if (!size) {
-
 
162
            return EPERM;
-
 
163
        }
-
 
164
        IPC_SET_ARG3(call->data, size);
-
 
165
        break;
148
    default:
166
    default:
149
        break;
167
        break;
150
    }
168
    }
151
    return 0;
169
    return 0;
152
}
170
}
Line 374... Line 392...
374
                 __native arg1, __native arg2)
392
                 __native arg1, __native arg2)
375
{
393
{
376
    call_t *call;
394
    call_t *call;
377
    ipc_data_t saved_data;
395
    ipc_data_t saved_data;
378
    int saveddata = 0;
396
    int saveddata = 0;
-
 
397
    int rc;
379
 
398
 
380
    call = get_call(callid);
399
    call = get_call(callid);
381
    if (!call)
400
    if (!call)
382
        return ENOENT;
401
        return ENOENT;
383
 
402
 
Line 387... Line 406...
387
    }
406
    }
388
 
407
 
389
    IPC_SET_RETVAL(call->data, retval);
408
    IPC_SET_RETVAL(call->data, retval);
390
    IPC_SET_ARG1(call->data, arg1);
409
    IPC_SET_ARG1(call->data, arg1);
391
    IPC_SET_ARG2(call->data, arg2);
410
    IPC_SET_ARG2(call->data, arg2);
392
    answer_preprocess(call, saveddata ? &saved_data : NULL);
411
    rc = answer_preprocess(call, saveddata ? &saved_data : NULL);
393
 
412
 
394
    ipc_answer(&TASK->answerbox, call);
413
    ipc_answer(&TASK->answerbox, call);
395
    return 0;
414
    return rc;
396
}
415
}
397
 
416
 
398
/** Send IPC answer */
417
/** Send IPC answer */
399
__native sys_ipc_answer(__native callid, ipc_data_t *data)
418
__native sys_ipc_answer(__native callid, ipc_data_t *data)
400
{
419
{
Line 414... Line 433...
414
    rc = copy_from_uspace(&call->data.args, &data->args,
433
    rc = copy_from_uspace(&call->data.args, &data->args,
415
             sizeof(call->data.args));
434
             sizeof(call->data.args));
416
    if (rc != 0)
435
    if (rc != 0)
417
        return rc;
436
        return rc;
418
 
437
 
419
    answer_preprocess(call, saveddata ? &saved_data : NULL);
438
    rc = answer_preprocess(call, saveddata ? &saved_data : NULL);
420
   
439
   
421
    ipc_answer(&TASK->answerbox, call);
440
    ipc_answer(&TASK->answerbox, call);
422
 
441
 
423
    return 0;
442
    return rc;
424
}
443
}
425
 
444
 
426
/** Hang up the phone
445
/** Hang up the phone
427
 *
446
 *
428
 */
447
 */