aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorChristian Grothoff <christian@grothoff.org>2013-11-15 21:20:18 +0000
committerChristian Grothoff <christian@grothoff.org>2013-11-15 21:20:18 +0000
commite38fa2748c5f85427959bc61f112582d72d856de (patch)
treee1cd322c5bccc01c6460b959a186586312807d14 /src
parentb3a34c936616c5c0339463449934fe045ff367e8 (diff)
downloadgnunet-e38fa2748c5f85427959bc61f112582d72d856de.tar.gz
gnunet-e38fa2748c5f85427959bc61f112582d72d856de.zip
-reworking connection to allow multiple waiting/active connections per line
Diffstat (limited to 'src')
-rw-r--r--src/conversation/conversation_api.c3
-rw-r--r--src/conversation/gnunet-service-conversation.c954
2 files changed, 570 insertions, 387 deletions
diff --git a/src/conversation/conversation_api.c b/src/conversation/conversation_api.c
index 9dfc6e913..1c71217bd 100644
--- a/src/conversation/conversation_api.c
+++ b/src/conversation/conversation_api.c
@@ -624,6 +624,7 @@ reconnect_phone (struct GNUNET_CONVERSATION_Phone *phone)
624 * @param ego ego to use for name resolution (when determining caller ID) 624 * @param ego ego to use for name resolution (when determining caller ID)
625 * @param event_handler how to notify the owner of the phone about events 625 * @param event_handler how to notify the owner of the phone about events
626 * @param event_handler_cls closure for @a event_handler 626 * @param event_handler_cls closure for @a event_handler
627 * @return NULL on error (no valid line configured)
627 */ 628 */
628struct GNUNET_CONVERSATION_Phone * 629struct GNUNET_CONVERSATION_Phone *
629GNUNET_CONVERSATION_phone_create (const struct GNUNET_CONFIGURATION_Handle *cfg, 630GNUNET_CONVERSATION_phone_create (const struct GNUNET_CONFIGURATION_Handle *cfg,
@@ -640,6 +641,8 @@ GNUNET_CONVERSATION_phone_create (const struct GNUNET_CONFIGURATION_Handle *cfg,
640 "LINE", 641 "LINE",
641 &line)) 642 &line))
642 return NULL; 643 return NULL;
644 if (line >= (1 << 31))
645 return NULL;
643 phone = GNUNET_new (struct GNUNET_CONVERSATION_Phone); 646 phone = GNUNET_new (struct GNUNET_CONVERSATION_Phone);
644 if (GNUNET_OK != 647 if (GNUNET_OK !=
645 GNUNET_CRYPTO_get_peer_identity (cfg, 648 GNUNET_CRYPTO_get_peer_identity (cfg,
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 */
50struct Line;
51
52/**
47 * The possible connection status 53 * The possible connection status
48 */ 54 */
49enum LineStatus 55enum 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 */
92struct Line 96struct 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 */
180struct 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 */
314static void 366static void
315destroy_line_mesh_channels (struct Line *line) 367destroy_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 */
348static void 406static void
349mq_done_finish_caller_shutdown (void *cls) 407mq_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 */
513static void
514handle_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 */
588static void
589handle_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 */
1115static void * 1290static void *
1116inbound_channel (void *cls, 1291inbound_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 */
1137static void 1313static void
1138inbound_end (void *cls, 1314inbound_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)},