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 | } |