Rev 1086 | Rev 1090 | Go to most recent revision | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed
Rev 1086 | Rev 1088 | ||
---|---|---|---|
Line 68... | Line 68... | ||
68 | * - The phone is disconnected (no more messages can be sent over this phone), |
68 | * - The phone is disconnected (no more messages can be sent over this phone), |
69 | * all in-progress messages are correctly handled. The anwerbox receives |
69 | * all in-progress messages are correctly handled. The anwerbox receives |
70 | * IPC_M_PHONE_HUNGUP call from the phone that hung up. When all async |
70 | * IPC_M_PHONE_HUNGUP call from the phone that hung up. When all async |
71 | * calls are answered, the phone is deallocated. |
71 | * calls are answered, the phone is deallocated. |
72 | * |
72 | * |
73 | * *** The answerbox hangs up (ipc_answer(ESLAM)) |
73 | * *** The answerbox hangs up (ipc_answer(EHANGUP)) |
74 | * - The phone is disconnected. IPC_M_ANSWERBOX_HUNGUP notification |
74 | * - The phone is disconnected. EHANGUP response code is sent |
- | 75 | * to the calling process. All new calls through this phone |
|
75 | * is sent to source task, the calling process is expected to |
76 | * get a EHUNGUP error code, the task is expected to |
76 | * send an sys_ipc_hangup after cleaning up it's internal structures. |
77 | * send an sys_ipc_hangup after cleaning up it's internal structures. |
77 | * |
78 | * |
- | 79 | * Call forwarding |
|
- | 80 | * |
|
- | 81 | * The call can be forwarded, so that the answer to call is passed directly |
|
- | 82 | * to the original sender. However, this poses special problems regarding |
|
- | 83 | * routing of hangup messages. |
|
- | 84 | * |
|
- | 85 | * sys_ipc_hangup -> IPC_M_PHONE_HUNGUP |
|
- | 86 | * - this message CANNOT be forwarded |
|
- | 87 | * |
|
- | 88 | * EHANGUP during forward |
|
- | 89 | * - The *forwarding* phone will be closed, EFORWARD is sent to receiver. |
|
- | 90 | * |
|
- | 91 | * EHANGUP, ENOENT during forward |
|
- | 92 | * - EFORWARD is sent to the receiver, ipc_forward returns error code EFORWARD |
|
- | 93 | * |
|
78 | * Cleanup strategy |
94 | * Cleanup strategy |
79 | * |
95 | * |
80 | * 1) Disconnect all our phones ('sys_ipc_hangup') |
96 | * 1) Disconnect all our phones ('ipc_phone_hangup'). |
81 | * |
97 | * |
82 | * 2) Disconnect all phones connected to answerbox. |
98 | * 2) Disconnect all phones connected to answerbox. |
83 | * * Send message 'PHONE_DISCONNECTED' to the target application |
- | |
84 | * - Once all phones are disconnected, no further calls can arrive |
- | |
85 | * |
99 | * |
86 | * 3) Answer all messages in 'calls' and 'dispatched_calls' queues with |
100 | * 3) Answer all messages in 'calls' and 'dispatched_calls' queues with |
87 | * appropriate error code. |
101 | * appropriate error code (EHANGUP, EFORWARD). |
88 | * |
102 | * |
89 | * 4) Wait for all async answers to arrive |
103 | * 4) Wait for all async answers to arrive. |
90 | * |
104 | * |
91 | */ |
105 | */ |
92 | 106 | ||
93 | #include <synch/spinlock.h> |
107 | #include <synch/spinlock.h> |
94 | #include <ipc/ipc.h> |
108 | #include <ipc/ipc.h> |
Line 114... | Line 128... | ||
114 | int i; |
128 | int i; |
115 | 129 | ||
116 | spinlock_lock(&TASK->lock); |
130 | spinlock_lock(&TASK->lock); |
117 | 131 | ||
118 | for (i=0; i < IPC_MAX_PHONES; i++) { |
132 | for (i=0; i < IPC_MAX_PHONES; i++) { |
119 | if (!TASK->phones[i].busy && !atomic_get(&TASK->phones[i].active_calls)) { |
133 | if (TASK->phones[i].busy==IPC_BUSY_FREE && !atomic_get(&TASK->phones[i].active_calls)) { |
120 | TASK->phones[i].busy = 1; |
134 | TASK->phones[i].busy = IPC_BUSY_CONNECTING; |
121 | break; |
135 | break; |
122 | } |
136 | } |
123 | } |
137 | } |
124 | spinlock_unlock(&TASK->lock); |
138 | spinlock_unlock(&TASK->lock); |
125 | 139 | ||
Line 134... | Line 148... | ||
134 | */ |
148 | */ |
135 | void phone_dealloc(int phoneid) |
149 | void phone_dealloc(int phoneid) |
136 | { |
150 | { |
137 | spinlock_lock(&TASK->lock); |
151 | spinlock_lock(&TASK->lock); |
138 | 152 | ||
139 | ASSERT(TASK->phones[phoneid].busy); |
153 | ASSERT(TASK->phones[phoneid].busy == IPC_BUSY_CONNECTING); |
140 | ASSERT(! TASK->phones[phoneid].callee); |
154 | ASSERT(! TASK->phones[phoneid].callee); |
141 | 155 | ||
142 | TASK->phones[phoneid].busy = 0; |
156 | TASK->phones[phoneid].busy = IPC_BUSY_FREE; |
143 | spinlock_unlock(&TASK->lock); |
157 | spinlock_unlock(&TASK->lock); |
144 | } |
158 | } |
145 | 159 | ||
146 | /** Connect phone to a given answerbox |
160 | /** Connect phone to a given answerbox |
147 | * |
161 | * |
Line 153... | Line 167... | ||
153 | */ |
167 | */ |
154 | void phone_connect(int phoneid, answerbox_t *box) |
168 | void phone_connect(int phoneid, answerbox_t *box) |
155 | { |
169 | { |
156 | phone_t *phone = &TASK->phones[phoneid]; |
170 | phone_t *phone = &TASK->phones[phoneid]; |
157 | 171 | ||
158 | ASSERT(phone->busy); |
172 | ASSERT(phone->busy == IPC_BUSY_CONNECTING); |
159 | ipc_phone_connect(phone, box); |
173 | ipc_phone_connect(phone, box); |
160 | } |
174 | } |