Rev 4055 | Rev 4439 | Go to most recent revision | Show entire file | Ignore 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 | } |