Further work on getting VoMP together. Added MDP messages to add

and remove a client from being interested in the phone-call state.
This commit is contained in:
gardners 2012-04-19 21:53:40 +09:30
parent a29a1283f7
commit b1a7ccd32f
2 changed files with 114 additions and 2 deletions

View File

@ -1081,6 +1081,12 @@ int create_serval_instance_dir();
int overlay_mdp_get_fds(struct pollfd *fds,int *fdcount,int fdmax);
int overlay_mdp_poll();
int overlay_mdp_reply_error(int sock,
struct sockaddr_un *recvaddr,int recvaddrlen,
int error_number,char *message);
extern int mdp_abstract_socket;
extern int mdp_named_socket;
typedef struct sockaddr_mdp {
unsigned char sid[SID_SIZE];
@ -1140,10 +1146,13 @@ typedef struct overlay_mdp_vompevent {
#define VOMPEVENT_RINGING (1<<0)
#define VOMPEVENT_CALLENDED (1<<1)
#define VOMPEVENT_CALLREJECT (1<<2)
#define VOMPEVENT_HANGUP VOMPEVENT_CALLREJECT
#define VOMPEVENT_TIMEOUT (1<<3)
#define VOMPEVENT_ERROR (1<<4)
#define VOMPEVENT_AUDIOSTREAMING (1<<5)
#define VOMPEVENT_DIAL (1<<6)
#define VOMPEVENT_REGISTERINTEREST (1<<7)
#define VOMPEVENT_WITHDRAWINTEREST (1<<8)
unsigned int flags;
unsigned short audio_sample_bytes;
unsigned char local_state;
@ -1231,8 +1240,9 @@ typedef struct vomp_call_state {
#define VOMP_CODEC_CODEC2_2400 0x01
#define VOMP_CODEC_CODEC2_1400 0x02
#define VOMP_CODEC_GSM 0x03
#define VOMP_CODEC_DTMF 0x04
#define VOMP_CODEC_ENGAGED 0x05
#define VOMP_CODEC_DTMF 0x80
#define VOMP_CODEC_ENGAGED 0x81
#define VOMP_CODEC_CALLERID 0x82
#define VOMP_CODEC_CODECSISUPPORT 0xfe
#define VOMP_CODEC_CHANGEYOURCODECTO 0xff

102
vomp.c
View File

@ -33,6 +33,13 @@ int vomp_call_count=0;
#define VOMP_MAX_CALLS 16
vomp_call_state vomp_call_states[VOMP_MAX_CALLS];
/* Now keep track of who wants to know what we are up to */
int vomp_interested_usock_count=0;
#define VOMP_MAX_INTERESTED 128
struct sockaddr_un *vomp_interested_usocks[VOMP_MAX_INTERESTED];
int vomp_interested_usock_lengths[VOMP_MAX_INTERESTED];
unsigned long long vomp_interested_expiries[VOMP_MAX_INTERESTED];
vomp_call_state *vomp_find_or_create_call(unsigned char *remote_sid,
unsigned char *local_sid,
unsigned int sender_session,
@ -157,6 +164,101 @@ int vomp_call_destroy(vomp_call_state *call)
int vomp_mdp_event(overlay_mdp_frame *mdp,
struct sockaddr_un *recvaddr,int recvaddrlen)
{
/* Frames from the user can take only a few forms:
- announce interest in call state.
- withdraw interest in call state.
- place a call (SID+DID combination)
- deliver audio for sending
- indicate pickup, hangup or call reject
We then send back all sorts of relevant call state information as well as
transported audio. In particular we inform when the call state changes,
including if any error has occurred.
*/
switch(mdp->vompevent.flags)
{
case VOMPEVENT_REGISTERINTEREST:
/* put unix domain socket on record to send call state event and audio to. */
{
int i;
int candidate=-1;
long long now=overlay_gettime_ms();
for(i=0;i<vomp_interested_usock_count;i++)
{
if (vomp_interested_usock_lengths[i]==recvaddrlen)
if (!memcmp(recvaddr->sun_path,
vomp_interested_usocks[i],recvaddrlen))
/* found it -- so we are already monitoring this one */
return overlay_mdp_reply_error(mdp_named_socket,recvaddr,recvaddrlen,
0,"Success");
if (vomp_interested_expiries[i]<now) candidate=i;
}
if (i>=vomp_interested_usock_count&&(candidate>-1)) i=candidate;
/* not currently on the list, so add */
if (i<VOMP_MAX_INTERESTED) {
if (vomp_interested_usocks[i]) {
free(vomp_interested_usocks[i]);
vomp_interested_usocks[i]=NULL;
}
vomp_interested_usocks[i]=malloc(recvaddrlen);
if (!vomp_interested_usocks[i])
return overlay_mdp_reply_error(mdp_named_socket, recvaddr,recvaddrlen,
4002,"Out of memory");
bcopy(recvaddr,vomp_interested_usocks[i],
recvaddrlen);
vomp_interested_usock_lengths[i]=recvaddrlen;
vomp_interested_expiries[i]=overlay_gettime_ms()+60000;
if (i==vomp_interested_usock_count) vomp_interested_usock_count++;
} else {
return overlay_mdp_reply_error
(mdp_named_socket,recvaddr,recvaddrlen,
4003,"Too many listeners (try again in a minute?)");
}
}
break;
case VOMPEVENT_WITHDRAWINTEREST:
/* opposite of above */
{
int i;
for(i=0;i<vomp_interested_usock_count;i++)
{
if (vomp_interested_usock_lengths[i]==recvaddrlen)
if (!memcmp(recvaddr->sun_path,
vomp_interested_usocks[i],recvaddrlen))
{
/* found it -- so we are already monitoring this one */
free(vomp_interested_usocks[i]);
if (i<vomp_interested_usock_count-1)
{
int swap=vomp_interested_usock_count-1;
vomp_interested_usock_lengths[i]
=vomp_interested_usock_lengths[swap];
vomp_interested_usocks[i]=vomp_interested_usocks[swap];
vomp_interested_expiries[i]=vomp_interested_expiries[swap];
}
vomp_interested_usock_count--;
return overlay_mdp_reply_error
(mdp_named_socket,recvaddr,recvaddrlen,
0,"Success. You have been removed.");
}
}
return overlay_mdp_reply_error
(mdp_named_socket,recvaddr,recvaddrlen,
0,"Success. You were never listening.");
}
break;
case VOMPEVENT_DIAL:
/* audio bytes is actually local DID:remote DID tuple. */
case VOMPEVENT_CALLREJECT: /* hangup is the same */
case VOMPEVENT_AUDIOSTREAMING: /* user supplying audio */
default:
/* didn't understand it, so respond with an error */
return overlay_mdp_reply_error(mdp_named_socket,
recvaddr,recvaddrlen,4001,
"Invalid VOMPEVENT request (use DIAL,HANGUP,CALLREJECT,AUDIOSTREAMING,REGISTERINTERST,WITHDRAWINTERST only)");
}
return WHY("Not implemented");
}