mirror of
https://github.com/servalproject/serval-dna.git
synced 2025-04-13 22:03:09 +00:00
fixed various bugs with priorty dispatch of voice traffic.
some debug tweaking etc.
This commit is contained in:
parent
602c00efd7
commit
7b520e7a49
11
monitor.c
11
monitor.c
@ -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,
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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).
|
||||
|
@ -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");
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
1
serval.h
1
serval.h
@ -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
35
vomp.c
@ -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;
|
||||
|
Loading…
x
Reference in New Issue
Block a user