Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • kernel/generic/src/ipc/sysipc.c

    r79ae36dd rab34cc9  
    4040#include <debug.h>
    4141#include <ipc/ipc.h>
    42 #include <ipc/ipc_methods.h>
     42#include <abi/ipc/methods.h>
    4343#include <ipc/sysipc.h>
    4444#include <ipc/irq.h>
    4545#include <ipc/ipcrsc.h>
     46#include <ipc/event.h>
    4647#include <ipc/kbox.h>
    4748#include <synch/waitq.h>
     
    5354#include <mm/as.h>
    5455#include <print.h>
     56#include <macros.h>
    5557
    5658/**
     
    134136        case IPC_M_DATA_WRITE:
    135137        case IPC_M_DATA_READ:
     138        case IPC_M_STATE_CHANGE_AUTHORIZE:
    136139                return true;
    137140        default:
     
    164167        case IPC_M_DATA_WRITE:
    165168        case IPC_M_DATA_READ:
     169        case IPC_M_STATE_CHANGE_AUTHORIZE:
    166170                return true;
    167171        default:
     
    249253                        /* The connection was accepted */
    250254                        phone_connect(phoneid, &answer->sender->answerbox);
    251                         /* Set 'task hash' as arg4 of response */
    252                         IPC_SET_ARG4(answer->data, (sysarg_t) TASK);
    253255                        /* Set 'phone hash' as arg5 of response */
    254256                        IPC_SET_ARG5(answer->data,
     
    334336                free(answer->buffer);
    335337                answer->buffer = NULL;
     338        } else if (IPC_GET_IMETHOD(*olddata) == IPC_M_STATE_CHANGE_AUTHORIZE) {
     339                if (!IPC_GET_RETVAL(answer->data)) {
     340                        /* The recipient authorized the change of state. */
     341                        phone_t *recipient_phone;
     342                        task_t *other_task_s;
     343                        task_t *other_task_r;
     344                        int rc;
     345
     346                        rc = phone_get(IPC_GET_ARG1(answer->data),
     347                            &recipient_phone);
     348                        if (rc != EOK) {
     349                                IPC_SET_RETVAL(answer->data, ENOENT);
     350                                return ENOENT;
     351                        }
     352
     353                        mutex_lock(&recipient_phone->lock);
     354                        if (recipient_phone->state != IPC_PHONE_CONNECTED) {
     355                                mutex_unlock(&recipient_phone->lock);
     356                                IPC_SET_RETVAL(answer->data, EINVAL);
     357                                return EINVAL;
     358                        }
     359
     360                        other_task_r = recipient_phone->callee->task;
     361                        other_task_s = (task_t *) IPC_GET_ARG5(*olddata);
     362
     363                        /*
     364                         * See if both the sender and the recipient meant the
     365                         * same third party task.
     366                         */
     367                        if (other_task_r != other_task_s) {
     368                                IPC_SET_RETVAL(answer->data, EINVAL);
     369                                rc = EINVAL;
     370                        } else {
     371                                rc = event_task_notify_5(other_task_r,
     372                                    EVENT_TASK_STATE_CHANGE, false,
     373                                    IPC_GET_ARG1(*olddata),
     374                                    IPC_GET_ARG2(*olddata),
     375                                    IPC_GET_ARG3(*olddata),
     376                                    LOWER32(olddata->task_id),
     377                                    UPPER32(olddata->task_id));
     378                                IPC_SET_RETVAL(answer->data, rc);
     379                        }
     380
     381                        mutex_unlock(&recipient_phone->lock);
     382                        return rc;
     383                }
    336384        }
    337385       
     
    427475        case IPC_M_DATA_READ: {
    428476                size_t size = IPC_GET_ARG2(call->data);
    429                 if (size <= 0)
    430                         return ELIMIT;
    431477                if (size > DATA_XFER_LIMIT) {
    432478                        int flags = IPC_GET_ARG3(call->data);
     
    458504                }
    459505               
     506                break;
     507        }
     508        case IPC_M_STATE_CHANGE_AUTHORIZE: {
     509                phone_t *sender_phone;
     510                task_t *other_task_s;
     511
     512                if (phone_get(IPC_GET_ARG5(call->data), &sender_phone) != EOK)
     513                        return ENOENT;
     514
     515                mutex_lock(&sender_phone->lock);
     516                if (sender_phone->state != IPC_PHONE_CONNECTED) {
     517                        mutex_unlock(&sender_phone->lock);
     518                        return EINVAL;
     519                }
     520
     521                other_task_s = sender_phone->callee->task;
     522
     523                mutex_unlock(&sender_phone->lock);
     524
     525                /* Remember the third party task hash. */
     526                IPC_SET_ARG5(call->data, (sysarg_t) other_task_s);
    460527                break;
    461528        }
Note: See TracChangeset for help on using the changeset viewer.