fixed various bugs with priorty dispatch of voice traffic.

some debug tweaking etc.
This commit is contained in:
gardners 2012-05-07 08:31:53 +09:30
parent 602c00efd7
commit 7b520e7a49
8 changed files with 108 additions and 21 deletions

View File

@ -376,7 +376,15 @@ int monitor_process_command(int index,char *cmd)
vomp_mdp_event(&mdp,NULL,0);
}
}
else if (sscanf(cmd,"pickup %x",&callSessionToken)==1) {
else if (sscanf(cmd,"status %x",&callSessionToken)==1) {
int i;
for(i=0;i<vomp_call_count;i++)
if (vomp_call_states[i].local.session==callSessionToken
||callSessionToken==0) {
vomp_call_states[i].local.last_state=0;
monitor_call_status(&vomp_call_states[i]);
}
} else if (sscanf(cmd,"pickup %x",&callSessionToken)==1) {
mdp.vompevent.flags=VOMPEVENT_PICKUP;
mdp.vompevent.call_session_token=callSessionToken;
vomp_mdp_event(&mdp,NULL,0);
@ -460,6 +468,7 @@ int monitor_call_status(vomp_call_state *call)
call->local.last_state=call->local.state;
call->remote.last_state=call->remote.state;
if (show) {
if (0) WHYF("sending call status to monitor");
snprintf(msg,1024,"CALLSTATUS:%06x:%06x:%d:%d:%s:%s:%s:%s\n",
call->local.session,call->remote.session,
call->local.state,call->remote.state,

View File

@ -556,3 +556,13 @@ int overlay_abbreviate_set_most_recent_address(unsigned char *in)
overlay_render_sid(in));
return 0;
}
int overlay_abbreviate_clear_most_recent_address()
{
/* make previous address invalid (first byte must be >0x0f to be valid) */
overlay_abbreviate_previous_address.b[0]=0x00;
if (debug&DEBUG_OVERLAYABBREVIATIONS)
fprintf(stderr,"Cleared most recent address\n");
return 0;
}

View File

@ -798,7 +798,10 @@ int overlay_tick_interface(int i, long long now)
component payloads are all self-authenticating, or at least that is the theory. */
unsigned char bytes[]={/* Magic */ 'O',0x10,
/* Version */ 0x00,0x01};
if (ob_append_bytes(e,bytes,4)) return WHY("ob_append_bytes() refused to append magic bytes.");
if (ob_append_bytes(e,bytes,4)) {
ob_free(e);
return WHY("ob_append_bytes() refused to append magic bytes.");
}
/* 1. Send announcement about ourselves, including one SID that we host if we host more than one SID
(the first SID we host becomes our own identity, saving a little bit of data here).

View File

@ -898,8 +898,10 @@ int overlay_mdp_dispatch(overlay_mdp_frame *mdp,int userGeneratedFrameP,
}
int q=OQ_ORDINARY;
if (mdp->out.dst.port==MDP_PORT_VOMP) q=OQ_ISOCHRONOUS_VOICE;
if (overlay_payload_enqueue(OQ_ORDINARY,frame,0))
if (mdp->out.dst.port==MDP_PORT_VOMP) {
q=OQ_ISOCHRONOUS_VOICE;
}
if (overlay_payload_enqueue(q,frame,0))
{
if (frame) op_free(frame);
return WHY("Error enqueuing frame");

View File

@ -244,7 +244,51 @@ int overlay_payload_enqueue(int q,overlay_frame *p,int forceBroadcastP)
Complain if there are too many frames in the queue.
*/
if (q==OQ_ISOCHRONOUS_VOICE&&(!forceBroadcastP)) {
/* Dispatch voice data immediately. */
int interface=-1;
int nexthoplen=SID_SIZE;
overlay_abbreviate_clear_most_recent_address();
if (overlay_get_nexthop(p->destination,p->nexthop,&nexthoplen,
&interface)) {
return WHY("Failed to resolve nexthop for voice packet");
}
if (interface==-1) {
return WHY("Failed to determine interface for sending voice packet");
}
overlay_buffer *b=ob_new(overlay_interfaces[interface].mtu);
unsigned char bytes[]={/* Magic */ 'O',0x10,
/* Version */ 0x00,0x01};
if (ob_append_bytes(b,bytes,4)) {
ob_free(b);
return WHY("ob_append_bytes() refused to append magic bytes.");
}
if (overlay_frame_package_fmt1(p,b)) {
ob_free(b);
return WHY("could not package voice frame for immediate dispatch");
}
if (debug&DEBUG_OVERLAYINTERFACES)
WHYF("Sending %d byte voice packet",b->length);
if (!overlay_broadcast_ensemble(interface,NULL,b->bytes,b->length))
{
overlay_update_sequence_number();
if (debug&DEBUG_OVERLAYINTERFACES)
WHYF("Voice frame #%lld sent on interface #%d (%d bytes)",
(long long)overlay_sequence_number,interface,b->length);
ob_free(b);
return 0;
} else {
WHYF("Failed to send voice frame on interface #%d (%d bytes)",
interface,b->length);
ob_free(b);
return -1;
}
}
if (q<0||q>=OQ_MAX) return WHY("Invalid queue specified");
if (!p) return WHY("Cannot queue NULL");
@ -276,22 +320,6 @@ int overlay_payload_enqueue(int q,overlay_frame *p,int forceBroadcastP)
if (0) dump_queue("after",q);
if (q==OQ_ISOCHRONOUS_VOICE
||(overlay_tx[q].length>=(overlay_tx[q].maxLength/2)))
{
/* queues are getting a bit full, so pump some packets out now.
XXX - this is a bit crude, as it should work out which
interfaces need prodding, and also correctly prioritise what
goes into the packet. Also, it should make sure the queue is
not too full after. */
int i;
long long now=overlay_gettime_ms();
for(i=0;i<overlay_interface_count;i++) {
overlay_tick_interface(i,now);
overlay_interfaces[i].last_tick_ms=now;
}
}
return 0;
}

View File

@ -388,6 +388,7 @@ int overlay_get_nexthop(unsigned char *d,unsigned char *nexthop,int *nexthoplen,
}
if (neh->scores[*interface]<1) {
if (debug&DEBUG_OVERLAYROUTING)
*interface=-1;
WHYF("No open path to %s\n",overlay_render_sid(neh->node->sid));
return -1;
}

View File

@ -840,6 +840,7 @@ int overlay_abbreviate_cache_lookup(unsigned char *in,unsigned char *out,int *of
int overlay_abbreviate_remember_index(int index_byte_count,unsigned char *in,unsigned char *index_bytes);
extern int overlay_abbreviate_repeat_policy;
int overlay_abbreviate_set_most_recent_address(unsigned char *in);
int overlay_abbreviate_clear_most_recent_address();
/* Return codes for resolution of abbreviated addressses */
#define OA_UNINITIALISED 0 /* Nothing has been written into the field */

35
vomp.c
View File

@ -602,6 +602,8 @@ int vomp_mdp_event(overlay_mdp_frame *mdp,
call->create_time=overlay_gettime_ms();
call->local.state=VOMP_STATE_CALLPREP;
call->remote.state=VOMP_STATE_NOCALL; /* far end has yet to agree that a call is happening */
monitor_call_status(call);
/* allocate unique call session token, which is how the client will
refer to this call during its life */
while (!call->local.session)
@ -644,6 +646,7 @@ int vomp_mdp_event(overlay_mdp_frame *mdp,
"No such call");
if (call->local.state==VOMP_STATE_INCALL) vomp_call_stop_audio(call);
call->local.state=VOMP_STATE_CALLENDED;
monitor_call_status(call);
overlay_mdp_reply_error(mdp_named_socket,
recvaddr,recvaddrlen,0,"Success");
return vomp_send_status(call,VOMP_TELLREMOTE|VOMP_TELLINTERESTED,NULL);
@ -660,6 +663,7 @@ int vomp_mdp_event(overlay_mdp_frame *mdp,
"No such call");
if (call->local.state==VOMP_STATE_RINGINGIN) {
call->local.state=VOMP_STATE_INCALL;
monitor_call_status(call);
call->ringing=0;
/* state machine does job of starting audio stream, just tell everyone about
the changed state. */
@ -767,6 +771,7 @@ int vomp_mdp_received(overlay_mdp_frame *mdp)
call->last_activity=overlay_gettime_ms();
call->remote.sequence=sender_seq;
call->remote.state=sender_state;
monitor_call_status(call);
return vomp_send_status(call,VOMP_TELLREMOTE|VOMP_TELLCODECS,NULL);
} else {
if (0) WHY("recvr_session!=0, looking for existing call");
@ -783,15 +788,21 @@ int vomp_mdp_received(overlay_mdp_frame *mdp)
{
/* No registered listener, so we cannot answer the call, so just reject
it. */
WHYF("Rejecting call due to lack of a listener: states=%d,%d",
if (0) WHYF("Rejecting call due to lack of a listener: states=%d,%d",
call->local.state,call->remote.state);
call->local.state=VOMP_STATE_CALLENDED;
monitor_call_status(call);
if (call->remote.state<VOMP_STATE_CALLENDED)
vomp_send_status(call,VOMP_TELLREMOTE,NULL);
/* now let the state machine progress to destroy the call */
}
if (0) {
WHYF("Far end is in state %s",vomp_describe_state(sender_state));
WHYF("I am in state %s",vomp_describe_state(call->local.state));
}
/* Consider states: our actual state, sender state, what the sender thinks
our state is, and what we think the sender's state is. But largely it
breaks down to what we think our state is, and what they think their
@ -799,6 +810,7 @@ int vomp_mdp_received(overlay_mdp_frame *mdp)
int combined_state=call->local.state<<3;
combined_state|=sender_state;
call->remote.state=sender_state;
monitor_call_status(call);
switch(combined_state) {
case (VOMP_STATE_NOCALL<<3)|VOMP_STATE_NOCALL:
/* We both think that we are not yet in a call, and we have session numbers
@ -828,6 +840,7 @@ int vomp_mdp_received(overlay_mdp_frame *mdp)
until we both have acknowledged this (when I am RINGINGIN and they are
RINGINGOUT). */
call->local.state=VOMP_STATE_RINGINGIN;
monitor_call_status(call);
vomp_extract_remote_codec_list(call,mdp);
break;
case (VOMP_STATE_NOCALL<<3)|VOMP_STATE_RINGINGIN:
@ -836,6 +849,7 @@ int vomp_mdp_received(overlay_mdp_frame *mdp)
We just keep persisting, because once they acknowledge this, we will
both move to CALLENDED and hang up */
call->local.state=VOMP_STATE_CALLENDED;
monitor_call_status(call);
break;
case (VOMP_STATE_NOCALL<<3)|VOMP_STATE_INCALL:
/* As above, a call has probably been hung up by us, but the far end has
@ -845,6 +859,7 @@ int vomp_mdp_received(overlay_mdp_frame *mdp)
case (VOMP_STATE_NOCALL<<3)|VOMP_STATE_CALLENDED:
/* Far end has given up on the call, so also move to CALLENDED */
call->local.state=VOMP_STATE_CALLENDED;
monitor_call_status(call);
break;
case (VOMP_STATE_CALLPREP<<3)|VOMP_STATE_NOCALL:
/* We are getting ready to ring, and the other end has issued a session
@ -853,6 +868,7 @@ int vomp_mdp_received(overlay_mdp_frame *mdp)
far end. But we don't start ringing until the far end acknowledges
the state change. */
call->local.state=VOMP_STATE_RINGINGOUT;
monitor_call_status(call);
vomp_extract_remote_codec_list(call,mdp);
break;
case (VOMP_STATE_CALLPREP<<3)|VOMP_STATE_CALLPREP:
@ -861,6 +877,7 @@ int vomp_mdp_received(overlay_mdp_frame *mdp)
let's not prevent it. We move to RINGINGOUT (as they probably will
as well). */
call->local.state=VOMP_STATE_RINGINGOUT;
monitor_call_status(call);
vomp_extract_remote_codec_list(call,mdp);
break;
case (VOMP_STATE_CALLPREP<<3)|VOMP_STATE_RINGINGOUT:
@ -868,6 +885,7 @@ int vomp_mdp_received(overlay_mdp_frame *mdp)
this seems a very unlikely situation. But the appropriate action is
clear: get ready to start ringing. */
call->local.state=VOMP_STATE_RINGINGIN;
monitor_call_status(call);
vomp_extract_remote_codec_list(call,mdp);
break;
case (VOMP_STATE_CALLPREP<<3)|VOMP_STATE_RINGINGIN:
@ -875,6 +893,7 @@ int vomp_mdp_received(overlay_mdp_frame *mdp)
They seem to have guessed our next move, which is fine. We move to
RINGINGOUT. */
call->local.state=VOMP_STATE_RINGINGOUT;
monitor_call_status(call);
vomp_extract_remote_codec_list(call,mdp);
break;
case (VOMP_STATE_CALLPREP<<3)|VOMP_STATE_INCALL:
@ -884,16 +903,19 @@ int vomp_mdp_received(overlay_mdp_frame *mdp)
can switch to engaged tone by sending a single VOMP_CODEC_ENGAGED
audio frame. Call-waiting not currently supported. */
call->local.state=VOMP_STATE_INCALL;
monitor_call_status(call);
if (vomp_call_start_audio(call)) call->local.codec=VOMP_CODEC_ENGAGED;
break;
case (VOMP_STATE_CALLPREP<<3)|VOMP_STATE_CALLENDED:
/* far end says no call */
call->local.state=VOMP_STATE_CALLENDED;
monitor_call_status(call);
break;
case (VOMP_STATE_RINGINGOUT<<3)|VOMP_STATE_NOCALL:
/* We are calling them, and they have not yet answered, wait for
synchronisation. */
call->local.state=VOMP_STATE_RINGINGOUT;
monitor_call_status(call);
vomp_extract_remote_codec_list(call,mdp);
break;
case (VOMP_STATE_RINGINGOUT<<3)|VOMP_STATE_CALLPREP:
@ -905,6 +927,7 @@ int vomp_mdp_received(overlay_mdp_frame *mdp)
/* we are each calling each other, so move to INCALL and start audio */
vomp_extract_remote_codec_list(call,mdp);
call->local.state=VOMP_STATE_INCALL;
monitor_call_status(call);
if (vomp_call_start_audio(call)) call->local.codec=VOMP_CODEC_ENGAGED;
break;
case (VOMP_STATE_RINGINGOUT<<3)|VOMP_STATE_RINGINGIN:
@ -917,6 +940,7 @@ int vomp_mdp_received(overlay_mdp_frame *mdp)
/* we are calling them, and they have entered the call, so we should enter
the call as well. */
call->local.state=VOMP_STATE_INCALL;
monitor_call_status(call);
call->ringing=0;
if (vomp_call_start_audio(call)) call->local.codec=VOMP_CODEC_ENGAGED;
break;
@ -924,10 +948,12 @@ int vomp_mdp_received(overlay_mdp_frame *mdp)
/* Other end has rejected call */
vomp_call_rejected(call);
call->local.state=VOMP_STATE_CALLENDED;
monitor_call_status(call);
break;
case (VOMP_STATE_RINGINGIN<<3)|VOMP_STATE_NOCALL:
/* we are ringing and they think there is no call, so move to CALLENDED */
call->local.state=VOMP_STATE_CALLENDED;
monitor_call_status(call);
vomp_call_error(call);
break;
case (VOMP_STATE_RINGINGIN<<3)|VOMP_STATE_CALLPREP:
@ -935,6 +961,7 @@ int vomp_mdp_received(overlay_mdp_frame *mdp)
ringing us. I guess we should stop ringing. Should we also abort the
call? */
call->local.state=VOMP_STATE_CALLENDED;
monitor_call_status(call);
vomp_call_error(call);
break;
case (VOMP_STATE_RINGINGIN<<3)|VOMP_STATE_RINGINGOUT:
@ -945,6 +972,7 @@ int vomp_mdp_received(overlay_mdp_frame *mdp)
case (VOMP_STATE_RINGINGIN<<3)|VOMP_STATE_RINGINGIN:
/* er, we both think that the other is calling us. */
call->local.state=VOMP_STATE_CALLENDED;
monitor_call_status(call);
vomp_call_error(call);
break;
case (VOMP_STATE_RINGINGIN<<3)|VOMP_STATE_INCALL:
@ -956,15 +984,18 @@ int vomp_mdp_received(overlay_mdp_frame *mdp)
/* the far end has rejected our attempt to call them */
vomp_call_rejected(call);
call->local.state=VOMP_STATE_CALLENDED;
monitor_call_status(call);
break;
case (VOMP_STATE_INCALL<<3)|VOMP_STATE_NOCALL:
/* this shouldn't happen */
call->local.state=VOMP_STATE_CALLENDED;
monitor_call_status(call);
vomp_call_error(call);
break;
case (VOMP_STATE_INCALL<<3)|VOMP_STATE_CALLPREP:
/* this shouldn't happen either */
call->local.state=VOMP_STATE_CALLENDED;
monitor_call_status(call);
vomp_call_error(call);
break;
case (VOMP_STATE_INCALL<<3)|VOMP_STATE_RINGINGOUT:
@ -983,6 +1014,7 @@ int vomp_mdp_received(overlay_mdp_frame *mdp)
/* far end hung up */
vomp_call_stop_audio(call);
call->local.state=VOMP_STATE_CALLENDED;
monitor_call_status(call);
break;
case (VOMP_STATE_CALLENDED<<3)|VOMP_STATE_NOCALL:
case (VOMP_STATE_CALLENDED<<3)|VOMP_STATE_CALLPREP:
@ -1452,6 +1484,7 @@ int vomp_tick()
Keep call structure hanging around for a bit so that we can
synchonrise with the far end if possible. */
vomp_call_states[i].local.state=VOMP_STATE_CALLENDED;
monitor_call_status(&vomp_call_states[i]);
vomp_send_status(&vomp_call_states[i],
VOMP_TELLREMOTE|VOMP_TELLINTERESTED,NULL);
vomp_call_states[i].last_activity=now;