2 * Copyright (c) 2012 Jakub Jermar
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
9 * - Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * - Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
14 * - The name of the author may not be used to endorse or promote products
15 * derived from this software without specific prior written permission.
17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
18 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
19 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
21 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
22 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29 /** @addtogroup genericipc
35 #include <ipc/sysipc_ops.h>
37 #include <ipc/ipcrsc.h>
38 #include <synch/mutex.h>
39 #include <proc/task.h>
40 #include <abi/errno.h>
43 static int request_preprocess(call_t
*call
, phone_t
*phone
)
47 kobject_t
*sender_obj
= kobject_get(TASK
, IPC_GET_ARG5(call
->data
),
52 mutex_lock(&sender_obj
->phone
->lock
);
53 if (sender_obj
->phone
->state
!= IPC_PHONE_CONNECTED
) {
54 mutex_unlock(&sender_obj
->phone
->lock
);
55 kobject_put(sender_obj
);
59 other_task_s
= sender_obj
->phone
->callee
->task
;
61 mutex_unlock(&sender_obj
->phone
->lock
);
63 /* Remember the third party task hash. */
64 IPC_SET_ARG5(call
->data
, (sysarg_t
) other_task_s
);
66 kobject_put(sender_obj
);
70 static int answer_preprocess(call_t
*answer
, ipc_data_t
*olddata
)
74 if (!IPC_GET_RETVAL(answer
->data
)) {
75 /* The recipient authorized the change of state. */
79 kobject_t
*recipient_obj
= kobject_get(TASK
,
80 IPC_GET_ARG1(answer
->data
), KOBJECT_TYPE_PHONE
);
82 IPC_SET_RETVAL(answer
->data
, ENOENT
);
86 mutex_lock(&recipient_obj
->phone
->lock
);
87 if (recipient_obj
->phone
->state
!= IPC_PHONE_CONNECTED
) {
88 mutex_unlock(&recipient_obj
->phone
->lock
);
89 IPC_SET_RETVAL(answer
->data
, EINVAL
);
90 kobject_put(recipient_obj
);
94 other_task_r
= recipient_obj
->phone
->callee
->task
;
95 other_task_s
= (task_t
*) IPC_GET_ARG5(*olddata
);
98 * See if both the sender and the recipient meant the
99 * same third party task.
101 if (other_task_r
!= other_task_s
) {
102 IPC_SET_RETVAL(answer
->data
, EINVAL
);
105 rc
= event_task_notify_5(other_task_r
,
106 EVENT_TASK_STATE_CHANGE
, false,
107 IPC_GET_ARG1(*olddata
),
108 IPC_GET_ARG2(*olddata
),
109 IPC_GET_ARG3(*olddata
),
110 LOWER32(olddata
->task_id
),
111 UPPER32(olddata
->task_id
));
112 IPC_SET_RETVAL(answer
->data
, rc
);
115 mutex_unlock(&recipient_obj
->phone
->lock
);
116 kobject_put(recipient_obj
);
122 sysipc_ops_t ipc_m_state_change_authorize_ops
= {
123 .request_preprocess
= request_preprocess
,
124 .request_forget
= null_request_forget
,
125 .request_process
= null_request_process
,
126 .answer_cleanup
= null_answer_cleanup
,
127 .answer_preprocess
= answer_preprocess
,
128 .answer_process
= null_answer_process
,