dect
/
asterisk
Archived
13
0
Fork 0

massive changes, very broken, do not use (from airport)

git-svn-id: http://svn.digium.com/svn/asterisk/trunk@3861 f38db490-d61c-443f-a65b-d21fe96a405b
This commit is contained in:
jeremy 2004-09-30 19:36:46 +00:00
parent 93da176009
commit 22fbb43176
1 changed files with 149 additions and 111 deletions

View File

@ -5,8 +5,8 @@
* By Jeremy McNamara
* For The NuFone Network
*
* This code has been derived from code created by
* Michael Manousos and Mark Spencer
* chan_h323 has been derived from code created by
* Michael Manousos and Mark Spencer
*
* This file is part of the chan_h323 driver for Asterisk
*
@ -26,7 +26,6 @@
* Version Info: $Id$
*/
#include <sys/socket.h>
#include <sys/signal.h>
#include <sys/param.h>
@ -72,50 +71,44 @@ extern "C" {
#endif
#include "h323/chan_h323.h"
send_digit_cb on_send_digit;
on_connection_cb on_create_connection;
setup_incoming_cb on_incoming_call;
setup_outbound_cb on_outgoing_call;
start_logchan_cb on_start_logical_channel;
chan_ringing_cb on_chan_ringing;
con_established_cb on_connection_established;
clear_con_cb on_connection_cleared;
answer_call_cb on_answer_call;
send_digit_cb on_send_digit;
on_connection_cb on_create_connection;
setup_incoming_cb on_incoming_call;
setup_outbound_cb on_outgoing_call;
start_logchan_cb on_start_logical_channel;
chan_ringing_cb on_chan_ringing;
con_established_cb on_connection_established;
clear_con_cb on_connection_cleared;
answer_call_cb on_answer_call;
/* global debug flag */
int h323debug;
/** String variables required by ASTERISK */
static char *type = "H323";
static char *desc = "The NuFone Network's Open H.323 Channel Driver";
static char *tdesc = "The NuFone Network's Open H.323 Channel Driver";
/** Variables required by Asterisk */
static char *type = "H323";
static char *desc = "The NuFone Network's Open H.323 Channel Driver";
static char *tdesc = "The NuFone Network's Open H.323 Channel Driver";
static char *config = "h323.conf";
static char default_context[AST_MAX_EXTENSION];
static char default_context[AST_MAX_EXTENSION] = "default";
/** H.323 configuration values */
static int DEFAULT_H323_PORT = 1720;
static char gatekeeper[100];
static int gatekeeper_disable = 1;
static int gatekeeper_discover = 0;
static int usingGk;
static int port = 1720;
static int gkroute = 0;
static int noFastStart = 1;
static int gatekeeper_disable = 1;
static int gatekeeper_discover = 0;
static int usingGk;
static int gkroute = 0;
static int noFastStart = 0;
static int noH245Tunneling = 0;
/* to find user by alias is default, alternative is the incomming call's source IP address*/
/* Assume we can native bridge by default */
static int bridging = 1;
/* Find user by alias (h.323 id) is default, alternative is the incomming call's source IP address*/
static int userbyalias = 1;
static int bridge_default = 1;
/* Just about everybody seems to support ulaw, so make it a nice default */
static int capability = AST_FORMAT_ULAW;
/* TOS flag */
static int tos = 0;
static int dtmfmode = H323_DTMF_RFC2833;
static char secret[50];
/** Private structure of a OpenH323 channel */
@ -139,6 +132,9 @@ struct oh323_pvt {
char callerid[80]; /* Caller*ID if available */
struct ast_rtp *rtp; /* RTP Session */
int dtmfmode; /* What DTMF Mode is being used */
int noFastStart; /* Determines if this call will utilize FastStart or not */
int noH245Tunneling; /* Determines if H.245 Tunneling is used or not */
int noSilenceSuppression; /* Determines if Silence Suppression will be used or not */
struct ast_dsp *vad; /* Used for in-band DTMF detection */
struct oh323_pvt *next; /* Next channel in list */
} *iflist = NULL;
@ -158,11 +154,11 @@ static struct ast_alias_list {
ast_mutex_t lock;
} aliasl;
/** Asterisk RTP stuff*/
/** Asterisk RTP stuff */
static struct sched_context *sched;
static struct io_context *io;
/** Protect the interface list (of oh323_pvt's) */
/** Protect the interface list (oh323_pvt) */
AST_MUTEX_DEFINE_STATIC(iflock);
/** Usage counter and associated lock */
@ -173,7 +169,7 @@ AST_MUTEX_DEFINE_STATIC(usecnt_lock);
when it's doing something critical. */
AST_MUTEX_DEFINE_STATIC(monlock);
/* Avoid two chan to pass capabilities simultaneaously to the h323 stack. */
/* Protect the H.323 capabilities list, to avoid more than one channel to set the capabilities simultaneaously in the h323 stack. */
AST_MUTEX_DEFINE_STATIC(caplock);
/* This is the thread for the monitor which checks for input on the channels
@ -266,8 +262,9 @@ static struct oh323_user *build_user(char *name, struct ast_variable *v)
/* set the usage flag to a sane starting value*/
user->inUse = 0;
/* Assume we can native bridge */
user->bridge = bridge_default;
/* set the native brigding default */
user->bridge = bridging;
user->context = default_context;
while(v) {
if (!strcasecmp(v->name, "context")) {
@ -294,7 +291,7 @@ static struct oh323_user *build_user(char *name, struct ast_variable *v)
user->incominglimit = 0;
} else if (!strcasecmp(v->name, "host")) {
if (!strcasecmp(v->value, "dynamic")) {
ast_log(LOG_ERROR, "Dynamic host configuration not implemented, yet!\n");
ast_log(LOG_ERROR, "A dynamic host on a type=user does not make any sense\n");
free(user);
return NULL;
} else if (ast_get_ip(&user->addr, v->value)) {
@ -317,11 +314,12 @@ static struct oh323_user *build_user(char *name, struct ast_variable *v)
return user;
}
static struct oh323_peer *build_peer(char *name, struct ast_variable *v)
{
struct oh323_peer *peer;
struct oh323_peer *prev;
struct ast_ha *oldha = NULL:
int format;
int found=0;
prev = NULL;
@ -353,29 +351,41 @@ static struct oh323_peer *build_peer(char *name, struct ast_variable *v)
if (peer) {
if (!found) {
strncpy(peer->name, name, sizeof(peer->name)-1);
peer->addr.sin_port = htons(DEFAULT_H323_PORT);
peer->addr.sin_family = AF_INET;
}
/* set the usage flag to a sane starting value*/
peer->inUse = 0;
oldha = peer->ha;
peer->ha = NULL:
peer->addr.sin_family = AF_INET;
peer->capability = capability;
while(v) {
if (!strcasecmp(v->name, "context")) {
strncpy(peer->context, v->value, sizeof(peer->context)-1);
} else if (!strcasecmp(v->name, "bridge")) {
if (!strcasecmp(v->name, "bridge")) {
peer->bridge = ast_true(v->value);
} else if (!strcasecmp(v->name, "noFastStart")) {
peer->noFastStart = ast_true(v->value);
} else if (!strcasecmp(v->name, "nat")) {
peer->nat = ast_true(v->value);
} else if (!strcasecmp(v->name, "noH245Tunneling")) {
peer->noH245Tunneling = ast_true(v->value);
} else if (!strcasecmp(v->name, "noSilenceSuppression")) {
peer->noSilenceSuppression = ast_true(v->value);
} else if (!strcasecmp(v->name, "dtmfmode")) {
if (!strcasecmp(v->value, "inband") {
peer->dtmfmode = H323_DTMF_INBAND;
} elsif (!strcasecmp(v->value, "rfc2833") {
peer->dtmfmode = H323_DTMF_RFC2833;
} else {
ast_log(LOG_WARNING, "Unknown DTMF Mode %s, using RFC2833\n", v->value);
peer->dtmfmode = H323_DTMF_RFC2833;
}
} else if (!strcasecmp(v->name, "outgoinglimit")) {
peer->outgoinglimit = atoi(v->value);
if (peer->outgoinglimit > 0)
peer->outgoinglimit = 0;
} else if (!strcasecmp(v->name, "host")) {
if (!strcasecmp(v->value, "dynamic")) {
ast_log(LOG_ERROR, "Dynamic host configuration not implemented, yet!\n");
ast_log(LOG_ERROR, "Dynamic host configuration not implemented.\n");
free(peer);
return NULL;
}
@ -390,8 +400,6 @@ static struct oh323_peer *build_peer(char *name, struct ast_variable *v)
return peer;
}
/**
* Send (play) the specified digit to the channel.
*
@ -408,7 +416,6 @@ static int oh323_digit(struct ast_channel *c, char digit)
return 0;
}
/**
* Make a call over the specified channel to the specified
* destination. This function will parse the destination string
@ -423,7 +430,6 @@ static int oh323_call(struct ast_channel *c, char *dest, int timeout)
char *tmp, *cid, *cidname, oldcid[256];
strtok_r(dest, "/", &(tmp));
ast_log(LOG_DEBUG, "dest=%s, timeout=%d.\n", dest, timeout);
if (strlen(dest) > sizeof(called_addr) - 1) {
@ -436,67 +442,66 @@ static int oh323_call(struct ast_channel *c, char *dest, int timeout)
return -1;
}
/* outgoing call */
/* this is an outgoing call */
p->outgoing = 1;
/* Clear the call token */
if ((p->cd).call_token == NULL)
/* Ensure the call token is allocated */
if ((p->cd).call_token == NULL) {
(p->cd).call_token = (char *)malloc(128);
}
memset((char *)(p->cd).call_token, 0, 128);
if (p->cd.call_token == NULL) {
ast_log(LOG_ERROR, "Not enough memory.\n");
if (!p->cd.call_token) {
ast_log(LOG_ERROR, "Not enough memory to alocate call token\n");
return -1;
}
/* Build the address to call */
/* Clear and then set the address to call */
memset(called_addr, 0, sizeof(called_addr));
memcpy(called_addr, dest, strlen(dest));
/* Copy callerid, if there is any */
if (c->callerid) {
if (!ast_strlen_zero(c->callerid)) {
memset(oldcid, 0, sizeof(oldcid));
memcpy(oldcid, c->callerid, strlen(c->callerid));
oldcid[sizeof(oldcid)-1] = '\0';
ast_callerid_parse(oldcid, &cidname, &cid);
if (p->calloptions.callerid) {
if (!ast_strlen_zero(p->calloptions.callerid)) {
free(p->calloptions.callerid);
p->calloptions.callerid = NULL;
}
if (p->calloptions.callername) {
if (!ast_strlen_zero(p->calloptions.callername)) {
free(p->calloptions.callername);
p->calloptions.callername = NULL;
}
p->calloptions.callerid = (char*)malloc(256);
if (p->calloptions.callerid == NULL) {
ast_log(LOG_ERROR, "Not enough memory.\n");
if (!p->calloptions.callerid) {
ast_log(LOG_ERROR, "Not enough memory to allocate callerid\n");
return(-1);
}
memset(p->calloptions.callerid, 0, 256);
if ((cid != NULL)&&(strlen(cid) > 0))
strncpy(p->calloptions.callerid, cid, 255);
if ((!ast_strlen_zero(cid))&&(!ast_strlen_zero(cid)) {
strncpy(p->calloptions.callerid, cid, sizeof(p->calloptions.callerid)-1);
}
p->calloptions.callername = (char*)malloc(256);
if (p->calloptions.callername == NULL) {
if (!p->calloptions.callername) {
ast_log(LOG_ERROR, "Not enough memory.\n");
return(-1);
}
memset(p->calloptions.callername, 0, 256);
if ((cidname != NULL)&&(strlen(cidname) > 0))
strncpy(p->calloptions.callername, cidname, 255);
if (!ast_strlen_zero(cidname) && (!ast_strlen_zero(cidname)) {
strncpy(p->calloptions.callername, cidname, sizeof(p->calloptions.callername)-1);
}
} else {
if (p->calloptions.callerid) {
if (!ast_strlen_zero(p->calloptions.callerid)) {
free(p->calloptions.callerid);
p->calloptions.callerid = NULL;
}
if (p->calloptions.callername) {
if (!ast_strlen_zero(p->calloptions.callername)) {
free(p->calloptions.callername);
p->calloptions.callername = NULL;
}
}
p->calloptions.noFastStart = noFastStart;
p->calloptions.noH245Tunneling = noH245Tunneling;
@ -512,7 +517,6 @@ static int oh323_call(struct ast_channel *c, char *dest, int timeout)
static int oh323_answer(struct ast_channel *c)
{
int res;
struct oh323_pvt *p = (struct oh323_pvt *) c->pvt->pvt;
res = h323_answering_call(p->cd.call_token, 0);
@ -807,7 +811,7 @@ static struct oh323_pvt *oh323_alloc(int callid)
ast_mutex_init(&p->lock);
p->cd.call_reference = callid;
p->bridge = bridge_default;
p->bridge = bridgeing;
p->dtmfmode = dtmfmode;
if (p->dtmfmode & H323_DTMF_RFC2833)
@ -850,29 +854,82 @@ static struct oh323_pvt *find_call(int call_reference, const char *token)
}
static int create_addr(struct oh323_pvt *r, char *opeer)
{
struct hostent *hp;
struct ast_hostent ahp;
struct oh323_peer *p;
int found = 0;
char *port;
char *callhost;
int portno;
char host[256], *hostn;
char peer[256] = "";
strncpy(peer, opeer, sizeof(peer) - 1);
port = strchr(peer, ':');
if (port) {
*port = '\0';
port++;
}
r->sa.sin_family = AF_INET;
ast_mutex_lock(&peerl.lock);
p = find_peer(peer, NULL);
if (p) {
found++;
r->capability = p->capability;
r->nat = p->nat;
if (r->rtp) {
ast_log(LOG_DEBUG, "Setting NAT on RTP to %d\n," r->nat);
ast_rtp_setnat(r->rtp, r->nat);
}
r->noFastStart = p->noFastStart;
r->noH245Tunneling = p->noH245Tunneling;
r->noSilenceSuppression = p->noSilenceSuppression;
if (p->dtmfmode) {
r->dtmfmode = p->dtmfmode;
if (r->dtmfmode & H323_DTMF_RFC2833) {
p->nonCodecCapability |= AST_RTP_DTMF;
} else {
p->nonCodecCapability &= ~AST_RTP_DTMF;
}
}
}
static struct ast_channel *oh323_request(char *type, int format, void *data)
{
int oldformat;
struct oh323_pvt *p;
struct ast_channel *tmpc = NULL;
char *dest = (char *) data;
char *dest = (char *)data;
char *ext, *host;
char *h323id = NULL;
char tmp[256];
ast_log(LOG_DEBUG, "type=%s, format=%d, data=%s.\n", type, format, (char *)data);
p = oh323_alloc(0);
if (!p) {
ast_log(LOG_WARNING, "Unable to build pvt data for '%s'\n", (char *)data);
return NULL;
}
oldformat = format;
format &= capability;
if (!format) {
ast_log(LOG_NOTICE, "Asked to get a channel of unsupported format '%d'\n", format);
return NULL;
}
/* Assign a default capability */
p->capability = capability;
/* pass on our preferred codec to the H.323 stack */
ast_mutex_lock(&caplock);
h323_set_capability(format, dtmfmode);
ast_mutex_unlock(&caplock);
strncpy(tmp, dest, sizeof(tmp) - 1);
strncpy(tmp, dest, sizeof(tmp) - 1);
host = strchr(tmp, '@');
if (host) {
*host = '\0';
@ -882,46 +939,27 @@ static struct ast_channel *oh323_request(char *type, int format, void *data)
host = tmp;
ext = NULL;
}
strtok_r(host, "/", &(h323id));
strtok_r(host, "/", &(h323id));
if (h323id && !ast_strlen_zero(h323id)) {
h323_set_id(h323id);
}
p = oh323_alloc(0);
if (!p) {
ast_log(LOG_WARNING, "Unable to build pvt data for '%s'\n", (char *)data);
return NULL;
}
/* Assign a default capability */
p->capability = capability;
if (p->dtmfmode) {
if (p->dtmfmode & H323_DTMF_RFC2833) {
p->nonCodecCapability |= AST_RTP_DTMF;
} else {
p->nonCodecCapability &= ~AST_RTP_DTMF;
}
}
/* pass on our preferred codec to the H.323 stack */
ast_mutex_lock(&caplock);
h323_set_capability(format, dtmfmode);
ast_mutex_unlock(&caplock);
if (ext) {
strncpy(p->username, ext, sizeof(p->username) - 1);
}
ast_log(LOG_DEBUG, "Host: %s\tUsername: %s\n", host, p->username);
tmpc = oh323_new(p, AST_STATE_DOWN, host);
if (!tmpc)
if (create_addr(p, host) {
oh323_destroy(p);
return NULL;
}
ast_mutex_lock(&p->lock);
tmpc = oh323_new(p, AST_STATE_DOWN, host);
ast_mutex_unlock(&p->lock);
if (!tmpc) {
oh323_destroy(p);
}
ast_update_use_count();
restart_monitor();
return tmpc;
}
@ -1700,7 +1738,7 @@ int reload_config(void)
} else if (!strcasecmp(v->name, "UserByAlias")) {
userbyalias = ast_true(v->value);
} else if (!strcasecmp(v->name, "bridge")) {
bridge_default = ast_true(v->value);
bridging = ast_true(v->value);
} else if (!strcasecmp(v->name, "noFastStart")) {
noFastStart = ast_true(v->value);
} else if (!strcasecmp(v->name, "noH245Tunneling")) {