Rev 4055 | Go to most recent revision | Show entire file | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed
Rev 4055 | Rev 4420 | ||
---|---|---|---|
Line 91... | Line 91... | ||
91 | * Otherwise return 0. |
91 | * Otherwise return 0. |
92 | */ |
92 | */ |
93 | static inline int method_is_forwardable(unative_t method) |
93 | static inline int method_is_forwardable(unative_t method) |
94 | { |
94 | { |
95 | switch (method) { |
95 | switch (method) { |
- | 96 | case IPC_M_CONNECTION_CLONE: |
|
- | 97 | case IPC_M_CONNECT_ME: |
|
96 | case IPC_M_PHONE_HUNGUP: |
98 | case IPC_M_PHONE_HUNGUP: |
97 | /* This message is meant only for the original recipient. */ |
99 | /* This message is meant only for the original recipient. */ |
98 | return 0; |
100 | return 0; |
99 | default: |
101 | default: |
100 | return 1; |
102 | return 1; |
Line 138... | Line 140... | ||
138 | * Return 0 otherwise. |
140 | * Return 0 otherwise. |
139 | */ |
141 | */ |
140 | static inline int answer_need_old(call_t *call) |
142 | static inline int answer_need_old(call_t *call) |
141 | { |
143 | { |
142 | switch (IPC_GET_METHOD(call->data)) { |
144 | switch (IPC_GET_METHOD(call->data)) { |
- | 145 | case IPC_M_CONNECTION_CLONE: |
|
- | 146 | case IPC_M_CONNECT_ME: |
|
143 | case IPC_M_CONNECT_TO_ME: |
147 | case IPC_M_CONNECT_TO_ME: |
144 | case IPC_M_CONNECT_ME_TO: |
148 | case IPC_M_CONNECT_ME_TO: |
145 | case IPC_M_SHARE_OUT: |
149 | case IPC_M_SHARE_OUT: |
146 | case IPC_M_SHARE_IN: |
150 | case IPC_M_SHARE_IN: |
147 | case IPC_M_DATA_WRITE: |
151 | case IPC_M_DATA_WRITE: |
Line 180... | Line 184... | ||
180 | } |
184 | } |
181 | 185 | ||
182 | if (!olddata) |
186 | if (!olddata) |
183 | return 0; |
187 | return 0; |
184 | 188 | ||
- | 189 | if (IPC_GET_METHOD(*olddata) == IPC_M_CONNECTION_CLONE) { |
|
- | 190 | phoneid = IPC_GET_ARG1(*olddata); |
|
- | 191 | phone_t *phone = &TASK->phones[phoneid]; |
|
- | 192 | if (IPC_GET_RETVAL(answer->data) != EOK) { |
|
- | 193 | /* |
|
- | 194 | * The recipient of the cloned phone rejected the offer. |
|
- | 195 | * In this case, the connection was established at the |
|
- | 196 | * request time and therefore we need to slam the phone. |
|
- | 197 | * We don't merely hangup as that would result in |
|
- | 198 | * sending IPC_M_HUNGUP to the third party on the |
|
- | 199 | * other side of the cloned phone. |
|
- | 200 | */ |
|
- | 201 | mutex_lock(&phone->lock); |
|
- | 202 | if (phone->state == IPC_PHONE_CONNECTED) { |
|
- | 203 | spinlock_lock(&phone->callee->lock); |
|
- | 204 | list_remove(&phone->link); |
|
- | 205 | phone->state = IPC_PHONE_SLAMMED; |
|
- | 206 | spinlock_unlock(&phone->callee->lock); |
|
- | 207 | } |
|
- | 208 | mutex_unlock(&phone->lock); |
|
- | 209 | } |
|
- | 210 | } else if (IPC_GET_METHOD(*olddata) == IPC_M_CONNECT_ME) { |
|
- | 211 | phone_t *phone = (phone_t *)IPC_GET_ARG5(*olddata); |
|
- | 212 | if (IPC_GET_RETVAL(answer->data) != EOK) { |
|
- | 213 | /* |
|
- | 214 | * The other party on the cloned phoned rejected our |
|
- | 215 | * request for connection on the protocol level. |
|
- | 216 | * We need to break the connection without sending |
|
- | 217 | * IPC_M_HUNGUP back. |
|
- | 218 | */ |
|
- | 219 | mutex_lock(&phone->lock); |
|
- | 220 | if (phone->state == IPC_PHONE_CONNECTED) { |
|
- | 221 | spinlock_lock(&phone->callee->lock); |
|
- | 222 | list_remove(&phone->link); |
|
- | 223 | phone->state = IPC_PHONE_SLAMMED; |
|
- | 224 | spinlock_unlock(&phone->callee->lock); |
|
- | 225 | } |
|
- | 226 | mutex_unlock(&phone->lock); |
|
- | 227 | } |
|
185 | if (IPC_GET_METHOD(*olddata) == IPC_M_CONNECT_TO_ME) { |
228 | } else if (IPC_GET_METHOD(*olddata) == IPC_M_CONNECT_TO_ME) { |
186 | phoneid = IPC_GET_ARG5(*olddata); |
229 | phoneid = IPC_GET_ARG5(*olddata); |
187 | if (IPC_GET_RETVAL(answer->data)) { |
230 | if (IPC_GET_RETVAL(answer->data) != EOK) { |
188 | /* The connection was not accepted */ |
231 | /* The connection was not accepted */ |
189 | phone_dealloc(phoneid); |
232 | phone_dealloc(phoneid); |
190 | } else { |
233 | } else { |
191 | /* The connection was accepted */ |
234 | /* The connection was accepted */ |
192 | phone_connect(phoneid, &answer->sender->answerbox); |
235 | phone_connect(phoneid, &answer->sender->answerbox); |
Line 194... | Line 237... | ||
194 | IPC_SET_ARG5(answer->data, |
237 | IPC_SET_ARG5(answer->data, |
195 | (unative_t) &TASK->phones[phoneid]); |
238 | (unative_t) &TASK->phones[phoneid]); |
196 | } |
239 | } |
197 | } else if (IPC_GET_METHOD(*olddata) == IPC_M_CONNECT_ME_TO) { |
240 | } else if (IPC_GET_METHOD(*olddata) == IPC_M_CONNECT_ME_TO) { |
198 | /* If the users accepted call, connect */ |
241 | /* If the users accepted call, connect */ |
199 | if (!IPC_GET_RETVAL(answer->data)) { |
242 | if (IPC_GET_RETVAL(answer->data) == EOK) { |
200 | ipc_phone_connect((phone_t *) IPC_GET_ARG5(*olddata), |
243 | ipc_phone_connect((phone_t *) IPC_GET_ARG5(*olddata), |
201 | &TASK->answerbox); |
244 | &TASK->answerbox); |
202 | } |
245 | } |
203 | } else if (IPC_GET_METHOD(*olddata) == IPC_M_SHARE_OUT) { |
246 | } else if (IPC_GET_METHOD(*olddata) == IPC_M_SHARE_OUT) { |
204 | if (!IPC_GET_RETVAL(answer->data)) { |
247 | if (!IPC_GET_RETVAL(answer->data)) { |
Line 306... | Line 349... | ||
306 | size_t size; |
349 | size_t size; |
307 | uintptr_t src; |
350 | uintptr_t src; |
308 | int rc; |
351 | int rc; |
309 | 352 | ||
310 | switch (IPC_GET_METHOD(call->data)) { |
353 | switch (IPC_GET_METHOD(call->data)) { |
- | 354 | case IPC_M_CONNECTION_CLONE: { |
|
- | 355 | phone_t *cloned_phone; |
|
- | 356 | GET_CHECK_PHONE(cloned_phone, IPC_GET_ARG1(call->data), |
|
- | 357 | return ENOENT); |
|
- | 358 | if (cloned_phone < phone) { |
|
- | 359 | mutex_lock(&cloned_phone->lock); |
|
- | 360 | mutex_lock(&phone->lock); |
|
- | 361 | } else { |
|
- | 362 | mutex_lock(&phone->lock); |
|
- | 363 | mutex_lock(&cloned_phone->lock); |
|
- | 364 | } |
|
- | 365 | if ((cloned_phone->state != IPC_PHONE_CONNECTED) || |
|
- | 366 | phone->state != IPC_PHONE_CONNECTED) { |
|
- | 367 | mutex_unlock(&cloned_phone->lock); |
|
- | 368 | mutex_unlock(&phone->lock); |
|
- | 369 | return EINVAL; |
|
- | 370 | } |
|
- | 371 | /* |
|
- | 372 | * We can be pretty sure now that both tasks exist and we are |
|
- | 373 | * connected to them. As we continue to hold the phone locks, |
|
- | 374 | * we are effectively preventing them from finishing their |
|
- | 375 | * potential cleanup. |
|
- | 376 | */ |
|
- | 377 | newphid = phone_alloc(phone->callee->task); |
|
- | 378 | if (newphid < 0) { |
|
- | 379 | mutex_unlock(&cloned_phone->lock); |
|
- | 380 | mutex_unlock(&phone->lock); |
|
- | 381 | return ELIMIT; |
|
- | 382 | } |
|
- | 383 | ipc_phone_connect(&phone->callee->task->phones[newphid], |
|
- | 384 | cloned_phone->callee); |
|
- | 385 | mutex_unlock(&cloned_phone->lock); |
|
- | 386 | mutex_unlock(&phone->lock); |
|
- | 387 | /* Set the new phone for the callee. */ |
|
- | 388 | IPC_SET_ARG1(call->data, newphid); |
|
- | 389 | break; |
|
- | 390 | } |
|
- | 391 | case IPC_M_CONNECT_ME: |
|
- | 392 | IPC_SET_ARG5(call->data, (unative_t) phone); |
|
- | 393 | break; |
|
311 | case IPC_M_CONNECT_ME_TO: |
394 | case IPC_M_CONNECT_ME_TO: |
312 | newphid = phone_alloc(); |
395 | newphid = phone_alloc(TASK); |
313 | if (newphid < 0) |
396 | if (newphid < 0) |
314 | return ELIMIT; |
397 | return ELIMIT; |
315 | /* Set arg5 for server */ |
398 | /* Set arg5 for server */ |
316 | IPC_SET_ARG5(call->data, (unative_t) &TASK->phones[newphid]); |
399 | IPC_SET_ARG5(call->data, (unative_t) &TASK->phones[newphid]); |
317 | call->flags |= IPC_CALL_CONN_ME_TO; |
400 | call->flags |= IPC_CALL_CONN_ME_TO; |
Line 330... | Line 413... | ||
330 | break; |
413 | break; |
331 | case IPC_M_DATA_WRITE: |
414 | case IPC_M_DATA_WRITE: |
332 | src = IPC_GET_ARG1(call->data); |
415 | src = IPC_GET_ARG1(call->data); |
333 | size = IPC_GET_ARG2(call->data); |
416 | size = IPC_GET_ARG2(call->data); |
334 | 417 | ||
335 | if ((size <= 0) || (size > DATA_XFER_LIMIT)) |
418 | if (size > DATA_XFER_LIMIT) |
336 | return ELIMIT; |
419 | return ELIMIT; |
337 | 420 | ||
338 | call->buffer = (uint8_t *) malloc(size, 0); |
421 | call->buffer = (uint8_t *) malloc(size, 0); |
339 | rc = copy_from_uspace(call->buffer, (void *) src, size); |
422 | rc = copy_from_uspace(call->buffer, (void *) src, size); |
340 | if (rc != 0) { |
423 | if (rc != 0) { |
Line 397... | Line 480... | ||
397 | static int process_request(answerbox_t *box, call_t *call) |
480 | static int process_request(answerbox_t *box, call_t *call) |
398 | { |
481 | { |
399 | int phoneid; |
482 | int phoneid; |
400 | 483 | ||
401 | if (IPC_GET_METHOD(call->data) == IPC_M_CONNECT_TO_ME) { |
484 | if (IPC_GET_METHOD(call->data) == IPC_M_CONNECT_TO_ME) { |
402 | phoneid = phone_alloc(); |
485 | phoneid = phone_alloc(TASK); |
403 | if (phoneid < 0) { /* Failed to allocate phone */ |
486 | if (phoneid < 0) { /* Failed to allocate phone */ |
404 | IPC_SET_RETVAL(call->data, ELIMIT); |
487 | IPC_SET_RETVAL(call->data, ELIMIT); |
405 | ipc_answer(box, call); |
488 | ipc_answer(box, call); |
406 | return -1; |
489 | return -1; |
407 | } |
490 | } |