/*
This file is part of GNUnet.
(C) 2013 Christian Grothoff (and other contributing authors)
-
+
GNUnet is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published
by the Free Software Foundation; either version 3, or (at your
option) any later version.
-
+
GNUnet is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
-
+
You should have received a copy of the GNU General Public License
along with GNUnet; see the file COPYING. If not, write to the
Free Software Foundation, Inc., 59 Temple Place - Suite 330,
* Handle for the reliable tunnel (contol data)
*/
struct GNUNET_MESH_Tunnel *tunnel_reliable;
-
+
/**
* Handle for unreliable tunnel (audio data)
*/
/**
* Current status of this line.
- */
+ */
enum LineStatus status;
};
return;
}
line->status = LS_CALLEE_CONNECTED;
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+ "Sending PICK_UP message to mesh with meta data `%s'\n",
+ meta);
e = GNUNET_MQ_msg_extra (mppm,
len,
GNUNET_MESSAGE_TYPE_CONVERSATION_MESH_PHONE_PICK_UP);
static void
destroy_line_mesh_tunnels (struct Line *line)
{
+ struct GNUNET_MESH_Tunnel *t;
+
if (NULL != line->reliable_mq)
{
GNUNET_MQ_destroy (line->reliable_mq);
GNUNET_MESH_notify_transmit_ready_cancel (line->unreliable_mth);
line->unreliable_mth = NULL;
}
- if (NULL != line->tunnel_unreliable)
+ if (NULL != (t = line->tunnel_unreliable))
{
- GNUNET_MESH_tunnel_destroy (line->tunnel_unreliable);
line->tunnel_unreliable = NULL;
+ GNUNET_MESH_tunnel_destroy (t);
}
- if (NULL != line->tunnel_reliable)
+ if (NULL != (t = line->tunnel_reliable))
{
- GNUNET_MESH_tunnel_destroy (line->tunnel_reliable);
line->tunnel_reliable = NULL;
+ GNUNET_MESH_tunnel_destroy (t);
}
}
break;
case LS_CALLER_SHUTDOWN:
destroy_line_mesh_tunnels (line);
- GNUNET_CONTAINER_DLL_remove (lines_head,
- lines_tail,
- line);
- GNUNET_free_non_null (line->audio_data);
- GNUNET_free (line);
break;
- }
+ }
}
GNUNET_SERVER_receive_done (client, GNUNET_OK);
return;
}
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+ "Sending HANG_UP message via mesh with meta data `%s'\n",
+ meta);
e = GNUNET_MQ_msg_extra (mhum,
len,
GNUNET_MESSAGE_TYPE_CONVERSATION_MESH_PHONE_HANG_UP);
GNUNET_CRYPTO_ecc_sign (&msg->caller_id,
&ring->purpose,
&ring->signature);
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+ "Sending RING message via mesh\n");
GNUNET_MQ_send (line->reliable_mq, e);
GNUNET_SERVER_receive_done (client, GNUNET_OK);
}
* @param cls the `struct Line` we are transmitting for
* @param size number of bytes available in @a buf
* @param buf where to copy the data
- * @return number of bytes copied to @buf
+ * @return number of bytes copied to @a buf
*/
static size_t
transmit_line_audio (void *cls,
{
struct Line *line = cls;
struct MeshAudioMessage *mam = buf;
-
+
line->unreliable_mth = NULL;
if ( (NULL == buf) ||
(size < sizeof (struct MeshAudioMessage) + line->audio_size) )
memcpy (&mam[1], line->audio_data, line->audio_size);
GNUNET_free (line->audio_data);
line->audio_data = NULL;
- return sizeof (struct MeshAudioMessage) + line->audio_size;
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+ "Sending %u bytes of audio data via mesh\n",
+ line->audio_size);
+ return sizeof (struct MeshAudioMessage) + line->audio_size;
}
switch (line->status)
{
case LS_CALLEE_LISTEN:
+ /* could be OK if the line just was closed by the other side */
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+ "Audio data dropped, channel is down\n");
+ GNUNET_SERVER_receive_done (client, GNUNET_OK);
+ break;
case LS_CALLEE_RINGING:
case LS_CALLER_CALLING:
GNUNET_break (0);
break;
case LS_CALLEE_SHUTDOWN:
case LS_CALLER_SHUTDOWN:
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG | GNUNET_ERROR_TYPE_BULK,
"Mesh audio channel in shutdown; audio data dropped\n");
GNUNET_SERVER_receive_done (client, GNUNET_OK);
return;
}
if (NULL == line->tunnel_unreliable)
{
- GNUNET_log (GNUNET_ERROR_TYPE_INFO,
+ GNUNET_log (GNUNET_ERROR_TYPE_INFO | GNUNET_ERROR_TYPE_BULK,
_("Mesh audio channel not ready; audio data dropped\n"));
- GNUNET_SERVER_receive_done (client, GNUNET_OK);
+ GNUNET_SERVER_receive_done (client, GNUNET_OK);
return;
}
if (NULL != line->unreliable_mth)
{
/* NOTE: we may want to not do this and instead combine the data */
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
- "Dropping previous audio data segment with %u bytes\n",
- line->audio_size);
+ "Bandwidth insufficient; dropping previous audio data segment with %u bytes\n",
+ (unsigned int) line->audio_size);
GNUNET_MESH_notify_transmit_ready_cancel (line->unreliable_mth);
+ line->unreliable_mth = NULL;
GNUNET_free (line->audio_data);
+ line->audio_data = NULL;
}
line->audio_size = size;
line->audio_data = GNUNET_malloc (line->audio_size);
line->unreliable_mth = GNUNET_MESH_notify_transmit_ready (line->tunnel_unreliable,
GNUNET_NO,
GNUNET_TIME_UNIT_FOREVER_REL,
- sizeof (struct MeshAudioMessage)
+ sizeof (struct MeshAudioMessage)
+ line->audio_size,
&transmit_line_audio,
line);
/**
- * We are done signalling shutdown to the other peer.
+ * We are done signalling shutdown to the other peer.
* Destroy the tunnel.
*
* @param cls the `struct GNUNET_MESH_tunnel` to destroy
mq_done_destroy_tunnel (void *cls)
{
struct GNUNET_MESH_Tunnel *tunnel = cls;
-
+
GNUNET_MESH_tunnel_destroy (tunnel);
}
struct GNUNET_MQ_Envelope *e;
struct MeshPhoneBusyMessage *busy;
struct ClientPhoneRingMessage cring;
-
+
msg = (const struct MeshPhoneRingMessage *) message;
if ( (msg->purpose.size != htonl (sizeof (struct GNUNET_PeerIdentity) * 2 +
sizeof (struct GNUNET_TIME_AbsoluteNBO) +
GNUNET_break_op (0);
return GNUNET_SYSERR;
}
- for (line = lines_head; NULL != line; line = line->next)
+ for (line = lines_head; NULL != line; line = line->next)
if ( (line->local_line == ntohl (msg->remote_line)) &&
(LS_CALLEE_LISTEN == line->status) )
break;
- if (NULL == line)
+ if (NULL == line)
{
GNUNET_log (GNUNET_ERROR_TYPE_INFO,
_("No available phone for incoming call on line %u, sending BUSY signal\n"),
cring.header.size = htons (sizeof (cring));
cring.reserved = htonl (0);
cring.caller_id = msg->caller_id;
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+ "Sending RING message to client\n");
GNUNET_SERVER_notification_context_unicast (nc,
line->client,
&cring.header,
size_t len = ntohs (message->size) - sizeof (struct MeshPhoneHangupMessage);
char buf[len + sizeof (struct ClientPhoneHangupMessage)];
struct ClientPhoneHangupMessage *hup;
-
+
msg = (const struct MeshPhoneHangupMessage *) message;
len = ntohs (msg->header.size) - sizeof (struct MeshPhoneHangupMessage);
reason = (const char *) &msg[1];
hup->header.size = sizeof (buf);
hup->header.type = htons (GNUNET_MESSAGE_TYPE_CONVERSATION_CS_PHONE_HANG_UP);
memcpy (&hup[1], reason, len);
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+ "Sending HANG UP message to client with reason `%s'\n",
+ reason);
GNUNET_SERVER_notification_context_unicast (nc,
line->client,
&hup->header,
size_t len = ntohs (message->size) - sizeof (struct MeshPhonePickupMessage);
char buf[len + sizeof (struct ClientPhonePickupMessage)];
struct ClientPhonePickupMessage *pick;
-
+
msg = (const struct MeshPhonePickupMessage *) message;
len = ntohs (msg->header.size) - sizeof (struct MeshPhonePickupMessage);
metadata = (const char *) &msg[1];
}
pick = (struct ClientPhonePickupMessage *) buf;
pick->header.size = sizeof (buf);
- pick->header.type = htons (GNUNET_MESSAGE_TYPE_CONVERSATION_CS_PHONE_PICK_UP);
+ pick->header.type = htons (GNUNET_MESSAGE_TYPE_CONVERSATION_CS_PHONE_PICKED_UP);
memcpy (&pick[1], metadata, len);
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+ "Sending PICKED UP message to client with metadata `%s'\n",
+ metadata);
GNUNET_SERVER_notification_context_unicast (nc,
line->client,
&pick->header,
GNUNET_APPLICATION_TYPE_CONVERSATION_AUDIO,
GNUNET_YES,
GNUNET_NO);
+ if (NULL == line->tunnel_unreliable)
+ {
+ GNUNET_break (0);
+ }
return GNUNET_OK;
}
}
busy.header.size = sizeof (busy);
busy.header.type = htons (GNUNET_MESSAGE_TYPE_CONVERSATION_CS_PHONE_BUSY);
- GNUNET_SERVER_notification_context_unicast (nc,
- line->client,
- &busy.header,
- GNUNET_NO);
GNUNET_MESH_receive_done (tunnel);
*tunnel_ctx = NULL;
switch (line->status)
GNUNET_break_op (0);
break;
case LS_CALLER_CALLING:
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+ "Sending BUSY message to client\n");
+ GNUNET_SERVER_notification_context_unicast (nc,
+ line->client,
+ &busy.header,
+ GNUNET_NO);
line->status = LS_CALLER_SHUTDOWN;
mq_done_finish_caller_shutdown (line);
break;
case LS_CALLER_CONNECTED:
+ GNUNET_break_op (0);
line->status = LS_CALLER_SHUTDOWN;
mq_done_finish_caller_shutdown (line);
break;
case LS_CALLER_SHUTDOWN:
+ GNUNET_break_op (0);
mq_done_finish_caller_shutdown (line);
break;
}
size_t msize = ntohs (message->size) - sizeof (struct MeshAudioMessage);
char buf[msize + sizeof (struct ClientAudioMessage)];
struct ClientAudioMessage *cam;
-
+ const union GNUNET_MESH_TunnelInfo *info;
+
msg = (const struct MeshAudioMessage *) message;
if (NULL == line)
{
- sender = *GNUNET_MESH_tunnel_get_info (tunnel,
- GNUNET_MESH_OPTION_PEER)->peer;
+ info = GNUNET_MESH_tunnel_get_info (tunnel,
+ GNUNET_MESH_OPTION_PEER);
+ if (NULL == info)
+ {
+ GNUNET_break (0);
+ return GNUNET_OK;
+ }
+ sender = info->peer;
for (line = lines_head; NULL != line; line = line->next)
if ( (line->local_line == ntohl (msg->remote_line)) &&
(LS_CALLEE_CONNECTED == line->status) &&
line->tunnel_unreliable = tunnel;
*tunnel_ctx = line;
}
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+ "Forwarding %u bytes of AUDIO data to client\n",
+ msize);
cam = (struct ClientAudioMessage *) buf;
cam->header.size = htons (sizeof (buf));
cam->header.type = htons (GNUNET_MESSAGE_TYPE_CONVERSATION_CS_AUDIO);
static void *
inbound_tunnel (void *cls,
struct GNUNET_MESH_Tunnel *tunnel,
- const struct GNUNET_PeerIdentity *initiator,
+ const struct GNUNET_PeerIdentity *initiator,
uint32_t port)
{
GNUNET_log (GNUNET_ERROR_TYPE_INFO,
- _("Received incoming tunnel on port %d\n"),
- port);
+ _("Received incoming tunnel on port %u\n"),
+ (unsigned int) port);
return NULL;
}
return;
if (line->tunnel_unreliable == tunnel)
{
+ if (NULL != line->unreliable_mth)
+ {
+ GNUNET_MESH_notify_transmit_ready_cancel (line->unreliable_mth);
+ line->unreliable_mth = NULL;
+ }
line->tunnel_unreliable = NULL;
return;
}
+ if (line->tunnel_reliable != tunnel)
+ return;
+ line->tunnel_reliable = NULL;
+
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+ "Mesh tunnel destroyed by mesh\n");
hup.header.size = sizeof (hup);
hup.header.type = htons (GNUNET_MESSAGE_TYPE_CONVERSATION_CS_PHONE_HANG_UP);
switch (line->status)
{
case LS_CALLEE_LISTEN:
GNUNET_break (0);
- return;
+ break;
case LS_CALLEE_RINGING:
case LS_CALLEE_CONNECTED:
GNUNET_SERVER_notification_context_unicast (nc,
break;
case LS_CALLEE_SHUTDOWN:
line->status = LS_CALLEE_LISTEN;
- destroy_line_mesh_tunnels (line);
break;
case LS_CALLER_CALLING:
case LS_CALLER_CONNECTED:
line->client,
&hup.header,
GNUNET_NO);
- destroy_line_mesh_tunnels (line);
- GNUNET_CONTAINER_DLL_remove (lines_head,
- lines_tail,
- line);
- GNUNET_free_non_null (line->audio_data);
- GNUNET_free (line);
break;
case LS_CALLER_SHUTDOWN:
- destroy_line_mesh_tunnels (line);
- GNUNET_CONTAINER_DLL_remove (lines_head,
- lines_tail,
- line);
- GNUNET_free (line);
break;
}
+ destroy_line_mesh_tunnels (line);
}
* @param client identification of the client
*/
static void
-handle_client_disconnect (void *cls,
+handle_client_disconnect (void *cls,
struct GNUNET_SERVER_Client *client)
{
struct Line *line;
+ if (NULL == client)
+ return;
line = GNUNET_SERVER_client_get_user_context (client, struct Line);
if (NULL == line)
return;
+ GNUNET_SERVER_client_set_user_context (client, NULL);
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+ "Client disconnected, closing line\n");
GNUNET_CONTAINER_DLL_remove (lines_head,
lines_tail,
line);
+ destroy_line_mesh_tunnels (line);
+ GNUNET_free_non_null (line->audio_data);
GNUNET_free (line);
- GNUNET_SERVER_client_set_user_context (client, NULL);
}
/**
* Shutdown nicely
- *
+ *
* @param cls closure, NULL
* @param tc the task context
*/
* @param c configuration
*/
static void
-run (void *cls,
+run (void *cls,
struct GNUNET_SERVER_Handle *server,
const struct GNUNET_CONFIGURATION_Handle *c)
{
{&handle_mesh_ring_message,
GNUNET_MESSAGE_TYPE_CONVERSATION_MESH_PHONE_RING,
sizeof (struct MeshPhoneRingMessage)},
- {&handle_mesh_hangup_message,
+ {&handle_mesh_hangup_message,
GNUNET_MESSAGE_TYPE_CONVERSATION_MESH_PHONE_HANG_UP,
0},
- {&handle_mesh_pickup_message,
+ {&handle_mesh_pickup_message,
GNUNET_MESSAGE_TYPE_CONVERSATION_MESH_PHONE_PICK_UP,
0},
- {&handle_mesh_busy_message,
+ {&handle_mesh_busy_message,
GNUNET_MESSAGE_TYPE_CONVERSATION_MESH_PHONE_BUSY,
sizeof (struct MeshPhoneBusyMessage)},
{&handle_mesh_audio_message, GNUNET_MESSAGE_TYPE_CONVERSATION_MESH_AUDIO,
0},
{NULL, 0, 0}
};
- static uint32_t ports[] = {
+ static uint32_t ports[] = {
GNUNET_APPLICATION_TYPE_CONVERSATION_CONTROL,
GNUNET_APPLICATION_TYPE_CONVERSATION_AUDIO,
- 0
+ 0
};
cfg = c;
GNUNET_assert (GNUNET_OK ==
- GNUNET_CRYPTO_get_host_identity (cfg,
+ GNUNET_CRYPTO_get_peer_identity (cfg,
&my_identity));
mesh = GNUNET_MESH_connect (cfg,
NULL,
&inbound_tunnel,
- &inbound_end,
- mesh_handlers,
+ &inbound_end,
+ mesh_handlers,
ports);
if (NULL == mesh)
nc = GNUNET_SERVER_notification_context_create (server, 16);
GNUNET_SERVER_add_handlers (server, server_handlers);
GNUNET_SERVER_disconnect_notify (server, &handle_client_disconnect, NULL);
- GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_FOREVER_REL,
+ GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_FOREVER_REL,
&do_shutdown,
NULL);
}
* @return 0 ok, 1 on error
*/
int
-main (int argc,
+main (int argc,
char *const *argv)
{
return (GNUNET_OK ==
GNUNET_SERVICE_run (argc, argv,
- "conversation",
+ "conversation",
GNUNET_SERVICE_OPTION_NONE,
&run, NULL)) ? 0 : 1;
}