[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[GNUnet-SVN] r30736 - gnunet/src/conversation
From: |
gnunet |
Subject: |
[GNUnet-SVN] r30736 - gnunet/src/conversation |
Date: |
Fri, 15 Nov 2013 22:20:18 +0100 |
Author: grothoff
Date: 2013-11-15 22:20:18 +0100 (Fri, 15 Nov 2013)
New Revision: 30736
Modified:
gnunet/src/conversation/conversation_api.c
gnunet/src/conversation/gnunet-service-conversation.c
Log:
-reworking connection to allow multiple waiting/active connections per line
Modified: gnunet/src/conversation/conversation_api.c
===================================================================
--- gnunet/src/conversation/conversation_api.c 2013-11-15 19:13:14 UTC (rev
30735)
+++ gnunet/src/conversation/conversation_api.c 2013-11-15 21:20:18 UTC (rev
30736)
@@ -624,6 +624,7 @@
* @param ego ego to use for name resolution (when determining caller ID)
* @param event_handler how to notify the owner of the phone about events
* @param event_handler_cls closure for @a event_handler
+ * @return NULL on error (no valid line configured)
*/
struct GNUNET_CONVERSATION_Phone *
GNUNET_CONVERSATION_phone_create (const struct GNUNET_CONFIGURATION_Handle
*cfg,
@@ -640,6 +641,8 @@
"LINE",
&line))
return NULL;
+ if (line >= (1 << 31))
+ return NULL;
phone = GNUNET_new (struct GNUNET_CONVERSATION_Phone);
if (GNUNET_OK !=
GNUNET_CRYPTO_get_peer_identity (cfg,
Modified: gnunet/src/conversation/gnunet-service-conversation.c
===================================================================
--- gnunet/src/conversation/gnunet-service-conversation.c 2013-11-15
19:13:14 UTC (rev 30735)
+++ gnunet/src/conversation/gnunet-service-conversation.c 2013-11-15
21:20:18 UTC (rev 30736)
@@ -44,64 +44,74 @@
/**
+ * A line connects a local client with a mesh channel (or, if it is an
+ * open line, is waiting for a mesh channel).
+ */
+struct Line;
+
+/**
* The possible connection status
*/
-enum LineStatus
+enum ChannelStatus
{
/**
- * We are waiting for incoming calls.
- */
- LS_CALLEE_LISTEN,
-
- /**
* Our phone is ringing, waiting for the client to pick up.
*/
- LS_CALLEE_RINGING,
+ CS_CALLEE_RINGING,
/**
* We are talking!
*/
- LS_CALLEE_CONNECTED,
+ CS_CALLEE_CONNECTED,
/**
* We're in shutdown, sending hangup messages before cleaning up.
*/
- LS_CALLEE_SHUTDOWN,
+ CS_CALLEE_SHUTDOWN,
/**
* We are waiting for the phone to be picked up.
*/
- LS_CALLER_CALLING,
+ CS_CALLER_CALLING,
/**
* We are talking!
*/
- LS_CALLER_CONNECTED,
+ CS_CALLER_CONNECTED,
/**
* We're in shutdown, sending hangup messages before cleaning up.
*/
- LS_CALLER_SHUTDOWN
+ CS_CALLER_SHUTDOWN
+
};
/**
- * A line connects a local client with a mesh channel (or, if it is an
- * open line, is waiting for a mesh channel).
+ * A `struct Channel` represents a mesh channel, which is a P2P
+ * connection to another conversation service. Multiple channels can
+ * be attached the the same `struct Line`, which represents a local
+ * client. We keep them in a linked list.
*/
-struct Line
+struct Channel
{
+
/**
- * Kept in a DLL.
+ * This is a DLL.
*/
- struct Line *next;
+ struct Channel *next;
/**
- * Kept in a DLL.
+ * This is a DLL.
*/
- struct Line *prev;
+ struct Channel *prev;
/**
+ * Line associated with the channel.
+ */
+ struct Line *line;
+
+ /**
* Handle for the reliable channel (contol data)
*/
struct GNUNET_MESH_Channel *channel_reliable;
@@ -122,11 +132,6 @@
struct GNUNET_MQ_Handle *reliable_mq;
/**
- * Handle to the line client.
- */
- struct GNUNET_SERVER_Client *client;
-
- /**
* Target of the line, if we are the caller.
*/
struct GNUNET_PeerIdentity target;
@@ -142,9 +147,9 @@
size_t audio_size;
/**
- * Our line number.
+ * Channel identifier.
*/
- uint32_t local_line;
+ uint32_t cid;
/**
* Remote line number.
@@ -154,12 +159,65 @@
/**
* Current status of this line.
*/
- enum LineStatus status;
+ enum ChannelStatus status;
+ /**
+ * #GNUNET_YES if the channel was suspended by the other peer.
+ */
+ int8_t suspended_remote;
+
+ /**
+ * #GNUNET_YES if the channel was suspended by the local client.
+ */
+ int8_t suspended_local;
+
};
/**
+ * A `struct Line` connects a local client with mesh channels.
+ */
+struct Line
+{
+ /**
+ * Kept in a DLL.
+ */
+ struct Line *next;
+
+ /**
+ * Kept in a DLL.
+ */
+ struct Line *prev;
+
+ /**
+ * This is a DLL.
+ */
+ struct Channel *channel_head;
+
+ /**
+ * This is a DLL.
+ */
+ struct Channel *channel_tail;
+
+ /**
+ * Handle to the line client.
+ */
+ struct GNUNET_SERVER_Client *client;
+
+ /**
+ * Generator for channel IDs.
+ */
+ uint32_t cid_gen;
+
+ /**
+ * Our line number.
+ */
+ uint32_t local_line;
+
+};
+
+
+/**
* Our configuration.
*/
static const struct GNUNET_CONFIGURATION_Handle *cfg;
@@ -212,7 +270,7 @@
const struct ClientPhoneRegisterMessage *msg;
struct Line *line;
- msg = (struct ClientPhoneRegisterMessage *) message;
+ msg = (const struct ClientPhoneRegisterMessage *) message;
line = GNUNET_SERVER_client_get_user_context (client, struct Line);
if (NULL != line)
{
@@ -227,7 +285,7 @@
GNUNET_CONTAINER_DLL_insert (lines_head,
lines_tail,
line);
- line->local_line = ntohl (msg->line);
+ line->local_line = ntohl (msg->line) & (~ (1 << 31));
GNUNET_SERVER_receive_done (client, GNUNET_OK);
}
@@ -247,19 +305,10 @@
const struct ClientPhonePickupMessage *msg;
struct GNUNET_MQ_Envelope *e;
struct MeshPhonePickupMessage *mppm;
- const char *meta;
struct Line *line;
- size_t len;
+ struct Channel *ch;
- msg = (struct ClientPhonePickupMessage *) message;
- meta = (const char *) &msg[1];
- len = ntohs (msg->header.size) - sizeof (struct ClientPhonePickupMessage);
- if ( (0 == len) ||
- ('\0' != meta[len - 1]) )
- {
- meta = NULL;
- len = 0;
- }
+ msg = (const struct ClientPhonePickupMessage *) message;
line = GNUNET_SERVER_client_get_user_context (client, struct Line);
if (NULL == line)
{
@@ -267,113 +316,118 @@
GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
return;
}
- switch (line->status)
+ for (ch = line->channel_head; NULL != ch; ch = ch->next)
+ if (msg->cid == ch->cid)
+ break;
+ if (NULL == ch)
{
- case LS_CALLEE_LISTEN:
+ /* could have been destroyed asynchronously, ignore message */
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
- "Ignoring client's PICKUP message, caller has HUNG UP
already\n");
- GNUNET_SERVER_receive_done (client, GNUNET_OK);
+ "Channel %u not found\n",
+ msg->cid);
+ return;
+ }
+ switch (ch->status)
+ {
+ case CS_CALLEE_RINGING:
+ ch->status = CS_CALLEE_CONNECTED;
break;
- case LS_CALLEE_RINGING:
- line->status = LS_CALLEE_CONNECTED;
- break;
- case LS_CALLEE_CONNECTED:
+ case CS_CALLEE_CONNECTED:
GNUNET_break (0);
GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
return;
- case LS_CALLEE_SHUTDOWN:
+ case CS_CALLEE_SHUTDOWN:
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
"Ignoring client's PICKUP message, line is in SHUTDOWN\n");
GNUNET_SERVER_receive_done (client, GNUNET_OK);
break;
- case LS_CALLER_CALLING:
- case LS_CALLER_CONNECTED:
- case LS_CALLER_SHUTDOWN:
+ case CS_CALLER_CALLING:
+ case CS_CALLER_CONNECTED:
+ case CS_CALLER_SHUTDOWN:
GNUNET_break (0);
GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
return;
}
- line->status = LS_CALLEE_CONNECTED;
+ GNUNET_break (CS_CALLEE_CONNECTED == ch->status);
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);
- memcpy (&mppm[1], meta, len);
- GNUNET_MQ_send (line->reliable_mq, e);
+ "Sending PICK_UP message to mesh\n");
+ e = GNUNET_MQ_msg (mppm,
+ GNUNET_MESSAGE_TYPE_CONVERSATION_MESH_PHONE_PICK_UP);
+ GNUNET_MQ_send (ch->reliable_mq, e);
GNUNET_SERVER_receive_done (client, GNUNET_OK);
}
/**
- * Destroy the mesh channels of a line.
+ * Destroy a channel.
*
- * @param line line to shutdown channels of
+ * @param ch channel to destroy.
*/
static void
-destroy_line_mesh_channels (struct Line *line)
+destroy_line_mesh_channels (struct Channel *ch)
{
+ struct Line *line = ch->line;
struct GNUNET_MESH_Channel *t;
- if (NULL != line->reliable_mq)
+ if (NULL != ch->reliable_mq)
{
- GNUNET_MQ_destroy (line->reliable_mq);
- line->reliable_mq = NULL;
+ GNUNET_MQ_destroy (ch->reliable_mq);
+ ch->reliable_mq = NULL;
}
- if (NULL != line->unreliable_mth)
+ if (NULL != ch->unreliable_mth)
{
- GNUNET_MESH_notify_transmit_ready_cancel (line->unreliable_mth);
- line->unreliable_mth = NULL;
+ GNUNET_MESH_notify_transmit_ready_cancel (ch->unreliable_mth);
+ ch->unreliable_mth = NULL;
}
- if (NULL != (t = line->channel_unreliable))
+ if (NULL != (t = ch->channel_unreliable))
{
- line->channel_unreliable = NULL;
+ ch->channel_unreliable = NULL;
GNUNET_MESH_channel_destroy (t);
}
- if (NULL != (t = line->channel_reliable))
+ if (NULL != (t = ch->channel_reliable))
{
- line->channel_reliable = NULL;
+ ch->channel_reliable = NULL;
GNUNET_MESH_channel_destroy (t);
}
+ GNUNET_CONTAINER_DLL_remove (line->channel_head,
+ line->channel_tail,
+ ch);
+ GNUNET_free_non_null (ch->audio_data);
+ GNUNET_free (ch);
}
/**
* We are done signalling shutdown to the other peer. Close down
- * (or reset) the line.
+ * the channel.
*
- * @param cls the `struct Line` to reset/terminate
+ * @param cls the `struct Channel` to reset/terminate
*/
static void
mq_done_finish_caller_shutdown (void *cls)
{
- struct Line *line = cls;
+ struct Channel *ch = cls;
- switch (line->status)
+ switch (ch->status)
{
- case LS_CALLEE_LISTEN:
+ case CS_CALLEE_RINGING:
GNUNET_break (0);
break;
- case LS_CALLEE_RINGING:
+ case CS_CALLEE_CONNECTED:
GNUNET_break (0);
break;
- case LS_CALLEE_CONNECTED:
+ case CS_CALLEE_SHUTDOWN:
+ destroy_line_mesh_channels (ch);
+ break;
+ case CS_CALLER_CALLING:
GNUNET_break (0);
break;
- case LS_CALLEE_SHUTDOWN:
- line->status = LS_CALLEE_LISTEN;
- destroy_line_mesh_channels (line);
- return;
- case LS_CALLER_CALLING:
- line->status = LS_CALLER_SHUTDOWN;
+ case CS_CALLER_CONNECTED:
+ GNUNET_break (0);
break;
- case LS_CALLER_CONNECTED:
- line->status = LS_CALLER_SHUTDOWN;
+ case CS_CALLER_SHUTDOWN:
+ destroy_line_mesh_channels (ch);
break;
- case LS_CALLER_SHUTDOWN:
- destroy_line_mesh_channels (line);
- break;
}
}
@@ -393,19 +447,81 @@
const struct ClientPhoneHangupMessage *msg;
struct GNUNET_MQ_Envelope *e;
struct MeshPhoneHangupMessage *mhum;
- const char *meta;
struct Line *line;
- size_t len;
+ struct Channel *ch;
- msg = (struct ClientPhoneHangupMessage *) message;
- meta = (const char *) &msg[1];
- len = ntohs (msg->header.size) - sizeof (struct ClientPhoneHangupMessage);
- if ( (0 == len) ||
- ('\0' != meta[len - 1]) )
+ msg = (const struct ClientPhoneHangupMessage *) message;
+ line = GNUNET_SERVER_client_get_user_context (client, struct Line);
+ if (NULL == line)
{
- meta = NULL;
- len = 0;
+ GNUNET_break (0);
+ GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
+ return;
}
+ for (ch = line->channel_head; NULL != ch; ch = ch->next)
+ if (msg->cid == ch->cid)
+ break;
+ if (NULL == ch)
+ {
+ /* could have been destroyed asynchronously, ignore message */
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+ "Channel %u not found\n",
+ msg->cid);
+ return;
+ }
+
+ switch (ch->status)
+ {
+ case CS_CALLEE_RINGING:
+ ch->status = CS_CALLEE_SHUTDOWN;
+ break;
+ case CS_CALLEE_CONNECTED:
+ ch->status = CS_CALLEE_SHUTDOWN;
+ break;
+ case CS_CALLEE_SHUTDOWN:
+ /* maybe the other peer closed asynchronously... */
+ return;
+ case CS_CALLER_CALLING:
+ ch->status = CS_CALLER_SHUTDOWN;
+ break;
+ case CS_CALLER_CONNECTED:
+ ch->status = CS_CALLER_SHUTDOWN;
+ break;
+ case CS_CALLER_SHUTDOWN:
+ /* maybe the other peer closed asynchronously... */
+ return;
+ }
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+ "Sending HANG_UP message via mesh\n");
+ e = GNUNET_MQ_msg (mhum,
+ GNUNET_MESSAGE_TYPE_CONVERSATION_MESH_PHONE_HANG_UP);
+ GNUNET_MQ_notify_sent (e,
+ &mq_done_finish_caller_shutdown,
+ ch);
+ GNUNET_MQ_send (ch->reliable_mq, e);
+ GNUNET_SERVER_receive_done (client, GNUNET_OK);
+}
+
+
+/**
+ * Function to handle a suspend request message from the client
+ *
+ * @param cls closure, NULL
+ * @param client the client from which the message is
+ * @param message the message from the client
+ */
+static void
+handle_client_suspend_message (void *cls,
+ struct GNUNET_SERVER_Client *client,
+ const struct GNUNET_MessageHeader *message)
+{
+ const struct ClientPhoneSuspendMessage *msg;
+ struct GNUNET_MQ_Envelope *e;
+ struct MeshPhoneSuspendMessage *mhum;
+ struct Line *line;
+ struct Channel *ch;
+
+ msg = (const struct ClientPhoneSuspendMessage *) message;
line = GNUNET_SERVER_client_get_user_context (client, struct Line);
if (NULL == line)
{
@@ -413,50 +529,132 @@
GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
return;
}
- switch (line->status)
+ for (ch = line->channel_head; NULL != ch; ch = ch->next)
+ if (msg->cid == ch->cid)
+ break;
+ if (NULL == ch)
{
- case LS_CALLEE_LISTEN:
+ /* could have been destroyed asynchronously, ignore message */
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+ "Channel %u not found\n",
+ msg->cid);
+ return;
+ }
+ if (GNUNET_YES == ch->suspended_local)
+ {
GNUNET_break (0);
- GNUNET_SERVER_receive_done (client, GNUNET_OK);
+ GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
return;
- case LS_CALLEE_RINGING:
- line->status = LS_CALLEE_SHUTDOWN;
+ }
+ switch (ch->status)
+ {
+ case CS_CALLEE_RINGING:
+ GNUNET_break (0);
+ GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
+ return;
+ case CS_CALLEE_CONNECTED:
+ ch->suspended_local = GNUNET_YES;
break;
- case LS_CALLEE_CONNECTED:
- line->status = LS_CALLEE_SHUTDOWN;
+ case CS_CALLEE_SHUTDOWN:
+ /* maybe the other peer closed asynchronously... */
+ return;
+ case CS_CALLER_CALLING:
+ GNUNET_break (0);
+ GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
+ return;
+ case CS_CALLER_CONNECTED:
+ ch->suspended_local = GNUNET_YES;
break;
- case LS_CALLEE_SHUTDOWN:
+ case CS_CALLER_SHUTDOWN:
+ /* maybe the other peer closed asynchronously... */
+ return;
+ }
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+ "Sending SUSPEND message via mesh\n");
+ e = GNUNET_MQ_msg (mhum,
+ GNUNET_MESSAGE_TYPE_CONVERSATION_MESH_PHONE_SUSPEND);
+ GNUNET_MQ_send (ch->reliable_mq, e);
+ GNUNET_SERVER_receive_done (client, GNUNET_OK);
+}
+
+
+/**
+ * Function to handle a resume request message from the client
+ *
+ * @param cls closure, NULL
+ * @param client the client from which the message is
+ * @param message the message from the client
+ */
+static void
+handle_client_resume_message (void *cls,
+ struct GNUNET_SERVER_Client *client,
+ const struct GNUNET_MessageHeader *message)
+{
+ const struct ClientPhoneResumeMessage *msg;
+ struct GNUNET_MQ_Envelope *e;
+ struct MeshPhoneResumeMessage *mhum;
+ struct Line *line;
+ struct Channel *ch;
+
+ msg = (const struct ClientPhoneResumeMessage *) message;
+ line = GNUNET_SERVER_client_get_user_context (client, struct Line);
+ if (NULL == line)
+ {
GNUNET_break (0);
- GNUNET_SERVER_receive_done (client, GNUNET_OK);
+ GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
return;
- case LS_CALLER_CALLING:
- line->status = LS_CALLER_SHUTDOWN;
+ }
+ for (ch = line->channel_head; NULL != ch; ch = ch->next)
+ if (msg->cid == ch->cid)
+ break;
+ if (NULL == ch)
+ {
+ /* could have been destroyed asynchronously, ignore message */
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+ "Channel %u not found\n",
+ msg->cid);
+ return;
+ }
+ if (GNUNET_YES != ch->suspended_local)
+ {
+ GNUNET_break (0);
+ GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
+ return;
+ }
+ switch (ch->status)
+ {
+ case CS_CALLEE_RINGING:
+ GNUNET_break (0);
+ GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
+ return;
+ case CS_CALLEE_CONNECTED:
+ ch->suspended_local = GNUNET_NO;
break;
- case LS_CALLER_CONNECTED:
- line->status = LS_CALLER_SHUTDOWN;
- break;
- case LS_CALLER_SHUTDOWN:
+ case CS_CALLEE_SHUTDOWN:
+ /* maybe the other peer closed asynchronously... */
+ return;
+ case CS_CALLER_CALLING:
GNUNET_break (0);
- GNUNET_SERVER_receive_done (client, GNUNET_OK);
+ GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
return;
+ case CS_CALLER_CONNECTED:
+ ch->suspended_local = GNUNET_NO;
+ break;
+ case CS_CALLER_SHUTDOWN:
+ /* maybe the other peer closed asynchronously... */
+ 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);
- memcpy (&mhum[1], meta, len);
- GNUNET_MQ_notify_sent (e,
- &mq_done_finish_caller_shutdown,
- line);
- GNUNET_MQ_send (line->reliable_mq, e);
+ "Sending RESUME message via mesh\n");
+ e = GNUNET_MQ_msg (mhum,
+ GNUNET_MESSAGE_TYPE_CONVERSATION_MESH_PHONE_RESUME);
+ GNUNET_MQ_send (ch->reliable_mq, e);
GNUNET_SERVER_receive_done (client, GNUNET_OK);
}
/**
- * Function to handle call request the client
+ * Function to handle call request from the client
*
* @param cls closure, NULL
* @param client the client from which the message is
@@ -469,10 +667,11 @@
{
const struct ClientCallMessage *msg;
struct Line *line;
+ struct Channel *ch;
struct GNUNET_MQ_Envelope *e;
struct MeshPhoneRingMessage *ring;
- msg = (struct ClientCallMessage *) message;
+ msg = (const struct ClientCallMessage *) message;
line = GNUNET_SERVER_client_get_user_context (client, struct Line);
if (NULL != line)
{
@@ -482,22 +681,27 @@
}
line = GNUNET_new (struct Line);
line->client = client;
+ line->local_line = (local_line_cnt++) | (1 << 31);
GNUNET_SERVER_client_set_user_context (client, line);
GNUNET_SERVER_notification_context_add (nc, client);
- line->target = msg->target;
GNUNET_CONTAINER_DLL_insert (lines_head,
lines_tail,
line);
- line->remote_line = ntohl (msg->line);
- line->status = LS_CALLER_CALLING;
- line->channel_reliable = GNUNET_MESH_channel_create (mesh,
- line,
+ ch = GNUNET_new (struct Channel);
+ ch->line = line;
+ GNUNET_CONTAINER_DLL_insert (line->channel_head,
+ line->channel_tail,
+ ch);
+ ch->target = msg->target;
+ ch->remote_line = ntohl (msg->line);
+ ch->status = CS_CALLER_CALLING;
+ ch->channel_reliable = GNUNET_MESH_channel_create (mesh,
+ ch,
&msg->target,
GNUNET_APPLICATION_TYPE_CONVERSATION_CONTROL,
GNUNET_NO,
GNUNET_YES);
- line->reliable_mq = GNUNET_MESH_mq_create (line->channel_reliable);
- line->local_line = local_line_cnt++;
+ ch->reliable_mq = GNUNET_MESH_mq_create (ch->channel_reliable);
e = GNUNET_MQ_msg (ring, GNUNET_MESSAGE_TYPE_CONVERSATION_MESH_PHONE_RING);
ring->purpose.purpose = htonl (GNUNET_SIGNATURE_PURPOSE_CONVERSATION_RING);
ring->purpose.size = htonl (sizeof (struct GNUNET_PeerIdentity) * 2 +
@@ -505,18 +709,18 @@
sizeof (struct
GNUNET_CRYPTO_EccSignaturePurpose) +
sizeof (struct GNUNET_CRYPTO_EcdsaPublicKey));
GNUNET_CRYPTO_ecdsa_key_get_public (&msg->caller_id,
- &ring->caller_id);
+ &ring->caller_id);
ring->remote_line = msg->line;
ring->source_line = line->local_line;
ring->target = msg->target;
ring->source = my_identity;
ring->expiration_time = GNUNET_TIME_absolute_hton
(GNUNET_TIME_relative_to_absolute (RING_TIMEOUT));
GNUNET_CRYPTO_ecdsa_sign (&msg->caller_id,
- &ring->purpose,
- &ring->signature);
+ &ring->purpose,
+ &ring->signature);
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
"Sending RING message via mesh\n");
- GNUNET_MQ_send (line->reliable_mq, e);
+ GNUNET_MQ_send (ch->reliable_mq, e);
GNUNET_SERVER_receive_done (client, GNUNET_OK);
}
@@ -524,7 +728,7 @@
/**
* Transmit audio data via unreliable mesh channel.
*
- * @param cls the `struct Line` we are transmitting for
+ * @param cls the `struct Channel` 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 @a buf
@@ -534,26 +738,26 @@
size_t size,
void *buf)
{
- struct Line *line = cls;
+ struct Channel *ch = cls;
struct MeshAudioMessage *mam = buf;
- line->unreliable_mth = NULL;
+ ch->unreliable_mth = NULL;
if ( (NULL == buf) ||
- (size < sizeof (struct MeshAudioMessage) + line->audio_size) )
+ (size < sizeof (struct MeshAudioMessage) + ch->audio_size) )
{
/* eh, other error handling? */
return 0;
}
- mam->header.size = htons (sizeof (struct MeshAudioMessage) +
line->audio_size);
+ mam->header.size = htons (sizeof (struct MeshAudioMessage) + ch->audio_size);
mam->header.type = htons (GNUNET_MESSAGE_TYPE_CONVERSATION_MESH_AUDIO);
- mam->remote_line = htonl (line->remote_line);
- memcpy (&mam[1], line->audio_data, line->audio_size);
- GNUNET_free (line->audio_data);
- line->audio_data = NULL;
+ mam->remote_line = htonl (ch->remote_line);
+ memcpy (&mam[1], ch->audio_data, ch->audio_size);
+ GNUNET_free (ch->audio_data);
+ ch->audio_data = NULL;
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;
+ ch->audio_size);
+ return sizeof (struct MeshAudioMessage) + ch->audio_size;
}
@@ -571,10 +775,11 @@
{
const struct ClientAudioMessage *msg;
struct Line *line;
+ struct Channel *ch;
size_t size;
size = ntohs (message->size) - sizeof (struct ClientAudioMessage);
- msg = (struct ClientAudioMessage *) message;
+ msg = (const struct ClientAudioMessage *) message;
line = GNUNET_SERVER_client_get_user_context (client, struct Line);
if (NULL == line)
{
@@ -582,60 +787,66 @@
GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
return;
}
- switch (line->status)
+ for (ch = line->channel_head; NULL != ch; ch = ch->next)
+ if (msg->cid == ch->cid)
+ break;
+ if (NULL == ch)
{
- case LS_CALLEE_LISTEN:
- /* could be OK if the line just was closed by the other side */
+ /* could have been destroyed asynchronously, ignore message */
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:
+ "Channel %u not found\n",
+ msg->cid);
+ return;
+ }
+
+ switch (ch->status)
+ {
+ case CS_CALLEE_RINGING:
+ case CS_CALLER_CALLING:
GNUNET_break (0);
GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
return;
- case LS_CALLEE_CONNECTED:
- case LS_CALLER_CONNECTED:
+ case CS_CALLEE_CONNECTED:
+ case CS_CALLER_CONNECTED:
/* common case, handled below */
break;
- case LS_CALLEE_SHUTDOWN:
- case LS_CALLER_SHUTDOWN:
+ case CS_CALLEE_SHUTDOWN:
+ case CS_CALLER_SHUTDOWN:
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->channel_unreliable)
+ if (NULL == ch->channel_unreliable)
{
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);
return;
}
- if (NULL != line->unreliable_mth)
+ if (NULL != ch->unreliable_mth)
{
/* NOTE: we may want to not do this and instead combine the data */
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
"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;
+ (unsigned int) ch->audio_size);
+ GNUNET_MESH_notify_transmit_ready_cancel (ch->unreliable_mth);
+ ch->unreliable_mth = NULL;
+ GNUNET_free (ch->audio_data);
+ ch->audio_data = NULL;
}
- line->audio_size = size;
- line->audio_data = GNUNET_malloc (line->audio_size);
- memcpy (line->audio_data,
+ ch->audio_size = size;
+ ch->audio_data = GNUNET_malloc (ch->audio_size);
+ memcpy (ch->audio_data,
&msg[1],
size);
- line->unreliable_mth = GNUNET_MESH_notify_transmit_ready
(line->channel_unreliable,
- GNUNET_NO,
-
GNUNET_TIME_UNIT_FOREVER_REL,
- sizeof (struct
MeshAudioMessage)
- + line->audio_size,
-
&transmit_line_audio,
- line);
+ ch->unreliable_mth = GNUNET_MESH_notify_transmit_ready
(ch->channel_unreliable,
+ GNUNET_NO,
+
GNUNET_TIME_UNIT_FOREVER_REL,
+ sizeof (struct
MeshAudioMessage)
+ + ch->audio_size,
+ &transmit_line_audio,
+ ch);
GNUNET_SERVER_receive_done (client, GNUNET_OK);
}
@@ -661,6 +872,7 @@
* @param cls closure, NULL
* @param channel the channel over which the message arrived
* @param channel_ctx the channel context, can be NULL
+ * or point to the `struct Channel`
* @param message the incoming message
* @return #GNUNET_OK
*/
@@ -672,9 +884,11 @@
{
const struct MeshPhoneRingMessage *msg;
struct Line *line;
+ struct Channel *ch;
struct GNUNET_MQ_Envelope *e;
struct MeshPhoneHangupMessage *hang_up;
struct ClientPhoneRingMessage cring;
+ struct GNUNET_MQ_Handle *reliable_mq;
msg = (const struct MeshPhoneRingMessage *) message;
if ( (msg->purpose.size != htonl (sizeof (struct GNUNET_PeerIdentity) * 2 +
@@ -691,30 +905,38 @@
return GNUNET_SYSERR;
}
for (line = lines_head; NULL != line; line = line->next)
- if ( (line->local_line == ntohl (msg->remote_line)) &&
- (LS_CALLEE_LISTEN == line->status) )
+ if (line->local_line == ntohl (msg->remote_line))
break;
if (NULL == line)
{
GNUNET_log (GNUNET_ERROR_TYPE_INFO,
_("No available phone for incoming call on line %u, sending
HANG_UP signal\n"),
ntohl (msg->remote_line));
- e = GNUNET_MQ_msg (hang_up,
GNUNET_MESSAGE_TYPE_CONVERSATION_MESH_PHONE_HANG_UP);
+ e = GNUNET_MQ_msg (hang_up,
+ GNUNET_MESSAGE_TYPE_CONVERSATION_MESH_PHONE_HANG_UP);
GNUNET_MQ_notify_sent (e,
&mq_done_destroy_channel,
channel);
- GNUNET_MQ_send (line->reliable_mq, e);
+ reliable_mq = GNUNET_MESH_mq_create (channel);
+ GNUNET_MQ_send (reliable_mq, e);
+ /* FIXME: do we need to clean up reliable_mq somehow/somewhere? */
GNUNET_MESH_receive_done (channel); /* needed? */
return GNUNET_OK;
}
- line->status = LS_CALLEE_RINGING;
- line->remote_line = ntohl (msg->source_line);
- line->channel_reliable = channel;
- line->reliable_mq = GNUNET_MESH_mq_create (line->channel_reliable);
- *channel_ctx = line;
+ ch = GNUNET_new (struct Channel);
+ ch->line = line;
+ GNUNET_CONTAINER_DLL_insert (line->channel_head,
+ line->channel_tail,
+ ch);
+ ch->status = CS_CALLEE_RINGING;
+ ch->remote_line = ntohl (msg->source_line);
+ ch->channel_reliable = channel;
+ ch->reliable_mq = GNUNET_MESH_mq_create (ch->channel_reliable);
+ ch->cid = line->cid_gen++;
+ *channel_ctx = ch;
cring.header.type = htons (GNUNET_MESSAGE_TYPE_CONVERSATION_CS_PHONE_RING);
cring.header.size = htons (sizeof (cring));
- cring.cid = htonl (0 /* FIXME */);
+ cring.cid = ch->cid;
cring.caller_id = msg->caller_id;
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
"Sending RING message to client\n");
@@ -733,6 +955,7 @@
* @param cls closure, NULL
* @param channel the channel over which the message arrived
* @param channel_ctx the channel context, can be NULL
+ * or point to the `struct Channel`
* @param message the incoming message
* @return #GNUNET_OK
*/
@@ -742,68 +965,40 @@
void **channel_ctx,
const struct GNUNET_MessageHeader *message)
{
- struct Line *line = *channel_ctx;
- const struct MeshPhoneHangupMessage *msg;
- const char *reason;
- size_t len = ntohs (message->size) - sizeof (struct MeshPhoneHangupMessage);
- char buf[len + sizeof (struct ClientPhoneHangupMessage)];
- struct ClientPhoneHangupMessage *hup;
+ struct Channel *ch = *channel_ctx;
+ struct Line *line;
+ struct ClientPhoneHangupMessage hup;
- msg = (const struct MeshPhoneHangupMessage *) message;
- len = ntohs (msg->header.size) - sizeof (struct MeshPhoneHangupMessage);
- reason = (const char *) &msg[1];
- if ( (0 == len) ||
- ('\0' != reason[len - 1]) )
+ if (NULL == ch)
{
- reason = NULL;
- len = 0;
- }
- if (NULL == line)
- {
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
"HANGUP message received for non-existing line, dropping
channel.\n");
return GNUNET_SYSERR;
}
+ line = ch->line;
*channel_ctx = NULL;
- switch (line->status)
+ hup.header.size = sizeof (hup);
+ hup.header.type = htons (GNUNET_MESSAGE_TYPE_CONVERSATION_CS_PHONE_HANG_UP);
+ hup.cid = ch->cid;
+ destroy_line_mesh_channels (ch);
+ switch (ch->status)
{
- case LS_CALLEE_LISTEN:
- GNUNET_break (0);
- return GNUNET_SYSERR;
- case LS_CALLEE_RINGING:
- line->status = LS_CALLEE_LISTEN;
- destroy_line_mesh_channels (line);
+ case CS_CALLEE_RINGING:
+ case CS_CALLEE_CONNECTED:
break;
- case LS_CALLEE_CONNECTED:
- line->status = LS_CALLEE_LISTEN;
- destroy_line_mesh_channels (line);
- break;
- case LS_CALLEE_SHUTDOWN:
- line->status = LS_CALLEE_LISTEN;
- destroy_line_mesh_channels (line);
+ case CS_CALLEE_SHUTDOWN:
return GNUNET_OK;
- case LS_CALLER_CALLING:
- line->status = LS_CALLER_SHUTDOWN;
- mq_done_finish_caller_shutdown (line);
+ case CS_CALLER_CALLING:
+ case CS_CALLER_CONNECTED:
break;
- case LS_CALLER_CONNECTED:
- line->status = LS_CALLER_SHUTDOWN;
- mq_done_finish_caller_shutdown (line);
- break;
- case LS_CALLER_SHUTDOWN:
- mq_done_finish_caller_shutdown (line);
+ case CS_CALLER_SHUTDOWN:
return GNUNET_OK;
}
- hup = (struct ClientPhoneHangupMessage *) buf;
- 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);
+ "Sending HANG UP message to client\n");
GNUNET_SERVER_notification_context_unicast (nc,
line->client,
- &hup->header,
+ &hup.header,
GNUNET_NO);
GNUNET_MESH_receive_done (channel);
return GNUNET_OK;
@@ -816,6 +1011,7 @@
* @param cls closure, NULL
* @param channel the channel over which the message arrived
* @param channel_ctx the channel context, can be NULL
+ * or point to the `struct Channel`
* @param message the incoming message
* @return #GNUNET_OK
*/
@@ -825,74 +1021,56 @@
void **channel_ctx,
const struct GNUNET_MessageHeader *message)
{
- const struct MeshPhonePickupMessage *msg;
- struct Line *line = *channel_ctx;
- const char *metadata;
- size_t len = ntohs (message->size) - sizeof (struct MeshPhonePickupMessage);
- char buf[len + sizeof (struct ClientPhonePickupMessage)];
- struct ClientPhonePickupMessage *pick;
+ struct Channel *ch = *channel_ctx;
+ struct Line *line;
+ struct ClientPhonePickupMessage pick;
- msg = (const struct MeshPhonePickupMessage *) message;
- len = ntohs (msg->header.size) - sizeof (struct MeshPhonePickupMessage);
- metadata = (const char *) &msg[1];
- if ( (0 == len) ||
- ('\0' != metadata[len - 1]) )
+ if (NULL == ch)
{
- metadata = NULL;
- len = 0;
- }
- if (NULL == line)
- {
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
- "PICKUP message received for non-existing line, dropping
channel.\n");
+ "PICKUP message received for non-existing channel, dropping
channel.\n");
return GNUNET_SYSERR;
}
+ line = ch->line;
GNUNET_MESH_receive_done (channel);
- switch (line->status)
+ switch (ch->status)
{
- case LS_CALLEE_LISTEN:
- GNUNET_break (0);
- return GNUNET_SYSERR;
- case LS_CALLEE_RINGING:
- case LS_CALLEE_CONNECTED:
+ case CS_CALLEE_RINGING:
+ case CS_CALLEE_CONNECTED:
GNUNET_break_op (0);
- destroy_line_mesh_channels (line);
- line->status = LS_CALLEE_LISTEN;
+ destroy_line_mesh_channels (ch);
return GNUNET_SYSERR;
- case LS_CALLEE_SHUTDOWN:
+ case CS_CALLEE_SHUTDOWN:
GNUNET_break_op (0);
- line->status = LS_CALLEE_LISTEN;
- destroy_line_mesh_channels (line);
+ destroy_line_mesh_channels (ch);
break;
- case LS_CALLER_CALLING:
- line->status = LS_CALLER_CONNECTED;
+ case CS_CALLER_CALLING:
+ ch->status = CS_CALLER_CONNECTED;
break;
- case LS_CALLER_CONNECTED:
+ case CS_CALLER_CONNECTED:
GNUNET_break_op (0);
return GNUNET_OK;
- case LS_CALLER_SHUTDOWN:
+ case CS_CALLER_SHUTDOWN:
GNUNET_break_op (0);
- mq_done_finish_caller_shutdown (line);
+ mq_done_finish_caller_shutdown (ch);
return GNUNET_SYSERR;
}
- pick = (struct ClientPhonePickupMessage *) buf;
- pick->header.size = sizeof (buf);
- pick->header.type = htons
(GNUNET_MESSAGE_TYPE_CONVERSATION_CS_PHONE_PICKED_UP);
- memcpy (&pick[1], metadata, len);
+ pick.header.size = sizeof (pick);
+ pick.header.type = htons
(GNUNET_MESSAGE_TYPE_CONVERSATION_CS_PHONE_PICKED_UP);
+ pick.cid = ch->cid;
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
- "Sending PICKED UP message to client with metadata `%s'\n",
- metadata);
+ "Sending PICKED UP message to client\n");
GNUNET_SERVER_notification_context_unicast (nc,
line->client,
- &pick->header,
+ &pick.header,
GNUNET_NO);
- line->channel_unreliable = GNUNET_MESH_channel_create (mesh,
- line,
- &line->target,
+ ch->channel_unreliable = GNUNET_MESH_channel_create (mesh,
+ ch,
+ &ch->target,
GNUNET_APPLICATION_TYPE_CONVERSATION_AUDIO,
GNUNET_YES,
GNUNET_NO);
- if (NULL == line->channel_unreliable)
+ if (NULL == ch->channel_unreliable)
{
GNUNET_break (0);
}
@@ -906,6 +1084,7 @@
* @param cls closure, NULL
* @param channel the channel over which the message arrived
* @param channel_ctx the channel context, can be NULL
+ * or point to the `struct Channel`
* @param message the incoming message
* @return #GNUNET_OK
*/
@@ -915,54 +1094,44 @@
void **channel_ctx,
const struct GNUNET_MessageHeader *message)
{
- struct Line *line = *channel_ctx;
+ struct Channel *ch = *channel_ctx;
+ struct Line *line;
struct ClientPhoneSuspendMessage suspend;
- if (NULL == line)
+ if (NULL == ch)
{
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
"SUSPEND message received for non-existing line, dropping
channel.\n");
return GNUNET_SYSERR;
}
+ line = ch->line;
suspend.header.size = sizeof (suspend);
suspend.header.type = htons
(GNUNET_MESSAGE_TYPE_CONVERSATION_CS_PHONE_SUSPEND);
- suspend.cid = htonl (0 /* FIXME */);
+ suspend.cid = ch->cid;
GNUNET_MESH_receive_done (channel);
- *channel_ctx = NULL;
- switch (line->status)
+ switch (ch->status)
{
- case LS_CALLEE_LISTEN:
- GNUNET_break (0);
- return GNUNET_SYSERR;
- case LS_CALLEE_RINGING:
+ case CS_CALLEE_RINGING:
GNUNET_break_op (0);
break;
- case LS_CALLEE_CONNECTED:
- GNUNET_break_op (0);
+ case CS_CALLEE_CONNECTED:
+ ch->suspended_remote = GNUNET_YES;
break;
- case LS_CALLEE_SHUTDOWN:
+ case CS_CALLEE_SHUTDOWN:
+ return GNUNET_OK;
+ case CS_CALLER_CALLING:
GNUNET_break_op (0);
break;
- case LS_CALLER_CALLING:
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
- "Sending SUSPEND message to client\n");
- GNUNET_SERVER_notification_context_unicast (nc,
- line->client,
- &suspend.header,
- GNUNET_NO);
- line->status = LS_CALLER_SHUTDOWN;
- mq_done_finish_caller_shutdown (line);
+ case CS_CALLER_CONNECTED:
+ ch->suspended_remote = GNUNET_YES;
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;
+ case CS_CALLER_SHUTDOWN:
+ return GNUNET_OK;
}
+ GNUNET_SERVER_notification_context_unicast (nc,
+ line->client,
+ &suspend.header,
+ GNUNET_NO);
return GNUNET_OK;
}
@@ -973,6 +1142,7 @@
* @param cls closure, NULL
* @param channel the channel over which the message arrived
* @param channel_ctx the channel context, can be NULL
+ * or point to the `struct Channel`
* @param message the incoming message
* @return #GNUNET_OK
*/
@@ -982,54 +1152,50 @@
void **channel_ctx,
const struct GNUNET_MessageHeader *message)
{
- struct Line *line = *channel_ctx;
+ struct Channel *ch = *channel_ctx;
+ struct Line *line;
struct ClientPhoneResumeMessage resume;
- if (NULL == line)
+ if (NULL == ch)
{
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
"RESUME message received for non-existing line, dropping
channel.\n");
return GNUNET_SYSERR;
}
+ line = ch->line;
resume.header.size = sizeof (resume);
resume.header.type = htons
(GNUNET_MESSAGE_TYPE_CONVERSATION_CS_PHONE_RESUME);
- resume.cid = htonl (0 /* FIXME */);
+ resume.cid = ch->cid;
GNUNET_MESH_receive_done (channel);
- *channel_ctx = NULL;
- switch (line->status)
+ if (GNUNET_YES != ch->suspended_remote)
{
- case LS_CALLEE_LISTEN:
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+ "RESUME message received for non-suspended channel, dropping
channel.\n");
+ return GNUNET_SYSERR;
+ }
+ switch (ch->status)
+ {
+ case CS_CALLEE_RINGING:
GNUNET_break (0);
- return GNUNET_SYSERR;
- case LS_CALLEE_RINGING:
- GNUNET_break_op (0);
break;
- case LS_CALLEE_CONNECTED:
- GNUNET_break_op (0);
+ case CS_CALLEE_CONNECTED:
+ ch->suspended_remote = GNUNET_NO;
break;
- case LS_CALLEE_SHUTDOWN:
- GNUNET_break_op (0);
+ case CS_CALLEE_SHUTDOWN:
+ return GNUNET_OK;
+ case CS_CALLER_CALLING:
+ GNUNET_break (0);
break;
- case LS_CALLER_CALLING:
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
- "Sending SUSPEND message to client\n");
- GNUNET_SERVER_notification_context_unicast (nc,
- line->client,
- &resume.header,
- GNUNET_NO);
- line->status = LS_CALLER_SHUTDOWN;
- mq_done_finish_caller_shutdown (line);
+ case CS_CALLER_CONNECTED:
+ ch->suspended_remote = GNUNET_NO;
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;
+ case CS_CALLER_SHUTDOWN:
+ return GNUNET_OK;
}
+ GNUNET_SERVER_notification_context_unicast (nc,
+ line->client,
+ &resume.header,
+ GNUNET_NO);
return GNUNET_OK;
}
@@ -1040,6 +1206,7 @@
* @param cls closure, NULL
* @param channel the channel over which the message arrived
* @param channel_ctx the channel context, can be NULL
+ * or point to the `struct Channel`
* @param message the incoming message
* @return #GNUNET_OK
*/
@@ -1050,7 +1217,8 @@
const struct GNUNET_MessageHeader *message)
{
const struct MeshAudioMessage *msg;
- struct Line *line = *channel_ctx;
+ struct Channel *ch = *channel_ctx;
+ struct Line *line;
struct GNUNET_PeerIdentity sender;
size_t msize = ntohs (message->size) - sizeof (struct MeshAudioMessage);
char buf[msize + sizeof (struct ClientAudioMessage)];
@@ -1058,10 +1226,10 @@
const union GNUNET_MESH_ChannelInfo *info;
msg = (const struct MeshAudioMessage *) message;
- if (NULL == line)
+ if (NULL == ch)
{
info = GNUNET_MESH_channel_get_info (channel,
- GNUNET_MESH_OPTION_PEER);
+ GNUNET_MESH_OPTION_PEER);
if (NULL == info)
{
GNUNET_break (0);
@@ -1069,22 +1237,27 @@
}
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) &&
- (0 == memcmp (&line->target,
- &sender,
- sizeof (struct GNUNET_PeerIdentity))) &&
- (NULL == line->channel_unreliable) )
- break;
- if (NULL == line)
+ if (line->local_line == ntohl (msg->remote_line))
+ {
+ for (ch = line->channel_head; NULL != ch; ch = ch->next)
+ {
+ if ( (CS_CALLEE_CONNECTED == ch->status) &&
+ (0 == memcmp (&ch->target,
+ &sender,
+ sizeof (struct GNUNET_PeerIdentity))) &&
+ (NULL == ch->channel_unreliable) )
+ break;
+ }
+ }
+ if (NULL == ch)
{
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
"Received AUDIO data for non-existing line %u, dropping.\n",
ntohl (msg->remote_line));
return GNUNET_SYSERR;
}
- line->channel_unreliable = channel;
- *channel_ctx = line;
+ ch->channel_unreliable = channel;
+ *channel_ctx = ch;
}
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
"Forwarding %u bytes of AUDIO data to client\n",
@@ -1092,6 +1265,7 @@
cam = (struct ClientAudioMessage *) buf;
cam->header.size = htons (sizeof (buf));
cam->header.type = htons (GNUNET_MESSAGE_TYPE_CONVERSATION_CS_AUDIO);
+ cam->cid = ch->cid;
memcpy (&cam[1], &msg[1], msize);
GNUNET_SERVER_notification_context_unicast (nc,
line->client,
@@ -1110,7 +1284,8 @@
* @param channel new handle to the channel
* @param initiator peer that started the channel
* @param port port
- * @return initial channel context for the channel (can be NULL -- that's not
an error)
+ * @return initial channel context for the channel;
+ * (can be NULL -- that's not an error)
*/
static void *
inbound_channel (void *cls,
@@ -1132,63 +1307,62 @@
* @param cls closure (set from #GNUNET_MESH_connect)
* @param channel connection to the other end (henceforth invalid)
* @param channel_ctx place where local state associated
- * with the channel is stored
+ * with the channel is stored;
+ * may point to the `struct Channel`
*/
static void
inbound_end (void *cls,
const struct GNUNET_MESH_Channel *channel,
void *channel_ctx)
{
- struct Line *line = channel_ctx;
+ struct Channel *ch = channel_ctx;
+ struct Line *line;
struct ClientPhoneHangupMessage hup;
- if (NULL == line)
+ if (NULL == ch)
return;
- if (line->channel_unreliable == channel)
+ line = ch->line;
+ if (ch->channel_unreliable == channel)
{
- if (NULL != line->unreliable_mth)
+ if (NULL != ch->unreliable_mth)
{
- GNUNET_MESH_notify_transmit_ready_cancel (line->unreliable_mth);
- line->unreliable_mth = NULL;
+ GNUNET_MESH_notify_transmit_ready_cancel (ch->unreliable_mth);
+ ch->unreliable_mth = NULL;
}
- line->channel_unreliable = NULL;
+ ch->channel_unreliable = NULL;
return;
}
- if (line->channel_reliable != channel)
+ if (ch->channel_reliable != channel)
return;
- line->channel_reliable = NULL;
+ ch->channel_reliable = NULL;
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
"Mesh channel destroyed by mesh\n");
hup.header.size = sizeof (hup);
hup.header.type = htons (GNUNET_MESSAGE_TYPE_CONVERSATION_CS_PHONE_HANG_UP);
- switch (line->status)
+ hup.cid = ch->cid;
+ switch (ch->status)
{
- case LS_CALLEE_LISTEN:
- GNUNET_break (0);
- break;
- case LS_CALLEE_RINGING:
- case LS_CALLEE_CONNECTED:
+ case CS_CALLEE_RINGING:
+ case CS_CALLEE_CONNECTED:
GNUNET_SERVER_notification_context_unicast (nc,
line->client,
&hup.header,
GNUNET_NO);
- line->status = LS_CALLEE_LISTEN;
break;
- case LS_CALLEE_SHUTDOWN:
- line->status = LS_CALLEE_LISTEN;
+ case CS_CALLEE_SHUTDOWN:
break;
- case LS_CALLER_CALLING:
- case LS_CALLER_CONNECTED:
+ case CS_CALLER_CALLING:
+ case CS_CALLER_CONNECTED:
GNUNET_SERVER_notification_context_unicast (nc,
line->client,
&hup.header,
GNUNET_NO);
break;
- case LS_CALLER_SHUTDOWN:
+ case CS_CALLER_SHUTDOWN:
break;
}
- destroy_line_mesh_channels (line);
+ destroy_line_mesh_channels (ch);
}
@@ -1215,8 +1389,8 @@
GNUNET_CONTAINER_DLL_remove (lines_head,
lines_tail,
line);
- destroy_line_mesh_channels (line);
- GNUNET_free_non_null (line->audio_data);
+ while (NULL != line->channel_head)
+ destroy_line_mesh_channels (line->channel_head);
GNUNET_free (line);
}
@@ -1262,13 +1436,19 @@
sizeof (struct ClientPhoneRegisterMessage)},
{&handle_client_pickup_message, NULL,
GNUNET_MESSAGE_TYPE_CONVERSATION_CS_PHONE_PICK_UP,
- 0},
+ sizeof (struct ClientPhonePickupMessage) },
+ {&handle_client_suspend_message, NULL,
+ GNUNET_MESSAGE_TYPE_CONVERSATION_CS_PHONE_SUSPEND,
+ sizeof (struct ClientPhoneSuspendMessage) },
+ {&handle_client_resume_message, NULL,
+ GNUNET_MESSAGE_TYPE_CONVERSATION_CS_PHONE_RESUME,
+ sizeof (struct ClientPhoneResumeMessage) },
{&handle_client_hangup_message, NULL,
GNUNET_MESSAGE_TYPE_CONVERSATION_CS_PHONE_HANG_UP,
- 0},
+ sizeof (struct ClientPhoneHangupMessage) },
{&handle_client_call_message, NULL,
GNUNET_MESSAGE_TYPE_CONVERSATION_CS_PHONE_CALL,
- 0},
+ sizeof (struct ClientCallMessage) },
{&handle_client_audio_message, NULL,
GNUNET_MESSAGE_TYPE_CONVERSATION_CS_AUDIO,
0},
@@ -1280,10 +1460,10 @@
sizeof (struct MeshPhoneRingMessage)},
{&handle_mesh_hangup_message,
GNUNET_MESSAGE_TYPE_CONVERSATION_MESH_PHONE_HANG_UP,
- 0},
+ sizeof (struct MeshPhoneHangupMessage)},
{&handle_mesh_pickup_message,
GNUNET_MESSAGE_TYPE_CONVERSATION_MESH_PHONE_PICK_UP,
- 0},
+ sizeof (struct MeshPhonePickupMessage)},
{&handle_mesh_suspend_message,
GNUNET_MESSAGE_TYPE_CONVERSATION_MESH_PHONE_SUSPEND,
sizeof (struct MeshPhoneSuspendMessage)},
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [GNUnet-SVN] r30736 - gnunet/src/conversation,
gnunet <=