diff options
author | Christian Grothoff <christian@grothoff.org> | 2013-11-15 21:20:18 +0000 |
---|---|---|
committer | Christian Grothoff <christian@grothoff.org> | 2013-11-15 21:20:18 +0000 |
commit | e38fa2748c5f85427959bc61f112582d72d856de (patch) | |
tree | e1cd322c5bccc01c6460b959a186586312807d14 /src/conversation/gnunet-service-conversation.c | |
parent | b3a34c936616c5c0339463449934fe045ff367e8 (diff) | |
download | gnunet-e38fa2748c5f85427959bc61f112582d72d856de.tar.gz gnunet-e38fa2748c5f85427959bc61f112582d72d856de.zip |
-reworking connection to allow multiple waiting/active connections per line
Diffstat (limited to 'src/conversation/gnunet-service-conversation.c')
-rw-r--r-- | src/conversation/gnunet-service-conversation.c | 954 |
1 files changed, 567 insertions, 387 deletions
diff --git a/src/conversation/gnunet-service-conversation.c b/src/conversation/gnunet-service-conversation.c index 9e3b48719..67ac31918 100644 --- a/src/conversation/gnunet-service-conversation.c +++ b/src/conversation/gnunet-service-conversation.c | |||
@@ -44,62 +44,72 @@ | |||
44 | 44 | ||
45 | 45 | ||
46 | /** | 46 | /** |
47 | * A line connects a local client with a mesh channel (or, if it is an | ||
48 | * open line, is waiting for a mesh channel). | ||
49 | */ | ||
50 | struct Line; | ||
51 | |||
52 | /** | ||
47 | * The possible connection status | 53 | * The possible connection status |
48 | */ | 54 | */ |
49 | enum LineStatus | 55 | enum ChannelStatus |
50 | { | 56 | { |
51 | /** | 57 | /** |
52 | * We are waiting for incoming calls. | ||
53 | */ | ||
54 | LS_CALLEE_LISTEN, | ||
55 | |||
56 | /** | ||
57 | * Our phone is ringing, waiting for the client to pick up. | 58 | * Our phone is ringing, waiting for the client to pick up. |
58 | */ | 59 | */ |
59 | LS_CALLEE_RINGING, | 60 | CS_CALLEE_RINGING, |
60 | 61 | ||
61 | /** | 62 | /** |
62 | * We are talking! | 63 | * We are talking! |
63 | */ | 64 | */ |
64 | LS_CALLEE_CONNECTED, | 65 | CS_CALLEE_CONNECTED, |
65 | 66 | ||
66 | /** | 67 | /** |
67 | * We're in shutdown, sending hangup messages before cleaning up. | 68 | * We're in shutdown, sending hangup messages before cleaning up. |
68 | */ | 69 | */ |
69 | LS_CALLEE_SHUTDOWN, | 70 | CS_CALLEE_SHUTDOWN, |
70 | 71 | ||
71 | /** | 72 | /** |
72 | * We are waiting for the phone to be picked up. | 73 | * We are waiting for the phone to be picked up. |
73 | */ | 74 | */ |
74 | LS_CALLER_CALLING, | 75 | CS_CALLER_CALLING, |
75 | 76 | ||
76 | /** | 77 | /** |
77 | * We are talking! | 78 | * We are talking! |
78 | */ | 79 | */ |
79 | LS_CALLER_CONNECTED, | 80 | CS_CALLER_CONNECTED, |
80 | 81 | ||
81 | /** | 82 | /** |
82 | * We're in shutdown, sending hangup messages before cleaning up. | 83 | * We're in shutdown, sending hangup messages before cleaning up. |
83 | */ | 84 | */ |
84 | LS_CALLER_SHUTDOWN | 85 | CS_CALLER_SHUTDOWN |
86 | |||
85 | }; | 87 | }; |
86 | 88 | ||
87 | 89 | ||
88 | /** | 90 | /** |
89 | * A line connects a local client with a mesh channel (or, if it is an | 91 | * A `struct Channel` represents a mesh channel, which is a P2P |
90 | * open line, is waiting for a mesh channel). | 92 | * connection to another conversation service. Multiple channels can |
93 | * be attached the the same `struct Line`, which represents a local | ||
94 | * client. We keep them in a linked list. | ||
91 | */ | 95 | */ |
92 | struct Line | 96 | struct Channel |
93 | { | 97 | { |
98 | |||
94 | /** | 99 | /** |
95 | * Kept in a DLL. | 100 | * This is a DLL. |
96 | */ | 101 | */ |
97 | struct Line *next; | 102 | struct Channel *next; |
98 | 103 | ||
99 | /** | 104 | /** |
100 | * Kept in a DLL. | 105 | * This is a DLL. |
101 | */ | 106 | */ |
102 | struct Line *prev; | 107 | struct Channel *prev; |
108 | |||
109 | /** | ||
110 | * Line associated with the channel. | ||
111 | */ | ||
112 | struct Line *line; | ||
103 | 113 | ||
104 | /** | 114 | /** |
105 | * Handle for the reliable channel (contol data) | 115 | * Handle for the reliable channel (contol data) |
@@ -122,11 +132,6 @@ struct Line | |||
122 | struct GNUNET_MQ_Handle *reliable_mq; | 132 | struct GNUNET_MQ_Handle *reliable_mq; |
123 | 133 | ||
124 | /** | 134 | /** |
125 | * Handle to the line client. | ||
126 | */ | ||
127 | struct GNUNET_SERVER_Client *client; | ||
128 | |||
129 | /** | ||
130 | * Target of the line, if we are the caller. | 135 | * Target of the line, if we are the caller. |
131 | */ | 136 | */ |
132 | struct GNUNET_PeerIdentity target; | 137 | struct GNUNET_PeerIdentity target; |
@@ -142,9 +147,9 @@ struct Line | |||
142 | size_t audio_size; | 147 | size_t audio_size; |
143 | 148 | ||
144 | /** | 149 | /** |
145 | * Our line number. | 150 | * Channel identifier. |
146 | */ | 151 | */ |
147 | uint32_t local_line; | 152 | uint32_t cid; |
148 | 153 | ||
149 | /** | 154 | /** |
150 | * Remote line number. | 155 | * Remote line number. |
@@ -154,7 +159,60 @@ struct Line | |||
154 | /** | 159 | /** |
155 | * Current status of this line. | 160 | * Current status of this line. |
156 | */ | 161 | */ |
157 | enum LineStatus status; | 162 | enum ChannelStatus status; |
163 | |||
164 | /** | ||
165 | * #GNUNET_YES if the channel was suspended by the other peer. | ||
166 | */ | ||
167 | int8_t suspended_remote; | ||
168 | |||
169 | /** | ||
170 | * #GNUNET_YES if the channel was suspended by the local client. | ||
171 | */ | ||
172 | int8_t suspended_local; | ||
173 | |||
174 | }; | ||
175 | |||
176 | |||
177 | /** | ||
178 | * A `struct Line` connects a local client with mesh channels. | ||
179 | */ | ||
180 | struct Line | ||
181 | { | ||
182 | /** | ||
183 | * Kept in a DLL. | ||
184 | */ | ||
185 | struct Line *next; | ||
186 | |||
187 | /** | ||
188 | * Kept in a DLL. | ||
189 | */ | ||
190 | struct Line *prev; | ||
191 | |||
192 | /** | ||
193 | * This is a DLL. | ||
194 | */ | ||
195 | struct Channel *channel_head; | ||
196 | |||
197 | /** | ||
198 | * This is a DLL. | ||
199 | */ | ||
200 | struct Channel *channel_tail; | ||
201 | |||
202 | /** | ||
203 | * Handle to the line client. | ||
204 | */ | ||
205 | struct GNUNET_SERVER_Client *client; | ||
206 | |||
207 | /** | ||
208 | * Generator for channel IDs. | ||
209 | */ | ||
210 | uint32_t cid_gen; | ||
211 | |||
212 | /** | ||
213 | * Our line number. | ||
214 | */ | ||
215 | uint32_t local_line; | ||
158 | 216 | ||
159 | }; | 217 | }; |
160 | 218 | ||
@@ -212,7 +270,7 @@ handle_client_register_message (void *cls, | |||
212 | const struct ClientPhoneRegisterMessage *msg; | 270 | const struct ClientPhoneRegisterMessage *msg; |
213 | struct Line *line; | 271 | struct Line *line; |
214 | 272 | ||
215 | msg = (struct ClientPhoneRegisterMessage *) message; | 273 | msg = (const struct ClientPhoneRegisterMessage *) message; |
216 | line = GNUNET_SERVER_client_get_user_context (client, struct Line); | 274 | line = GNUNET_SERVER_client_get_user_context (client, struct Line); |
217 | if (NULL != line) | 275 | if (NULL != line) |
218 | { | 276 | { |
@@ -227,7 +285,7 @@ handle_client_register_message (void *cls, | |||
227 | GNUNET_CONTAINER_DLL_insert (lines_head, | 285 | GNUNET_CONTAINER_DLL_insert (lines_head, |
228 | lines_tail, | 286 | lines_tail, |
229 | line); | 287 | line); |
230 | line->local_line = ntohl (msg->line); | 288 | line->local_line = ntohl (msg->line) & (~ (1 << 31)); |
231 | GNUNET_SERVER_receive_done (client, GNUNET_OK); | 289 | GNUNET_SERVER_receive_done (client, GNUNET_OK); |
232 | } | 290 | } |
233 | 291 | ||
@@ -247,19 +305,10 @@ handle_client_pickup_message (void *cls, | |||
247 | const struct ClientPhonePickupMessage *msg; | 305 | const struct ClientPhonePickupMessage *msg; |
248 | struct GNUNET_MQ_Envelope *e; | 306 | struct GNUNET_MQ_Envelope *e; |
249 | struct MeshPhonePickupMessage *mppm; | 307 | struct MeshPhonePickupMessage *mppm; |
250 | const char *meta; | ||
251 | struct Line *line; | 308 | struct Line *line; |
252 | size_t len; | 309 | struct Channel *ch; |
253 | 310 | ||
254 | msg = (struct ClientPhonePickupMessage *) message; | 311 | msg = (const struct ClientPhonePickupMessage *) message; |
255 | meta = (const char *) &msg[1]; | ||
256 | len = ntohs (msg->header.size) - sizeof (struct ClientPhonePickupMessage); | ||
257 | if ( (0 == len) || | ||
258 | ('\0' != meta[len - 1]) ) | ||
259 | { | ||
260 | meta = NULL; | ||
261 | len = 0; | ||
262 | } | ||
263 | line = GNUNET_SERVER_client_get_user_context (client, struct Line); | 312 | line = GNUNET_SERVER_client_get_user_context (client, struct Line); |
264 | if (NULL == line) | 313 | if (NULL == line) |
265 | { | 314 | { |
@@ -267,112 +316,117 @@ handle_client_pickup_message (void *cls, | |||
267 | GNUNET_SERVER_receive_done (client, GNUNET_SYSERR); | 316 | GNUNET_SERVER_receive_done (client, GNUNET_SYSERR); |
268 | return; | 317 | return; |
269 | } | 318 | } |
270 | switch (line->status) | 319 | for (ch = line->channel_head; NULL != ch; ch = ch->next) |
320 | if (msg->cid == ch->cid) | ||
321 | break; | ||
322 | if (NULL == ch) | ||
271 | { | 323 | { |
272 | case LS_CALLEE_LISTEN: | 324 | /* could have been destroyed asynchronously, ignore message */ |
273 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 325 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
274 | "Ignoring client's PICKUP message, caller has HUNG UP already\n"); | 326 | "Channel %u not found\n", |
275 | GNUNET_SERVER_receive_done (client, GNUNET_OK); | 327 | msg->cid); |
276 | break; | 328 | return; |
277 | case LS_CALLEE_RINGING: | 329 | } |
278 | line->status = LS_CALLEE_CONNECTED; | 330 | switch (ch->status) |
331 | { | ||
332 | case CS_CALLEE_RINGING: | ||
333 | ch->status = CS_CALLEE_CONNECTED; | ||
279 | break; | 334 | break; |
280 | case LS_CALLEE_CONNECTED: | 335 | case CS_CALLEE_CONNECTED: |
281 | GNUNET_break (0); | 336 | GNUNET_break (0); |
282 | GNUNET_SERVER_receive_done (client, GNUNET_SYSERR); | 337 | GNUNET_SERVER_receive_done (client, GNUNET_SYSERR); |
283 | return; | 338 | return; |
284 | case LS_CALLEE_SHUTDOWN: | 339 | case CS_CALLEE_SHUTDOWN: |
285 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 340 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
286 | "Ignoring client's PICKUP message, line is in SHUTDOWN\n"); | 341 | "Ignoring client's PICKUP message, line is in SHUTDOWN\n"); |
287 | GNUNET_SERVER_receive_done (client, GNUNET_OK); | 342 | GNUNET_SERVER_receive_done (client, GNUNET_OK); |
288 | break; | 343 | break; |
289 | case LS_CALLER_CALLING: | 344 | case CS_CALLER_CALLING: |
290 | case LS_CALLER_CONNECTED: | 345 | case CS_CALLER_CONNECTED: |
291 | case LS_CALLER_SHUTDOWN: | 346 | case CS_CALLER_SHUTDOWN: |
292 | GNUNET_break (0); | 347 | GNUNET_break (0); |
293 | GNUNET_SERVER_receive_done (client, GNUNET_SYSERR); | 348 | GNUNET_SERVER_receive_done (client, GNUNET_SYSERR); |
294 | return; | 349 | return; |
295 | } | 350 | } |
296 | line->status = LS_CALLEE_CONNECTED; | 351 | GNUNET_break (CS_CALLEE_CONNECTED == ch->status); |
297 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 352 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
298 | "Sending PICK_UP message to mesh with meta data `%s'\n", | 353 | "Sending PICK_UP message to mesh\n"); |
299 | meta); | 354 | e = GNUNET_MQ_msg (mppm, |
300 | e = GNUNET_MQ_msg_extra (mppm, | 355 | GNUNET_MESSAGE_TYPE_CONVERSATION_MESH_PHONE_PICK_UP); |
301 | len, | 356 | GNUNET_MQ_send (ch->reliable_mq, e); |
302 | GNUNET_MESSAGE_TYPE_CONVERSATION_MESH_PHONE_PICK_UP); | ||
303 | memcpy (&mppm[1], meta, len); | ||
304 | GNUNET_MQ_send (line->reliable_mq, e); | ||
305 | GNUNET_SERVER_receive_done (client, GNUNET_OK); | 357 | GNUNET_SERVER_receive_done (client, GNUNET_OK); |
306 | } | 358 | } |
307 | 359 | ||
308 | 360 | ||
309 | /** | 361 | /** |
310 | * Destroy the mesh channels of a line. | 362 | * Destroy a channel. |
311 | * | 363 | * |
312 | * @param line line to shutdown channels of | 364 | * @param ch channel to destroy. |
313 | */ | 365 | */ |
314 | static void | 366 | static void |
315 | destroy_line_mesh_channels (struct Line *line) | 367 | destroy_line_mesh_channels (struct Channel *ch) |
316 | { | 368 | { |
369 | struct Line *line = ch->line; | ||
317 | struct GNUNET_MESH_Channel *t; | 370 | struct GNUNET_MESH_Channel *t; |
318 | 371 | ||
319 | if (NULL != line->reliable_mq) | 372 | if (NULL != ch->reliable_mq) |
320 | { | 373 | { |
321 | GNUNET_MQ_destroy (line->reliable_mq); | 374 | GNUNET_MQ_destroy (ch->reliable_mq); |
322 | line->reliable_mq = NULL; | 375 | ch->reliable_mq = NULL; |
323 | } | 376 | } |
324 | if (NULL != line->unreliable_mth) | 377 | if (NULL != ch->unreliable_mth) |
325 | { | 378 | { |
326 | GNUNET_MESH_notify_transmit_ready_cancel (line->unreliable_mth); | 379 | GNUNET_MESH_notify_transmit_ready_cancel (ch->unreliable_mth); |
327 | line->unreliable_mth = NULL; | 380 | ch->unreliable_mth = NULL; |
328 | } | 381 | } |
329 | if (NULL != (t = line->channel_unreliable)) | 382 | if (NULL != (t = ch->channel_unreliable)) |
330 | { | 383 | { |
331 | line->channel_unreliable = NULL; | 384 | ch->channel_unreliable = NULL; |
332 | GNUNET_MESH_channel_destroy (t); | 385 | GNUNET_MESH_channel_destroy (t); |
333 | } | 386 | } |
334 | if (NULL != (t = line->channel_reliable)) | 387 | if (NULL != (t = ch->channel_reliable)) |
335 | { | 388 | { |
336 | line->channel_reliable = NULL; | 389 | ch->channel_reliable = NULL; |
337 | GNUNET_MESH_channel_destroy (t); | 390 | GNUNET_MESH_channel_destroy (t); |
338 | } | 391 | } |
392 | GNUNET_CONTAINER_DLL_remove (line->channel_head, | ||
393 | line->channel_tail, | ||
394 | ch); | ||
395 | GNUNET_free_non_null (ch->audio_data); | ||
396 | GNUNET_free (ch); | ||
339 | } | 397 | } |
340 | 398 | ||
341 | 399 | ||
342 | /** | 400 | /** |
343 | * We are done signalling shutdown to the other peer. Close down | 401 | * We are done signalling shutdown to the other peer. Close down |
344 | * (or reset) the line. | 402 | * the channel. |
345 | * | 403 | * |
346 | * @param cls the `struct Line` to reset/terminate | 404 | * @param cls the `struct Channel` to reset/terminate |
347 | */ | 405 | */ |
348 | static void | 406 | static void |
349 | mq_done_finish_caller_shutdown (void *cls) | 407 | mq_done_finish_caller_shutdown (void *cls) |
350 | { | 408 | { |
351 | struct Line *line = cls; | 409 | struct Channel *ch = cls; |
352 | 410 | ||
353 | switch (line->status) | 411 | switch (ch->status) |
354 | { | 412 | { |
355 | case LS_CALLEE_LISTEN: | 413 | case CS_CALLEE_RINGING: |
356 | GNUNET_break (0); | 414 | GNUNET_break (0); |
357 | break; | 415 | break; |
358 | case LS_CALLEE_RINGING: | 416 | case CS_CALLEE_CONNECTED: |
359 | GNUNET_break (0); | 417 | GNUNET_break (0); |
360 | break; | 418 | break; |
361 | case LS_CALLEE_CONNECTED: | 419 | case CS_CALLEE_SHUTDOWN: |
362 | GNUNET_break (0); | 420 | destroy_line_mesh_channels (ch); |
363 | break; | 421 | break; |
364 | case LS_CALLEE_SHUTDOWN: | 422 | case CS_CALLER_CALLING: |
365 | line->status = LS_CALLEE_LISTEN; | 423 | GNUNET_break (0); |
366 | destroy_line_mesh_channels (line); | ||
367 | return; | ||
368 | case LS_CALLER_CALLING: | ||
369 | line->status = LS_CALLER_SHUTDOWN; | ||
370 | break; | 424 | break; |
371 | case LS_CALLER_CONNECTED: | 425 | case CS_CALLER_CONNECTED: |
372 | line->status = LS_CALLER_SHUTDOWN; | 426 | GNUNET_break (0); |
373 | break; | 427 | break; |
374 | case LS_CALLER_SHUTDOWN: | 428 | case CS_CALLER_SHUTDOWN: |
375 | destroy_line_mesh_channels (line); | 429 | destroy_line_mesh_channels (ch); |
376 | break; | 430 | break; |
377 | } | 431 | } |
378 | } | 432 | } |
@@ -393,19 +447,81 @@ handle_client_hangup_message (void *cls, | |||
393 | const struct ClientPhoneHangupMessage *msg; | 447 | const struct ClientPhoneHangupMessage *msg; |
394 | struct GNUNET_MQ_Envelope *e; | 448 | struct GNUNET_MQ_Envelope *e; |
395 | struct MeshPhoneHangupMessage *mhum; | 449 | struct MeshPhoneHangupMessage *mhum; |
396 | const char *meta; | ||
397 | struct Line *line; | 450 | struct Line *line; |
398 | size_t len; | 451 | struct Channel *ch; |
399 | 452 | ||
400 | msg = (struct ClientPhoneHangupMessage *) message; | 453 | msg = (const struct ClientPhoneHangupMessage *) message; |
401 | meta = (const char *) &msg[1]; | 454 | line = GNUNET_SERVER_client_get_user_context (client, struct Line); |
402 | len = ntohs (msg->header.size) - sizeof (struct ClientPhoneHangupMessage); | 455 | if (NULL == line) |
403 | if ( (0 == len) || | ||
404 | ('\0' != meta[len - 1]) ) | ||
405 | { | 456 | { |
406 | meta = NULL; | 457 | GNUNET_break (0); |
407 | len = 0; | 458 | GNUNET_SERVER_receive_done (client, GNUNET_SYSERR); |
459 | return; | ||
460 | } | ||
461 | for (ch = line->channel_head; NULL != ch; ch = ch->next) | ||
462 | if (msg->cid == ch->cid) | ||
463 | break; | ||
464 | if (NULL == ch) | ||
465 | { | ||
466 | /* could have been destroyed asynchronously, ignore message */ | ||
467 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
468 | "Channel %u not found\n", | ||
469 | msg->cid); | ||
470 | return; | ||
471 | } | ||
472 | |||
473 | switch (ch->status) | ||
474 | { | ||
475 | case CS_CALLEE_RINGING: | ||
476 | ch->status = CS_CALLEE_SHUTDOWN; | ||
477 | break; | ||
478 | case CS_CALLEE_CONNECTED: | ||
479 | ch->status = CS_CALLEE_SHUTDOWN; | ||
480 | break; | ||
481 | case CS_CALLEE_SHUTDOWN: | ||
482 | /* maybe the other peer closed asynchronously... */ | ||
483 | return; | ||
484 | case CS_CALLER_CALLING: | ||
485 | ch->status = CS_CALLER_SHUTDOWN; | ||
486 | break; | ||
487 | case CS_CALLER_CONNECTED: | ||
488 | ch->status = CS_CALLER_SHUTDOWN; | ||
489 | break; | ||
490 | case CS_CALLER_SHUTDOWN: | ||
491 | /* maybe the other peer closed asynchronously... */ | ||
492 | return; | ||
408 | } | 493 | } |
494 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
495 | "Sending HANG_UP message via mesh\n"); | ||
496 | e = GNUNET_MQ_msg (mhum, | ||
497 | GNUNET_MESSAGE_TYPE_CONVERSATION_MESH_PHONE_HANG_UP); | ||
498 | GNUNET_MQ_notify_sent (e, | ||
499 | &mq_done_finish_caller_shutdown, | ||
500 | ch); | ||
501 | GNUNET_MQ_send (ch->reliable_mq, e); | ||
502 | GNUNET_SERVER_receive_done (client, GNUNET_OK); | ||
503 | } | ||
504 | |||
505 | |||
506 | /** | ||
507 | * Function to handle a suspend request message from the client | ||
508 | * | ||
509 | * @param cls closure, NULL | ||
510 | * @param client the client from which the message is | ||
511 | * @param message the message from the client | ||
512 | */ | ||
513 | static void | ||
514 | handle_client_suspend_message (void *cls, | ||
515 | struct GNUNET_SERVER_Client *client, | ||
516 | const struct GNUNET_MessageHeader *message) | ||
517 | { | ||
518 | const struct ClientPhoneSuspendMessage *msg; | ||
519 | struct GNUNET_MQ_Envelope *e; | ||
520 | struct MeshPhoneSuspendMessage *mhum; | ||
521 | struct Line *line; | ||
522 | struct Channel *ch; | ||
523 | |||
524 | msg = (const struct ClientPhoneSuspendMessage *) message; | ||
409 | line = GNUNET_SERVER_client_get_user_context (client, struct Line); | 525 | line = GNUNET_SERVER_client_get_user_context (client, struct Line); |
410 | if (NULL == line) | 526 | if (NULL == line) |
411 | { | 527 | { |
@@ -413,50 +529,132 @@ handle_client_hangup_message (void *cls, | |||
413 | GNUNET_SERVER_receive_done (client, GNUNET_SYSERR); | 529 | GNUNET_SERVER_receive_done (client, GNUNET_SYSERR); |
414 | return; | 530 | return; |
415 | } | 531 | } |
416 | switch (line->status) | 532 | for (ch = line->channel_head; NULL != ch; ch = ch->next) |
533 | if (msg->cid == ch->cid) | ||
534 | break; | ||
535 | if (NULL == ch) | ||
536 | { | ||
537 | /* could have been destroyed asynchronously, ignore message */ | ||
538 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
539 | "Channel %u not found\n", | ||
540 | msg->cid); | ||
541 | return; | ||
542 | } | ||
543 | if (GNUNET_YES == ch->suspended_local) | ||
417 | { | 544 | { |
418 | case LS_CALLEE_LISTEN: | ||
419 | GNUNET_break (0); | 545 | GNUNET_break (0); |
420 | GNUNET_SERVER_receive_done (client, GNUNET_OK); | 546 | GNUNET_SERVER_receive_done (client, GNUNET_SYSERR); |
421 | return; | 547 | return; |
422 | case LS_CALLEE_RINGING: | 548 | } |
423 | line->status = LS_CALLEE_SHUTDOWN; | 549 | switch (ch->status) |
424 | break; | 550 | { |
425 | case LS_CALLEE_CONNECTED: | 551 | case CS_CALLEE_RINGING: |
426 | line->status = LS_CALLEE_SHUTDOWN; | 552 | GNUNET_break (0); |
553 | GNUNET_SERVER_receive_done (client, GNUNET_SYSERR); | ||
554 | return; | ||
555 | case CS_CALLEE_CONNECTED: | ||
556 | ch->suspended_local = GNUNET_YES; | ||
427 | break; | 557 | break; |
428 | case LS_CALLEE_SHUTDOWN: | 558 | case CS_CALLEE_SHUTDOWN: |
559 | /* maybe the other peer closed asynchronously... */ | ||
560 | return; | ||
561 | case CS_CALLER_CALLING: | ||
429 | GNUNET_break (0); | 562 | GNUNET_break (0); |
430 | GNUNET_SERVER_receive_done (client, GNUNET_OK); | 563 | GNUNET_SERVER_receive_done (client, GNUNET_SYSERR); |
431 | return; | 564 | return; |
432 | case LS_CALLER_CALLING: | 565 | case CS_CALLER_CONNECTED: |
433 | line->status = LS_CALLER_SHUTDOWN; | 566 | ch->suspended_local = GNUNET_YES; |
434 | break; | 567 | break; |
435 | case LS_CALLER_CONNECTED: | 568 | case CS_CALLER_SHUTDOWN: |
436 | line->status = LS_CALLER_SHUTDOWN; | 569 | /* maybe the other peer closed asynchronously... */ |
570 | return; | ||
571 | } | ||
572 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
573 | "Sending SUSPEND message via mesh\n"); | ||
574 | e = GNUNET_MQ_msg (mhum, | ||
575 | GNUNET_MESSAGE_TYPE_CONVERSATION_MESH_PHONE_SUSPEND); | ||
576 | GNUNET_MQ_send (ch->reliable_mq, e); | ||
577 | GNUNET_SERVER_receive_done (client, GNUNET_OK); | ||
578 | } | ||
579 | |||
580 | |||
581 | /** | ||
582 | * Function to handle a resume request message from the client | ||
583 | * | ||
584 | * @param cls closure, NULL | ||
585 | * @param client the client from which the message is | ||
586 | * @param message the message from the client | ||
587 | */ | ||
588 | static void | ||
589 | handle_client_resume_message (void *cls, | ||
590 | struct GNUNET_SERVER_Client *client, | ||
591 | const struct GNUNET_MessageHeader *message) | ||
592 | { | ||
593 | const struct ClientPhoneResumeMessage *msg; | ||
594 | struct GNUNET_MQ_Envelope *e; | ||
595 | struct MeshPhoneResumeMessage *mhum; | ||
596 | struct Line *line; | ||
597 | struct Channel *ch; | ||
598 | |||
599 | msg = (const struct ClientPhoneResumeMessage *) message; | ||
600 | line = GNUNET_SERVER_client_get_user_context (client, struct Line); | ||
601 | if (NULL == line) | ||
602 | { | ||
603 | GNUNET_break (0); | ||
604 | GNUNET_SERVER_receive_done (client, GNUNET_SYSERR); | ||
605 | return; | ||
606 | } | ||
607 | for (ch = line->channel_head; NULL != ch; ch = ch->next) | ||
608 | if (msg->cid == ch->cid) | ||
609 | break; | ||
610 | if (NULL == ch) | ||
611 | { | ||
612 | /* could have been destroyed asynchronously, ignore message */ | ||
613 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
614 | "Channel %u not found\n", | ||
615 | msg->cid); | ||
616 | return; | ||
617 | } | ||
618 | if (GNUNET_YES != ch->suspended_local) | ||
619 | { | ||
620 | GNUNET_break (0); | ||
621 | GNUNET_SERVER_receive_done (client, GNUNET_SYSERR); | ||
622 | return; | ||
623 | } | ||
624 | switch (ch->status) | ||
625 | { | ||
626 | case CS_CALLEE_RINGING: | ||
627 | GNUNET_break (0); | ||
628 | GNUNET_SERVER_receive_done (client, GNUNET_SYSERR); | ||
629 | return; | ||
630 | case CS_CALLEE_CONNECTED: | ||
631 | ch->suspended_local = GNUNET_NO; | ||
437 | break; | 632 | break; |
438 | case LS_CALLER_SHUTDOWN: | 633 | case CS_CALLEE_SHUTDOWN: |
634 | /* maybe the other peer closed asynchronously... */ | ||
635 | return; | ||
636 | case CS_CALLER_CALLING: | ||
439 | GNUNET_break (0); | 637 | GNUNET_break (0); |
440 | GNUNET_SERVER_receive_done (client, GNUNET_OK); | 638 | GNUNET_SERVER_receive_done (client, GNUNET_SYSERR); |
639 | return; | ||
640 | case CS_CALLER_CONNECTED: | ||
641 | ch->suspended_local = GNUNET_NO; | ||
642 | break; | ||
643 | case CS_CALLER_SHUTDOWN: | ||
644 | /* maybe the other peer closed asynchronously... */ | ||
441 | return; | 645 | return; |
442 | } | 646 | } |
443 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 647 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
444 | "Sending HANG_UP message via mesh with meta data `%s'\n", | 648 | "Sending RESUME message via mesh\n"); |
445 | meta); | 649 | e = GNUNET_MQ_msg (mhum, |
446 | e = GNUNET_MQ_msg_extra (mhum, | 650 | GNUNET_MESSAGE_TYPE_CONVERSATION_MESH_PHONE_RESUME); |
447 | len, | 651 | GNUNET_MQ_send (ch->reliable_mq, e); |
448 | GNUNET_MESSAGE_TYPE_CONVERSATION_MESH_PHONE_HANG_UP); | ||
449 | memcpy (&mhum[1], meta, len); | ||
450 | GNUNET_MQ_notify_sent (e, | ||
451 | &mq_done_finish_caller_shutdown, | ||
452 | line); | ||
453 | GNUNET_MQ_send (line->reliable_mq, e); | ||
454 | GNUNET_SERVER_receive_done (client, GNUNET_OK); | 652 | GNUNET_SERVER_receive_done (client, GNUNET_OK); |
455 | } | 653 | } |
456 | 654 | ||
457 | 655 | ||
458 | /** | 656 | /** |
459 | * Function to handle call request the client | 657 | * Function to handle call request from the client |
460 | * | 658 | * |
461 | * @param cls closure, NULL | 659 | * @param cls closure, NULL |
462 | * @param client the client from which the message is | 660 | * @param client the client from which the message is |
@@ -469,10 +667,11 @@ handle_client_call_message (void *cls, | |||
469 | { | 667 | { |
470 | const struct ClientCallMessage *msg; | 668 | const struct ClientCallMessage *msg; |
471 | struct Line *line; | 669 | struct Line *line; |
670 | struct Channel *ch; | ||
472 | struct GNUNET_MQ_Envelope *e; | 671 | struct GNUNET_MQ_Envelope *e; |
473 | struct MeshPhoneRingMessage *ring; | 672 | struct MeshPhoneRingMessage *ring; |
474 | 673 | ||
475 | msg = (struct ClientCallMessage *) message; | 674 | msg = (const struct ClientCallMessage *) message; |
476 | line = GNUNET_SERVER_client_get_user_context (client, struct Line); | 675 | line = GNUNET_SERVER_client_get_user_context (client, struct Line); |
477 | if (NULL != line) | 676 | if (NULL != line) |
478 | { | 677 | { |
@@ -482,22 +681,27 @@ handle_client_call_message (void *cls, | |||
482 | } | 681 | } |
483 | line = GNUNET_new (struct Line); | 682 | line = GNUNET_new (struct Line); |
484 | line->client = client; | 683 | line->client = client; |
684 | line->local_line = (local_line_cnt++) | (1 << 31); | ||
485 | GNUNET_SERVER_client_set_user_context (client, line); | 685 | GNUNET_SERVER_client_set_user_context (client, line); |
486 | GNUNET_SERVER_notification_context_add (nc, client); | 686 | GNUNET_SERVER_notification_context_add (nc, client); |
487 | line->target = msg->target; | ||
488 | GNUNET_CONTAINER_DLL_insert (lines_head, | 687 | GNUNET_CONTAINER_DLL_insert (lines_head, |
489 | lines_tail, | 688 | lines_tail, |
490 | line); | 689 | line); |
491 | line->remote_line = ntohl (msg->line); | 690 | ch = GNUNET_new (struct Channel); |
492 | line->status = LS_CALLER_CALLING; | 691 | ch->line = line; |
493 | line->channel_reliable = GNUNET_MESH_channel_create (mesh, | 692 | GNUNET_CONTAINER_DLL_insert (line->channel_head, |
494 | line, | 693 | line->channel_tail, |
694 | ch); | ||
695 | ch->target = msg->target; | ||
696 | ch->remote_line = ntohl (msg->line); | ||
697 | ch->status = CS_CALLER_CALLING; | ||
698 | ch->channel_reliable = GNUNET_MESH_channel_create (mesh, | ||
699 | ch, | ||
495 | &msg->target, | 700 | &msg->target, |
496 | GNUNET_APPLICATION_TYPE_CONVERSATION_CONTROL, | 701 | GNUNET_APPLICATION_TYPE_CONVERSATION_CONTROL, |
497 | GNUNET_NO, | 702 | GNUNET_NO, |
498 | GNUNET_YES); | 703 | GNUNET_YES); |
499 | line->reliable_mq = GNUNET_MESH_mq_create (line->channel_reliable); | 704 | ch->reliable_mq = GNUNET_MESH_mq_create (ch->channel_reliable); |
500 | line->local_line = local_line_cnt++; | ||
501 | e = GNUNET_MQ_msg (ring, GNUNET_MESSAGE_TYPE_CONVERSATION_MESH_PHONE_RING); | 705 | e = GNUNET_MQ_msg (ring, GNUNET_MESSAGE_TYPE_CONVERSATION_MESH_PHONE_RING); |
502 | ring->purpose.purpose = htonl (GNUNET_SIGNATURE_PURPOSE_CONVERSATION_RING); | 706 | ring->purpose.purpose = htonl (GNUNET_SIGNATURE_PURPOSE_CONVERSATION_RING); |
503 | ring->purpose.size = htonl (sizeof (struct GNUNET_PeerIdentity) * 2 + | 707 | ring->purpose.size = htonl (sizeof (struct GNUNET_PeerIdentity) * 2 + |
@@ -505,18 +709,18 @@ handle_client_call_message (void *cls, | |||
505 | sizeof (struct GNUNET_CRYPTO_EccSignaturePurpose) + | 709 | sizeof (struct GNUNET_CRYPTO_EccSignaturePurpose) + |
506 | sizeof (struct GNUNET_CRYPTO_EcdsaPublicKey)); | 710 | sizeof (struct GNUNET_CRYPTO_EcdsaPublicKey)); |
507 | GNUNET_CRYPTO_ecdsa_key_get_public (&msg->caller_id, | 711 | GNUNET_CRYPTO_ecdsa_key_get_public (&msg->caller_id, |
508 | &ring->caller_id); | 712 | &ring->caller_id); |
509 | ring->remote_line = msg->line; | 713 | ring->remote_line = msg->line; |
510 | ring->source_line = line->local_line; | 714 | ring->source_line = line->local_line; |
511 | ring->target = msg->target; | 715 | ring->target = msg->target; |
512 | ring->source = my_identity; | 716 | ring->source = my_identity; |
513 | ring->expiration_time = GNUNET_TIME_absolute_hton (GNUNET_TIME_relative_to_absolute (RING_TIMEOUT)); | 717 | ring->expiration_time = GNUNET_TIME_absolute_hton (GNUNET_TIME_relative_to_absolute (RING_TIMEOUT)); |
514 | GNUNET_CRYPTO_ecdsa_sign (&msg->caller_id, | 718 | GNUNET_CRYPTO_ecdsa_sign (&msg->caller_id, |
515 | &ring->purpose, | 719 | &ring->purpose, |
516 | &ring->signature); | 720 | &ring->signature); |
517 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 721 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
518 | "Sending RING message via mesh\n"); | 722 | "Sending RING message via mesh\n"); |
519 | GNUNET_MQ_send (line->reliable_mq, e); | 723 | GNUNET_MQ_send (ch->reliable_mq, e); |
520 | GNUNET_SERVER_receive_done (client, GNUNET_OK); | 724 | GNUNET_SERVER_receive_done (client, GNUNET_OK); |
521 | } | 725 | } |
522 | 726 | ||
@@ -524,7 +728,7 @@ handle_client_call_message (void *cls, | |||
524 | /** | 728 | /** |
525 | * Transmit audio data via unreliable mesh channel. | 729 | * Transmit audio data via unreliable mesh channel. |
526 | * | 730 | * |
527 | * @param cls the `struct Line` we are transmitting for | 731 | * @param cls the `struct Channel` we are transmitting for |
528 | * @param size number of bytes available in @a buf | 732 | * @param size number of bytes available in @a buf |
529 | * @param buf where to copy the data | 733 | * @param buf where to copy the data |
530 | * @return number of bytes copied to @a buf | 734 | * @return number of bytes copied to @a buf |
@@ -534,26 +738,26 @@ transmit_line_audio (void *cls, | |||
534 | size_t size, | 738 | size_t size, |
535 | void *buf) | 739 | void *buf) |
536 | { | 740 | { |
537 | struct Line *line = cls; | 741 | struct Channel *ch = cls; |
538 | struct MeshAudioMessage *mam = buf; | 742 | struct MeshAudioMessage *mam = buf; |
539 | 743 | ||
540 | line->unreliable_mth = NULL; | 744 | ch->unreliable_mth = NULL; |
541 | if ( (NULL == buf) || | 745 | if ( (NULL == buf) || |
542 | (size < sizeof (struct MeshAudioMessage) + line->audio_size) ) | 746 | (size < sizeof (struct MeshAudioMessage) + ch->audio_size) ) |
543 | { | 747 | { |
544 | /* eh, other error handling? */ | 748 | /* eh, other error handling? */ |
545 | return 0; | 749 | return 0; |
546 | } | 750 | } |
547 | mam->header.size = htons (sizeof (struct MeshAudioMessage) + line->audio_size); | 751 | mam->header.size = htons (sizeof (struct MeshAudioMessage) + ch->audio_size); |
548 | mam->header.type = htons (GNUNET_MESSAGE_TYPE_CONVERSATION_MESH_AUDIO); | 752 | mam->header.type = htons (GNUNET_MESSAGE_TYPE_CONVERSATION_MESH_AUDIO); |
549 | mam->remote_line = htonl (line->remote_line); | 753 | mam->remote_line = htonl (ch->remote_line); |
550 | memcpy (&mam[1], line->audio_data, line->audio_size); | 754 | memcpy (&mam[1], ch->audio_data, ch->audio_size); |
551 | GNUNET_free (line->audio_data); | 755 | GNUNET_free (ch->audio_data); |
552 | line->audio_data = NULL; | 756 | ch->audio_data = NULL; |
553 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 757 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
554 | "Sending %u bytes of audio data via mesh\n", | 758 | "Sending %u bytes of audio data via mesh\n", |
555 | line->audio_size); | 759 | ch->audio_size); |
556 | return sizeof (struct MeshAudioMessage) + line->audio_size; | 760 | return sizeof (struct MeshAudioMessage) + ch->audio_size; |
557 | } | 761 | } |
558 | 762 | ||
559 | 763 | ||
@@ -571,10 +775,11 @@ handle_client_audio_message (void *cls, | |||
571 | { | 775 | { |
572 | const struct ClientAudioMessage *msg; | 776 | const struct ClientAudioMessage *msg; |
573 | struct Line *line; | 777 | struct Line *line; |
778 | struct Channel *ch; | ||
574 | size_t size; | 779 | size_t size; |
575 | 780 | ||
576 | size = ntohs (message->size) - sizeof (struct ClientAudioMessage); | 781 | size = ntohs (message->size) - sizeof (struct ClientAudioMessage); |
577 | msg = (struct ClientAudioMessage *) message; | 782 | msg = (const struct ClientAudioMessage *) message; |
578 | line = GNUNET_SERVER_client_get_user_context (client, struct Line); | 783 | line = GNUNET_SERVER_client_get_user_context (client, struct Line); |
579 | if (NULL == line) | 784 | if (NULL == line) |
580 | { | 785 | { |
@@ -582,60 +787,66 @@ handle_client_audio_message (void *cls, | |||
582 | GNUNET_SERVER_receive_done (client, GNUNET_SYSERR); | 787 | GNUNET_SERVER_receive_done (client, GNUNET_SYSERR); |
583 | return; | 788 | return; |
584 | } | 789 | } |
585 | switch (line->status) | 790 | for (ch = line->channel_head; NULL != ch; ch = ch->next) |
791 | if (msg->cid == ch->cid) | ||
792 | break; | ||
793 | if (NULL == ch) | ||
586 | { | 794 | { |
587 | case LS_CALLEE_LISTEN: | 795 | /* could have been destroyed asynchronously, ignore message */ |
588 | /* could be OK if the line just was closed by the other side */ | ||
589 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 796 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
590 | "Audio data dropped, channel is down\n"); | 797 | "Channel %u not found\n", |
591 | GNUNET_SERVER_receive_done (client, GNUNET_OK); | 798 | msg->cid); |
592 | break; | 799 | return; |
593 | case LS_CALLEE_RINGING: | 800 | } |
594 | case LS_CALLER_CALLING: | 801 | |
802 | switch (ch->status) | ||
803 | { | ||
804 | case CS_CALLEE_RINGING: | ||
805 | case CS_CALLER_CALLING: | ||
595 | GNUNET_break (0); | 806 | GNUNET_break (0); |
596 | GNUNET_SERVER_receive_done (client, GNUNET_SYSERR); | 807 | GNUNET_SERVER_receive_done (client, GNUNET_SYSERR); |
597 | return; | 808 | return; |
598 | case LS_CALLEE_CONNECTED: | 809 | case CS_CALLEE_CONNECTED: |
599 | case LS_CALLER_CONNECTED: | 810 | case CS_CALLER_CONNECTED: |
600 | /* common case, handled below */ | 811 | /* common case, handled below */ |
601 | break; | 812 | break; |
602 | case LS_CALLEE_SHUTDOWN: | 813 | case CS_CALLEE_SHUTDOWN: |
603 | case LS_CALLER_SHUTDOWN: | 814 | case CS_CALLER_SHUTDOWN: |
604 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG | GNUNET_ERROR_TYPE_BULK, | 815 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG | GNUNET_ERROR_TYPE_BULK, |
605 | "Mesh audio channel in shutdown; audio data dropped\n"); | 816 | "Mesh audio channel in shutdown; audio data dropped\n"); |
606 | GNUNET_SERVER_receive_done (client, GNUNET_OK); | 817 | GNUNET_SERVER_receive_done (client, GNUNET_OK); |
607 | return; | 818 | return; |
608 | } | 819 | } |
609 | if (NULL == line->channel_unreliable) | 820 | if (NULL == ch->channel_unreliable) |
610 | { | 821 | { |
611 | GNUNET_log (GNUNET_ERROR_TYPE_INFO | GNUNET_ERROR_TYPE_BULK, | 822 | GNUNET_log (GNUNET_ERROR_TYPE_INFO | GNUNET_ERROR_TYPE_BULK, |
612 | _("Mesh audio channel not ready; audio data dropped\n")); | 823 | _("Mesh audio channel not ready; audio data dropped\n")); |
613 | GNUNET_SERVER_receive_done (client, GNUNET_OK); | 824 | GNUNET_SERVER_receive_done (client, GNUNET_OK); |
614 | return; | 825 | return; |
615 | } | 826 | } |
616 | if (NULL != line->unreliable_mth) | 827 | if (NULL != ch->unreliable_mth) |
617 | { | 828 | { |
618 | /* NOTE: we may want to not do this and instead combine the data */ | 829 | /* NOTE: we may want to not do this and instead combine the data */ |
619 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 830 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
620 | "Bandwidth insufficient; dropping previous audio data segment with %u bytes\n", | 831 | "Bandwidth insufficient; dropping previous audio data segment with %u bytes\n", |
621 | (unsigned int) line->audio_size); | 832 | (unsigned int) ch->audio_size); |
622 | GNUNET_MESH_notify_transmit_ready_cancel (line->unreliable_mth); | 833 | GNUNET_MESH_notify_transmit_ready_cancel (ch->unreliable_mth); |
623 | line->unreliable_mth = NULL; | 834 | ch->unreliable_mth = NULL; |
624 | GNUNET_free (line->audio_data); | 835 | GNUNET_free (ch->audio_data); |
625 | line->audio_data = NULL; | 836 | ch->audio_data = NULL; |
626 | } | 837 | } |
627 | line->audio_size = size; | 838 | ch->audio_size = size; |
628 | line->audio_data = GNUNET_malloc (line->audio_size); | 839 | ch->audio_data = GNUNET_malloc (ch->audio_size); |
629 | memcpy (line->audio_data, | 840 | memcpy (ch->audio_data, |
630 | &msg[1], | 841 | &msg[1], |
631 | size); | 842 | size); |
632 | line->unreliable_mth = GNUNET_MESH_notify_transmit_ready (line->channel_unreliable, | 843 | ch->unreliable_mth = GNUNET_MESH_notify_transmit_ready (ch->channel_unreliable, |
633 | GNUNET_NO, | 844 | GNUNET_NO, |
634 | GNUNET_TIME_UNIT_FOREVER_REL, | 845 | GNUNET_TIME_UNIT_FOREVER_REL, |
635 | sizeof (struct MeshAudioMessage) | 846 | sizeof (struct MeshAudioMessage) |
636 | + line->audio_size, | 847 | + ch->audio_size, |
637 | &transmit_line_audio, | 848 | &transmit_line_audio, |
638 | line); | 849 | ch); |
639 | GNUNET_SERVER_receive_done (client, GNUNET_OK); | 850 | GNUNET_SERVER_receive_done (client, GNUNET_OK); |
640 | } | 851 | } |
641 | 852 | ||
@@ -661,6 +872,7 @@ mq_done_destroy_channel (void *cls) | |||
661 | * @param cls closure, NULL | 872 | * @param cls closure, NULL |
662 | * @param channel the channel over which the message arrived | 873 | * @param channel the channel over which the message arrived |
663 | * @param channel_ctx the channel context, can be NULL | 874 | * @param channel_ctx the channel context, can be NULL |
875 | * or point to the `struct Channel` | ||
664 | * @param message the incoming message | 876 | * @param message the incoming message |
665 | * @return #GNUNET_OK | 877 | * @return #GNUNET_OK |
666 | */ | 878 | */ |
@@ -672,9 +884,11 @@ handle_mesh_ring_message (void *cls, | |||
672 | { | 884 | { |
673 | const struct MeshPhoneRingMessage *msg; | 885 | const struct MeshPhoneRingMessage *msg; |
674 | struct Line *line; | 886 | struct Line *line; |
887 | struct Channel *ch; | ||
675 | struct GNUNET_MQ_Envelope *e; | 888 | struct GNUNET_MQ_Envelope *e; |
676 | struct MeshPhoneHangupMessage *hang_up; | 889 | struct MeshPhoneHangupMessage *hang_up; |
677 | struct ClientPhoneRingMessage cring; | 890 | struct ClientPhoneRingMessage cring; |
891 | struct GNUNET_MQ_Handle *reliable_mq; | ||
678 | 892 | ||
679 | msg = (const struct MeshPhoneRingMessage *) message; | 893 | msg = (const struct MeshPhoneRingMessage *) message; |
680 | if ( (msg->purpose.size != htonl (sizeof (struct GNUNET_PeerIdentity) * 2 + | 894 | if ( (msg->purpose.size != htonl (sizeof (struct GNUNET_PeerIdentity) * 2 + |
@@ -691,30 +905,38 @@ handle_mesh_ring_message (void *cls, | |||
691 | return GNUNET_SYSERR; | 905 | return GNUNET_SYSERR; |
692 | } | 906 | } |
693 | for (line = lines_head; NULL != line; line = line->next) | 907 | for (line = lines_head; NULL != line; line = line->next) |
694 | if ( (line->local_line == ntohl (msg->remote_line)) && | 908 | if (line->local_line == ntohl (msg->remote_line)) |
695 | (LS_CALLEE_LISTEN == line->status) ) | ||
696 | break; | 909 | break; |
697 | if (NULL == line) | 910 | if (NULL == line) |
698 | { | 911 | { |
699 | GNUNET_log (GNUNET_ERROR_TYPE_INFO, | 912 | GNUNET_log (GNUNET_ERROR_TYPE_INFO, |
700 | _("No available phone for incoming call on line %u, sending HANG_UP signal\n"), | 913 | _("No available phone for incoming call on line %u, sending HANG_UP signal\n"), |
701 | ntohl (msg->remote_line)); | 914 | ntohl (msg->remote_line)); |
702 | e = GNUNET_MQ_msg (hang_up, GNUNET_MESSAGE_TYPE_CONVERSATION_MESH_PHONE_HANG_UP); | 915 | e = GNUNET_MQ_msg (hang_up, |
916 | GNUNET_MESSAGE_TYPE_CONVERSATION_MESH_PHONE_HANG_UP); | ||
703 | GNUNET_MQ_notify_sent (e, | 917 | GNUNET_MQ_notify_sent (e, |
704 | &mq_done_destroy_channel, | 918 | &mq_done_destroy_channel, |
705 | channel); | 919 | channel); |
706 | GNUNET_MQ_send (line->reliable_mq, e); | 920 | reliable_mq = GNUNET_MESH_mq_create (channel); |
921 | GNUNET_MQ_send (reliable_mq, e); | ||
922 | /* FIXME: do we need to clean up reliable_mq somehow/somewhere? */ | ||
707 | GNUNET_MESH_receive_done (channel); /* needed? */ | 923 | GNUNET_MESH_receive_done (channel); /* needed? */ |
708 | return GNUNET_OK; | 924 | return GNUNET_OK; |
709 | } | 925 | } |
710 | line->status = LS_CALLEE_RINGING; | 926 | ch = GNUNET_new (struct Channel); |
711 | line->remote_line = ntohl (msg->source_line); | 927 | ch->line = line; |
712 | line->channel_reliable = channel; | 928 | GNUNET_CONTAINER_DLL_insert (line->channel_head, |
713 | line->reliable_mq = GNUNET_MESH_mq_create (line->channel_reliable); | 929 | line->channel_tail, |
714 | *channel_ctx = line; | 930 | ch); |
931 | ch->status = CS_CALLEE_RINGING; | ||
932 | ch->remote_line = ntohl (msg->source_line); | ||
933 | ch->channel_reliable = channel; | ||
934 | ch->reliable_mq = GNUNET_MESH_mq_create (ch->channel_reliable); | ||
935 | ch->cid = line->cid_gen++; | ||
936 | *channel_ctx = ch; | ||
715 | cring.header.type = htons (GNUNET_MESSAGE_TYPE_CONVERSATION_CS_PHONE_RING); | 937 | cring.header.type = htons (GNUNET_MESSAGE_TYPE_CONVERSATION_CS_PHONE_RING); |
716 | cring.header.size = htons (sizeof (cring)); | 938 | cring.header.size = htons (sizeof (cring)); |
717 | cring.cid = htonl (0 /* FIXME */); | 939 | cring.cid = ch->cid; |
718 | cring.caller_id = msg->caller_id; | 940 | cring.caller_id = msg->caller_id; |
719 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 941 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
720 | "Sending RING message to client\n"); | 942 | "Sending RING message to client\n"); |
@@ -733,6 +955,7 @@ handle_mesh_ring_message (void *cls, | |||
733 | * @param cls closure, NULL | 955 | * @param cls closure, NULL |
734 | * @param channel the channel over which the message arrived | 956 | * @param channel the channel over which the message arrived |
735 | * @param channel_ctx the channel context, can be NULL | 957 | * @param channel_ctx the channel context, can be NULL |
958 | * or point to the `struct Channel` | ||
736 | * @param message the incoming message | 959 | * @param message the incoming message |
737 | * @return #GNUNET_OK | 960 | * @return #GNUNET_OK |
738 | */ | 961 | */ |
@@ -742,68 +965,40 @@ handle_mesh_hangup_message (void *cls, | |||
742 | void **channel_ctx, | 965 | void **channel_ctx, |
743 | const struct GNUNET_MessageHeader *message) | 966 | const struct GNUNET_MessageHeader *message) |
744 | { | 967 | { |
745 | struct Line *line = *channel_ctx; | 968 | struct Channel *ch = *channel_ctx; |
746 | const struct MeshPhoneHangupMessage *msg; | 969 | struct Line *line; |
747 | const char *reason; | 970 | struct ClientPhoneHangupMessage hup; |
748 | size_t len = ntohs (message->size) - sizeof (struct MeshPhoneHangupMessage); | 971 | |
749 | char buf[len + sizeof (struct ClientPhoneHangupMessage)]; | 972 | if (NULL == ch) |
750 | struct ClientPhoneHangupMessage *hup; | ||
751 | |||
752 | msg = (const struct MeshPhoneHangupMessage *) message; | ||
753 | len = ntohs (msg->header.size) - sizeof (struct MeshPhoneHangupMessage); | ||
754 | reason = (const char *) &msg[1]; | ||
755 | if ( (0 == len) || | ||
756 | ('\0' != reason[len - 1]) ) | ||
757 | { | ||
758 | reason = NULL; | ||
759 | len = 0; | ||
760 | } | ||
761 | if (NULL == line) | ||
762 | { | 973 | { |
763 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 974 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
764 | "HANGUP message received for non-existing line, dropping channel.\n"); | 975 | "HANGUP message received for non-existing line, dropping channel.\n"); |
765 | return GNUNET_SYSERR; | 976 | return GNUNET_SYSERR; |
766 | } | 977 | } |
978 | line = ch->line; | ||
767 | *channel_ctx = NULL; | 979 | *channel_ctx = NULL; |
768 | switch (line->status) | 980 | hup.header.size = sizeof (hup); |
981 | hup.header.type = htons (GNUNET_MESSAGE_TYPE_CONVERSATION_CS_PHONE_HANG_UP); | ||
982 | hup.cid = ch->cid; | ||
983 | destroy_line_mesh_channels (ch); | ||
984 | switch (ch->status) | ||
769 | { | 985 | { |
770 | case LS_CALLEE_LISTEN: | 986 | case CS_CALLEE_RINGING: |
771 | GNUNET_break (0); | 987 | case CS_CALLEE_CONNECTED: |
772 | return GNUNET_SYSERR; | ||
773 | case LS_CALLEE_RINGING: | ||
774 | line->status = LS_CALLEE_LISTEN; | ||
775 | destroy_line_mesh_channels (line); | ||
776 | break; | ||
777 | case LS_CALLEE_CONNECTED: | ||
778 | line->status = LS_CALLEE_LISTEN; | ||
779 | destroy_line_mesh_channels (line); | ||
780 | break; | 988 | break; |
781 | case LS_CALLEE_SHUTDOWN: | 989 | case CS_CALLEE_SHUTDOWN: |
782 | line->status = LS_CALLEE_LISTEN; | ||
783 | destroy_line_mesh_channels (line); | ||
784 | return GNUNET_OK; | 990 | return GNUNET_OK; |
785 | case LS_CALLER_CALLING: | 991 | case CS_CALLER_CALLING: |
786 | line->status = LS_CALLER_SHUTDOWN; | 992 | case CS_CALLER_CONNECTED: |
787 | mq_done_finish_caller_shutdown (line); | ||
788 | break; | 993 | break; |
789 | case LS_CALLER_CONNECTED: | 994 | case CS_CALLER_SHUTDOWN: |
790 | line->status = LS_CALLER_SHUTDOWN; | ||
791 | mq_done_finish_caller_shutdown (line); | ||
792 | break; | ||
793 | case LS_CALLER_SHUTDOWN: | ||
794 | mq_done_finish_caller_shutdown (line); | ||
795 | return GNUNET_OK; | 995 | return GNUNET_OK; |
796 | } | 996 | } |
797 | hup = (struct ClientPhoneHangupMessage *) buf; | ||
798 | hup->header.size = sizeof (buf); | ||
799 | hup->header.type = htons (GNUNET_MESSAGE_TYPE_CONVERSATION_CS_PHONE_HANG_UP); | ||
800 | memcpy (&hup[1], reason, len); | ||
801 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 997 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
802 | "Sending HANG UP message to client with reason `%s'\n", | 998 | "Sending HANG UP message to client\n"); |
803 | reason); | ||
804 | GNUNET_SERVER_notification_context_unicast (nc, | 999 | GNUNET_SERVER_notification_context_unicast (nc, |
805 | line->client, | 1000 | line->client, |
806 | &hup->header, | 1001 | &hup.header, |
807 | GNUNET_NO); | 1002 | GNUNET_NO); |
808 | GNUNET_MESH_receive_done (channel); | 1003 | GNUNET_MESH_receive_done (channel); |
809 | return GNUNET_OK; | 1004 | return GNUNET_OK; |
@@ -816,6 +1011,7 @@ handle_mesh_hangup_message (void *cls, | |||
816 | * @param cls closure, NULL | 1011 | * @param cls closure, NULL |
817 | * @param channel the channel over which the message arrived | 1012 | * @param channel the channel over which the message arrived |
818 | * @param channel_ctx the channel context, can be NULL | 1013 | * @param channel_ctx the channel context, can be NULL |
1014 | * or point to the `struct Channel` | ||
819 | * @param message the incoming message | 1015 | * @param message the incoming message |
820 | * @return #GNUNET_OK | 1016 | * @return #GNUNET_OK |
821 | */ | 1017 | */ |
@@ -825,74 +1021,56 @@ handle_mesh_pickup_message (void *cls, | |||
825 | void **channel_ctx, | 1021 | void **channel_ctx, |
826 | const struct GNUNET_MessageHeader *message) | 1022 | const struct GNUNET_MessageHeader *message) |
827 | { | 1023 | { |
828 | const struct MeshPhonePickupMessage *msg; | 1024 | struct Channel *ch = *channel_ctx; |
829 | struct Line *line = *channel_ctx; | 1025 | struct Line *line; |
830 | const char *metadata; | 1026 | struct ClientPhonePickupMessage pick; |
831 | size_t len = ntohs (message->size) - sizeof (struct MeshPhonePickupMessage); | 1027 | |
832 | char buf[len + sizeof (struct ClientPhonePickupMessage)]; | 1028 | if (NULL == ch) |
833 | struct ClientPhonePickupMessage *pick; | ||
834 | |||
835 | msg = (const struct MeshPhonePickupMessage *) message; | ||
836 | len = ntohs (msg->header.size) - sizeof (struct MeshPhonePickupMessage); | ||
837 | metadata = (const char *) &msg[1]; | ||
838 | if ( (0 == len) || | ||
839 | ('\0' != metadata[len - 1]) ) | ||
840 | { | ||
841 | metadata = NULL; | ||
842 | len = 0; | ||
843 | } | ||
844 | if (NULL == line) | ||
845 | { | 1029 | { |
846 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 1030 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
847 | "PICKUP message received for non-existing line, dropping channel.\n"); | 1031 | "PICKUP message received for non-existing channel, dropping channel.\n"); |
848 | return GNUNET_SYSERR; | 1032 | return GNUNET_SYSERR; |
849 | } | 1033 | } |
1034 | line = ch->line; | ||
850 | GNUNET_MESH_receive_done (channel); | 1035 | GNUNET_MESH_receive_done (channel); |
851 | switch (line->status) | 1036 | switch (ch->status) |
852 | { | 1037 | { |
853 | case LS_CALLEE_LISTEN: | 1038 | case CS_CALLEE_RINGING: |
854 | GNUNET_break (0); | 1039 | case CS_CALLEE_CONNECTED: |
855 | return GNUNET_SYSERR; | ||
856 | case LS_CALLEE_RINGING: | ||
857 | case LS_CALLEE_CONNECTED: | ||
858 | GNUNET_break_op (0); | 1040 | GNUNET_break_op (0); |
859 | destroy_line_mesh_channels (line); | 1041 | destroy_line_mesh_channels (ch); |
860 | line->status = LS_CALLEE_LISTEN; | ||
861 | return GNUNET_SYSERR; | 1042 | return GNUNET_SYSERR; |
862 | case LS_CALLEE_SHUTDOWN: | 1043 | case CS_CALLEE_SHUTDOWN: |
863 | GNUNET_break_op (0); | 1044 | GNUNET_break_op (0); |
864 | line->status = LS_CALLEE_LISTEN; | 1045 | destroy_line_mesh_channels (ch); |
865 | destroy_line_mesh_channels (line); | ||
866 | break; | 1046 | break; |
867 | case LS_CALLER_CALLING: | 1047 | case CS_CALLER_CALLING: |
868 | line->status = LS_CALLER_CONNECTED; | 1048 | ch->status = CS_CALLER_CONNECTED; |
869 | break; | 1049 | break; |
870 | case LS_CALLER_CONNECTED: | 1050 | case CS_CALLER_CONNECTED: |
871 | GNUNET_break_op (0); | 1051 | GNUNET_break_op (0); |
872 | return GNUNET_OK; | 1052 | return GNUNET_OK; |
873 | case LS_CALLER_SHUTDOWN: | 1053 | case CS_CALLER_SHUTDOWN: |
874 | GNUNET_break_op (0); | 1054 | GNUNET_break_op (0); |
875 | mq_done_finish_caller_shutdown (line); | 1055 | mq_done_finish_caller_shutdown (ch); |
876 | return GNUNET_SYSERR; | 1056 | return GNUNET_SYSERR; |
877 | } | 1057 | } |
878 | pick = (struct ClientPhonePickupMessage *) buf; | 1058 | pick.header.size = sizeof (pick); |
879 | pick->header.size = sizeof (buf); | 1059 | pick.header.type = htons (GNUNET_MESSAGE_TYPE_CONVERSATION_CS_PHONE_PICKED_UP); |
880 | pick->header.type = htons (GNUNET_MESSAGE_TYPE_CONVERSATION_CS_PHONE_PICKED_UP); | 1060 | pick.cid = ch->cid; |
881 | memcpy (&pick[1], metadata, len); | ||
882 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 1061 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
883 | "Sending PICKED UP message to client with metadata `%s'\n", | 1062 | "Sending PICKED UP message to client\n"); |
884 | metadata); | ||
885 | GNUNET_SERVER_notification_context_unicast (nc, | 1063 | GNUNET_SERVER_notification_context_unicast (nc, |
886 | line->client, | 1064 | line->client, |
887 | &pick->header, | 1065 | &pick.header, |
888 | GNUNET_NO); | 1066 | GNUNET_NO); |
889 | line->channel_unreliable = GNUNET_MESH_channel_create (mesh, | 1067 | ch->channel_unreliable = GNUNET_MESH_channel_create (mesh, |
890 | line, | 1068 | ch, |
891 | &line->target, | 1069 | &ch->target, |
892 | GNUNET_APPLICATION_TYPE_CONVERSATION_AUDIO, | 1070 | GNUNET_APPLICATION_TYPE_CONVERSATION_AUDIO, |
893 | GNUNET_YES, | 1071 | GNUNET_YES, |
894 | GNUNET_NO); | 1072 | GNUNET_NO); |
895 | if (NULL == line->channel_unreliable) | 1073 | if (NULL == ch->channel_unreliable) |
896 | { | 1074 | { |
897 | GNUNET_break (0); | 1075 | GNUNET_break (0); |
898 | } | 1076 | } |
@@ -906,6 +1084,7 @@ handle_mesh_pickup_message (void *cls, | |||
906 | * @param cls closure, NULL | 1084 | * @param cls closure, NULL |
907 | * @param channel the channel over which the message arrived | 1085 | * @param channel the channel over which the message arrived |
908 | * @param channel_ctx the channel context, can be NULL | 1086 | * @param channel_ctx the channel context, can be NULL |
1087 | * or point to the `struct Channel` | ||
909 | * @param message the incoming message | 1088 | * @param message the incoming message |
910 | * @return #GNUNET_OK | 1089 | * @return #GNUNET_OK |
911 | */ | 1090 | */ |
@@ -915,54 +1094,44 @@ handle_mesh_suspend_message (void *cls, | |||
915 | void **channel_ctx, | 1094 | void **channel_ctx, |
916 | const struct GNUNET_MessageHeader *message) | 1095 | const struct GNUNET_MessageHeader *message) |
917 | { | 1096 | { |
918 | struct Line *line = *channel_ctx; | 1097 | struct Channel *ch = *channel_ctx; |
1098 | struct Line *line; | ||
919 | struct ClientPhoneSuspendMessage suspend; | 1099 | struct ClientPhoneSuspendMessage suspend; |
920 | 1100 | ||
921 | if (NULL == line) | 1101 | if (NULL == ch) |
922 | { | 1102 | { |
923 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 1103 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
924 | "SUSPEND message received for non-existing line, dropping channel.\n"); | 1104 | "SUSPEND message received for non-existing line, dropping channel.\n"); |
925 | return GNUNET_SYSERR; | 1105 | return GNUNET_SYSERR; |
926 | } | 1106 | } |
1107 | line = ch->line; | ||
927 | suspend.header.size = sizeof (suspend); | 1108 | suspend.header.size = sizeof (suspend); |
928 | suspend.header.type = htons (GNUNET_MESSAGE_TYPE_CONVERSATION_CS_PHONE_SUSPEND); | 1109 | suspend.header.type = htons (GNUNET_MESSAGE_TYPE_CONVERSATION_CS_PHONE_SUSPEND); |
929 | suspend.cid = htonl (0 /* FIXME */); | 1110 | suspend.cid = ch->cid; |
930 | GNUNET_MESH_receive_done (channel); | 1111 | GNUNET_MESH_receive_done (channel); |
931 | *channel_ctx = NULL; | 1112 | switch (ch->status) |
932 | switch (line->status) | ||
933 | { | 1113 | { |
934 | case LS_CALLEE_LISTEN: | 1114 | case CS_CALLEE_RINGING: |
935 | GNUNET_break (0); | ||
936 | return GNUNET_SYSERR; | ||
937 | case LS_CALLEE_RINGING: | ||
938 | GNUNET_break_op (0); | 1115 | GNUNET_break_op (0); |
939 | break; | 1116 | break; |
940 | case LS_CALLEE_CONNECTED: | 1117 | case CS_CALLEE_CONNECTED: |
941 | GNUNET_break_op (0); | 1118 | ch->suspended_remote = GNUNET_YES; |
942 | break; | 1119 | break; |
943 | case LS_CALLEE_SHUTDOWN: | 1120 | case CS_CALLEE_SHUTDOWN: |
944 | GNUNET_break_op (0); | 1121 | return GNUNET_OK; |
945 | break; | 1122 | case CS_CALLER_CALLING: |
946 | case LS_CALLER_CALLING: | ||
947 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
948 | "Sending SUSPEND message to client\n"); | ||
949 | GNUNET_SERVER_notification_context_unicast (nc, | ||
950 | line->client, | ||
951 | &suspend.header, | ||
952 | GNUNET_NO); | ||
953 | line->status = LS_CALLER_SHUTDOWN; | ||
954 | mq_done_finish_caller_shutdown (line); | ||
955 | break; | ||
956 | case LS_CALLER_CONNECTED: | ||
957 | GNUNET_break_op (0); | 1123 | GNUNET_break_op (0); |
958 | line->status = LS_CALLER_SHUTDOWN; | ||
959 | mq_done_finish_caller_shutdown (line); | ||
960 | break; | 1124 | break; |
961 | case LS_CALLER_SHUTDOWN: | 1125 | case CS_CALLER_CONNECTED: |
962 | GNUNET_break_op (0); | 1126 | ch->suspended_remote = GNUNET_YES; |
963 | mq_done_finish_caller_shutdown (line); | ||
964 | break; | 1127 | break; |
1128 | case CS_CALLER_SHUTDOWN: | ||
1129 | return GNUNET_OK; | ||
965 | } | 1130 | } |
1131 | GNUNET_SERVER_notification_context_unicast (nc, | ||
1132 | line->client, | ||
1133 | &suspend.header, | ||
1134 | GNUNET_NO); | ||
966 | return GNUNET_OK; | 1135 | return GNUNET_OK; |
967 | } | 1136 | } |
968 | 1137 | ||
@@ -973,6 +1142,7 @@ handle_mesh_suspend_message (void *cls, | |||
973 | * @param cls closure, NULL | 1142 | * @param cls closure, NULL |
974 | * @param channel the channel over which the message arrived | 1143 | * @param channel the channel over which the message arrived |
975 | * @param channel_ctx the channel context, can be NULL | 1144 | * @param channel_ctx the channel context, can be NULL |
1145 | * or point to the `struct Channel` | ||
976 | * @param message the incoming message | 1146 | * @param message the incoming message |
977 | * @return #GNUNET_OK | 1147 | * @return #GNUNET_OK |
978 | */ | 1148 | */ |
@@ -982,54 +1152,50 @@ handle_mesh_resume_message (void *cls, | |||
982 | void **channel_ctx, | 1152 | void **channel_ctx, |
983 | const struct GNUNET_MessageHeader *message) | 1153 | const struct GNUNET_MessageHeader *message) |
984 | { | 1154 | { |
985 | struct Line *line = *channel_ctx; | 1155 | struct Channel *ch = *channel_ctx; |
1156 | struct Line *line; | ||
986 | struct ClientPhoneResumeMessage resume; | 1157 | struct ClientPhoneResumeMessage resume; |
987 | 1158 | ||
988 | if (NULL == line) | 1159 | if (NULL == ch) |
989 | { | 1160 | { |
990 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 1161 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
991 | "RESUME message received for non-existing line, dropping channel.\n"); | 1162 | "RESUME message received for non-existing line, dropping channel.\n"); |
992 | return GNUNET_SYSERR; | 1163 | return GNUNET_SYSERR; |
993 | } | 1164 | } |
1165 | line = ch->line; | ||
994 | resume.header.size = sizeof (resume); | 1166 | resume.header.size = sizeof (resume); |
995 | resume.header.type = htons (GNUNET_MESSAGE_TYPE_CONVERSATION_CS_PHONE_RESUME); | 1167 | resume.header.type = htons (GNUNET_MESSAGE_TYPE_CONVERSATION_CS_PHONE_RESUME); |
996 | resume.cid = htonl (0 /* FIXME */); | 1168 | resume.cid = ch->cid; |
997 | GNUNET_MESH_receive_done (channel); | 1169 | GNUNET_MESH_receive_done (channel); |
998 | *channel_ctx = NULL; | 1170 | if (GNUNET_YES != ch->suspended_remote) |
999 | switch (line->status) | ||
1000 | { | 1171 | { |
1001 | case LS_CALLEE_LISTEN: | 1172 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
1002 | GNUNET_break (0); | 1173 | "RESUME message received for non-suspended channel, dropping channel.\n"); |
1003 | return GNUNET_SYSERR; | 1174 | return GNUNET_SYSERR; |
1004 | case LS_CALLEE_RINGING: | 1175 | } |
1005 | GNUNET_break_op (0); | 1176 | switch (ch->status) |
1006 | break; | 1177 | { |
1007 | case LS_CALLEE_CONNECTED: | 1178 | case CS_CALLEE_RINGING: |
1008 | GNUNET_break_op (0); | 1179 | GNUNET_break (0); |
1009 | break; | 1180 | break; |
1010 | case LS_CALLEE_SHUTDOWN: | 1181 | case CS_CALLEE_CONNECTED: |
1011 | GNUNET_break_op (0); | 1182 | ch->suspended_remote = GNUNET_NO; |
1012 | break; | 1183 | break; |
1013 | case LS_CALLER_CALLING: | 1184 | case CS_CALLEE_SHUTDOWN: |
1014 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 1185 | return GNUNET_OK; |
1015 | "Sending SUSPEND message to client\n"); | 1186 | case CS_CALLER_CALLING: |
1016 | GNUNET_SERVER_notification_context_unicast (nc, | 1187 | GNUNET_break (0); |
1017 | line->client, | ||
1018 | &resume.header, | ||
1019 | GNUNET_NO); | ||
1020 | line->status = LS_CALLER_SHUTDOWN; | ||
1021 | mq_done_finish_caller_shutdown (line); | ||
1022 | break; | 1188 | break; |
1023 | case LS_CALLER_CONNECTED: | 1189 | case CS_CALLER_CONNECTED: |
1024 | GNUNET_break_op (0); | 1190 | ch->suspended_remote = GNUNET_NO; |
1025 | line->status = LS_CALLER_SHUTDOWN; | ||
1026 | mq_done_finish_caller_shutdown (line); | ||
1027 | break; | ||
1028 | case LS_CALLER_SHUTDOWN: | ||
1029 | GNUNET_break_op (0); | ||
1030 | mq_done_finish_caller_shutdown (line); | ||
1031 | break; | 1191 | break; |
1192 | case CS_CALLER_SHUTDOWN: | ||
1193 | return GNUNET_OK; | ||
1032 | } | 1194 | } |
1195 | GNUNET_SERVER_notification_context_unicast (nc, | ||
1196 | line->client, | ||
1197 | &resume.header, | ||
1198 | GNUNET_NO); | ||
1033 | return GNUNET_OK; | 1199 | return GNUNET_OK; |
1034 | } | 1200 | } |
1035 | 1201 | ||
@@ -1040,6 +1206,7 @@ handle_mesh_resume_message (void *cls, | |||
1040 | * @param cls closure, NULL | 1206 | * @param cls closure, NULL |
1041 | * @param channel the channel over which the message arrived | 1207 | * @param channel the channel over which the message arrived |
1042 | * @param channel_ctx the channel context, can be NULL | 1208 | * @param channel_ctx the channel context, can be NULL |
1209 | * or point to the `struct Channel` | ||
1043 | * @param message the incoming message | 1210 | * @param message the incoming message |
1044 | * @return #GNUNET_OK | 1211 | * @return #GNUNET_OK |
1045 | */ | 1212 | */ |
@@ -1050,7 +1217,8 @@ handle_mesh_audio_message (void *cls, | |||
1050 | const struct GNUNET_MessageHeader *message) | 1217 | const struct GNUNET_MessageHeader *message) |
1051 | { | 1218 | { |
1052 | const struct MeshAudioMessage *msg; | 1219 | const struct MeshAudioMessage *msg; |
1053 | struct Line *line = *channel_ctx; | 1220 | struct Channel *ch = *channel_ctx; |
1221 | struct Line *line; | ||
1054 | struct GNUNET_PeerIdentity sender; | 1222 | struct GNUNET_PeerIdentity sender; |
1055 | size_t msize = ntohs (message->size) - sizeof (struct MeshAudioMessage); | 1223 | size_t msize = ntohs (message->size) - sizeof (struct MeshAudioMessage); |
1056 | char buf[msize + sizeof (struct ClientAudioMessage)]; | 1224 | char buf[msize + sizeof (struct ClientAudioMessage)]; |
@@ -1058,10 +1226,10 @@ handle_mesh_audio_message (void *cls, | |||
1058 | const union GNUNET_MESH_ChannelInfo *info; | 1226 | const union GNUNET_MESH_ChannelInfo *info; |
1059 | 1227 | ||
1060 | msg = (const struct MeshAudioMessage *) message; | 1228 | msg = (const struct MeshAudioMessage *) message; |
1061 | if (NULL == line) | 1229 | if (NULL == ch) |
1062 | { | 1230 | { |
1063 | info = GNUNET_MESH_channel_get_info (channel, | 1231 | info = GNUNET_MESH_channel_get_info (channel, |
1064 | GNUNET_MESH_OPTION_PEER); | 1232 | GNUNET_MESH_OPTION_PEER); |
1065 | if (NULL == info) | 1233 | if (NULL == info) |
1066 | { | 1234 | { |
1067 | GNUNET_break (0); | 1235 | GNUNET_break (0); |
@@ -1069,22 +1237,27 @@ handle_mesh_audio_message (void *cls, | |||
1069 | } | 1237 | } |
1070 | sender = *(info->peer); | 1238 | sender = *(info->peer); |
1071 | for (line = lines_head; NULL != line; line = line->next) | 1239 | for (line = lines_head; NULL != line; line = line->next) |
1072 | if ( (line->local_line == ntohl (msg->remote_line)) && | 1240 | if (line->local_line == ntohl (msg->remote_line)) |
1073 | (LS_CALLEE_CONNECTED == line->status) && | 1241 | { |
1074 | (0 == memcmp (&line->target, | 1242 | for (ch = line->channel_head; NULL != ch; ch = ch->next) |
1075 | &sender, | 1243 | { |
1076 | sizeof (struct GNUNET_PeerIdentity))) && | 1244 | if ( (CS_CALLEE_CONNECTED == ch->status) && |
1077 | (NULL == line->channel_unreliable) ) | 1245 | (0 == memcmp (&ch->target, |
1078 | break; | 1246 | &sender, |
1079 | if (NULL == line) | 1247 | sizeof (struct GNUNET_PeerIdentity))) && |
1248 | (NULL == ch->channel_unreliable) ) | ||
1249 | break; | ||
1250 | } | ||
1251 | } | ||
1252 | if (NULL == ch) | ||
1080 | { | 1253 | { |
1081 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 1254 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
1082 | "Received AUDIO data for non-existing line %u, dropping.\n", | 1255 | "Received AUDIO data for non-existing line %u, dropping.\n", |
1083 | ntohl (msg->remote_line)); | 1256 | ntohl (msg->remote_line)); |
1084 | return GNUNET_SYSERR; | 1257 | return GNUNET_SYSERR; |
1085 | } | 1258 | } |
1086 | line->channel_unreliable = channel; | 1259 | ch->channel_unreliable = channel; |
1087 | *channel_ctx = line; | 1260 | *channel_ctx = ch; |
1088 | } | 1261 | } |
1089 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 1262 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
1090 | "Forwarding %u bytes of AUDIO data to client\n", | 1263 | "Forwarding %u bytes of AUDIO data to client\n", |
@@ -1092,6 +1265,7 @@ handle_mesh_audio_message (void *cls, | |||
1092 | cam = (struct ClientAudioMessage *) buf; | 1265 | cam = (struct ClientAudioMessage *) buf; |
1093 | cam->header.size = htons (sizeof (buf)); | 1266 | cam->header.size = htons (sizeof (buf)); |
1094 | cam->header.type = htons (GNUNET_MESSAGE_TYPE_CONVERSATION_CS_AUDIO); | 1267 | cam->header.type = htons (GNUNET_MESSAGE_TYPE_CONVERSATION_CS_AUDIO); |
1268 | cam->cid = ch->cid; | ||
1095 | memcpy (&cam[1], &msg[1], msize); | 1269 | memcpy (&cam[1], &msg[1], msize); |
1096 | GNUNET_SERVER_notification_context_unicast (nc, | 1270 | GNUNET_SERVER_notification_context_unicast (nc, |
1097 | line->client, | 1271 | line->client, |
@@ -1110,7 +1284,8 @@ handle_mesh_audio_message (void *cls, | |||
1110 | * @param channel new handle to the channel | 1284 | * @param channel new handle to the channel |
1111 | * @param initiator peer that started the channel | 1285 | * @param initiator peer that started the channel |
1112 | * @param port port | 1286 | * @param port port |
1113 | * @return initial channel context for the channel (can be NULL -- that's not an error) | 1287 | * @return initial channel context for the channel; |
1288 | * (can be NULL -- that's not an error) | ||
1114 | */ | 1289 | */ |
1115 | static void * | 1290 | static void * |
1116 | inbound_channel (void *cls, | 1291 | inbound_channel (void *cls, |
@@ -1132,63 +1307,62 @@ inbound_channel (void *cls, | |||
1132 | * @param cls closure (set from #GNUNET_MESH_connect) | 1307 | * @param cls closure (set from #GNUNET_MESH_connect) |
1133 | * @param channel connection to the other end (henceforth invalid) | 1308 | * @param channel connection to the other end (henceforth invalid) |
1134 | * @param channel_ctx place where local state associated | 1309 | * @param channel_ctx place where local state associated |
1135 | * with the channel is stored | 1310 | * with the channel is stored; |
1311 | * may point to the `struct Channel` | ||
1136 | */ | 1312 | */ |
1137 | static void | 1313 | static void |
1138 | inbound_end (void *cls, | 1314 | inbound_end (void *cls, |
1139 | const struct GNUNET_MESH_Channel *channel, | 1315 | const struct GNUNET_MESH_Channel *channel, |
1140 | void *channel_ctx) | 1316 | void *channel_ctx) |
1141 | { | 1317 | { |
1142 | struct Line *line = channel_ctx; | 1318 | struct Channel *ch = channel_ctx; |
1319 | struct Line *line; | ||
1143 | struct ClientPhoneHangupMessage hup; | 1320 | struct ClientPhoneHangupMessage hup; |
1144 | 1321 | ||
1145 | if (NULL == line) | 1322 | if (NULL == ch) |
1146 | return; | 1323 | return; |
1147 | if (line->channel_unreliable == channel) | 1324 | line = ch->line; |
1325 | if (ch->channel_unreliable == channel) | ||
1148 | { | 1326 | { |
1149 | if (NULL != line->unreliable_mth) | 1327 | if (NULL != ch->unreliable_mth) |
1150 | { | 1328 | { |
1151 | GNUNET_MESH_notify_transmit_ready_cancel (line->unreliable_mth); | 1329 | GNUNET_MESH_notify_transmit_ready_cancel (ch->unreliable_mth); |
1152 | line->unreliable_mth = NULL; | 1330 | ch->unreliable_mth = NULL; |
1153 | } | 1331 | } |
1154 | line->channel_unreliable = NULL; | 1332 | ch->channel_unreliable = NULL; |
1155 | return; | 1333 | return; |
1156 | } | 1334 | } |
1157 | if (line->channel_reliable != channel) | 1335 | if (ch->channel_reliable != channel) |
1158 | return; | 1336 | return; |
1159 | line->channel_reliable = NULL; | 1337 | ch->channel_reliable = NULL; |
1160 | 1338 | ||
1161 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 1339 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
1162 | "Mesh channel destroyed by mesh\n"); | 1340 | "Mesh channel destroyed by mesh\n"); |
1163 | hup.header.size = sizeof (hup); | 1341 | hup.header.size = sizeof (hup); |
1164 | hup.header.type = htons (GNUNET_MESSAGE_TYPE_CONVERSATION_CS_PHONE_HANG_UP); | 1342 | hup.header.type = htons (GNUNET_MESSAGE_TYPE_CONVERSATION_CS_PHONE_HANG_UP); |
1165 | switch (line->status) | 1343 | hup.cid = ch->cid; |
1344 | switch (ch->status) | ||
1166 | { | 1345 | { |
1167 | case LS_CALLEE_LISTEN: | 1346 | case CS_CALLEE_RINGING: |
1168 | GNUNET_break (0); | 1347 | case CS_CALLEE_CONNECTED: |
1169 | break; | ||
1170 | case LS_CALLEE_RINGING: | ||
1171 | case LS_CALLEE_CONNECTED: | ||
1172 | GNUNET_SERVER_notification_context_unicast (nc, | 1348 | GNUNET_SERVER_notification_context_unicast (nc, |
1173 | line->client, | 1349 | line->client, |
1174 | &hup.header, | 1350 | &hup.header, |
1175 | GNUNET_NO); | 1351 | GNUNET_NO); |
1176 | line->status = LS_CALLEE_LISTEN; | ||
1177 | break; | 1352 | break; |
1178 | case LS_CALLEE_SHUTDOWN: | 1353 | case CS_CALLEE_SHUTDOWN: |
1179 | line->status = LS_CALLEE_LISTEN; | ||
1180 | break; | 1354 | break; |
1181 | case LS_CALLER_CALLING: | 1355 | case CS_CALLER_CALLING: |
1182 | case LS_CALLER_CONNECTED: | 1356 | case CS_CALLER_CONNECTED: |
1183 | GNUNET_SERVER_notification_context_unicast (nc, | 1357 | GNUNET_SERVER_notification_context_unicast (nc, |
1184 | line->client, | 1358 | line->client, |
1185 | &hup.header, | 1359 | &hup.header, |
1186 | GNUNET_NO); | 1360 | GNUNET_NO); |
1187 | break; | 1361 | break; |
1188 | case LS_CALLER_SHUTDOWN: | 1362 | case CS_CALLER_SHUTDOWN: |
1189 | break; | 1363 | break; |
1190 | } | 1364 | } |
1191 | destroy_line_mesh_channels (line); | 1365 | destroy_line_mesh_channels (ch); |
1192 | } | 1366 | } |
1193 | 1367 | ||
1194 | 1368 | ||
@@ -1215,8 +1389,8 @@ handle_client_disconnect (void *cls, | |||
1215 | GNUNET_CONTAINER_DLL_remove (lines_head, | 1389 | GNUNET_CONTAINER_DLL_remove (lines_head, |
1216 | lines_tail, | 1390 | lines_tail, |
1217 | line); | 1391 | line); |
1218 | destroy_line_mesh_channels (line); | 1392 | while (NULL != line->channel_head) |
1219 | GNUNET_free_non_null (line->audio_data); | 1393 | destroy_line_mesh_channels (line->channel_head); |
1220 | GNUNET_free (line); | 1394 | GNUNET_free (line); |
1221 | } | 1395 | } |
1222 | 1396 | ||
@@ -1262,13 +1436,19 @@ run (void *cls, | |||
1262 | sizeof (struct ClientPhoneRegisterMessage)}, | 1436 | sizeof (struct ClientPhoneRegisterMessage)}, |
1263 | {&handle_client_pickup_message, NULL, | 1437 | {&handle_client_pickup_message, NULL, |
1264 | GNUNET_MESSAGE_TYPE_CONVERSATION_CS_PHONE_PICK_UP, | 1438 | GNUNET_MESSAGE_TYPE_CONVERSATION_CS_PHONE_PICK_UP, |
1265 | 0}, | 1439 | sizeof (struct ClientPhonePickupMessage) }, |
1440 | {&handle_client_suspend_message, NULL, | ||
1441 | GNUNET_MESSAGE_TYPE_CONVERSATION_CS_PHONE_SUSPEND, | ||
1442 | sizeof (struct ClientPhoneSuspendMessage) }, | ||
1443 | {&handle_client_resume_message, NULL, | ||
1444 | GNUNET_MESSAGE_TYPE_CONVERSATION_CS_PHONE_RESUME, | ||
1445 | sizeof (struct ClientPhoneResumeMessage) }, | ||
1266 | {&handle_client_hangup_message, NULL, | 1446 | {&handle_client_hangup_message, NULL, |
1267 | GNUNET_MESSAGE_TYPE_CONVERSATION_CS_PHONE_HANG_UP, | 1447 | GNUNET_MESSAGE_TYPE_CONVERSATION_CS_PHONE_HANG_UP, |
1268 | 0}, | 1448 | sizeof (struct ClientPhoneHangupMessage) }, |
1269 | {&handle_client_call_message, NULL, | 1449 | {&handle_client_call_message, NULL, |
1270 | GNUNET_MESSAGE_TYPE_CONVERSATION_CS_PHONE_CALL, | 1450 | GNUNET_MESSAGE_TYPE_CONVERSATION_CS_PHONE_CALL, |
1271 | 0}, | 1451 | sizeof (struct ClientCallMessage) }, |
1272 | {&handle_client_audio_message, NULL, | 1452 | {&handle_client_audio_message, NULL, |
1273 | GNUNET_MESSAGE_TYPE_CONVERSATION_CS_AUDIO, | 1453 | GNUNET_MESSAGE_TYPE_CONVERSATION_CS_AUDIO, |
1274 | 0}, | 1454 | 0}, |
@@ -1280,10 +1460,10 @@ run (void *cls, | |||
1280 | sizeof (struct MeshPhoneRingMessage)}, | 1460 | sizeof (struct MeshPhoneRingMessage)}, |
1281 | {&handle_mesh_hangup_message, | 1461 | {&handle_mesh_hangup_message, |
1282 | GNUNET_MESSAGE_TYPE_CONVERSATION_MESH_PHONE_HANG_UP, | 1462 | GNUNET_MESSAGE_TYPE_CONVERSATION_MESH_PHONE_HANG_UP, |
1283 | 0}, | 1463 | sizeof (struct MeshPhoneHangupMessage)}, |
1284 | {&handle_mesh_pickup_message, | 1464 | {&handle_mesh_pickup_message, |
1285 | GNUNET_MESSAGE_TYPE_CONVERSATION_MESH_PHONE_PICK_UP, | 1465 | GNUNET_MESSAGE_TYPE_CONVERSATION_MESH_PHONE_PICK_UP, |
1286 | 0}, | 1466 | sizeof (struct MeshPhonePickupMessage)}, |
1287 | {&handle_mesh_suspend_message, | 1467 | {&handle_mesh_suspend_message, |
1288 | GNUNET_MESSAGE_TYPE_CONVERSATION_MESH_PHONE_SUSPEND, | 1468 | GNUNET_MESSAGE_TYPE_CONVERSATION_MESH_PHONE_SUSPEND, |
1289 | sizeof (struct MeshPhoneSuspendMessage)}, | 1469 | sizeof (struct MeshPhoneSuspendMessage)}, |