diff options
author | jeremy <jeremy@f38db490-d61c-443f-a65b-d21fe96a405b> | 2004-09-30 19:36:46 +0000 |
---|---|---|
committer | jeremy <jeremy@f38db490-d61c-443f-a65b-d21fe96a405b> | 2004-09-30 19:36:46 +0000 |
commit | 22fbb4317672229e85cc3fa76fd6220627844144 (patch) | |
tree | a83dd5f5e35de64b74690e550fdd5ad6ee160b64 /channels | |
parent | 93da1760096bb6939cddf555467a628e4d7fed52 (diff) |
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
Diffstat (limited to 'channels')
-rwxr-xr-x | channels/chan_h323.c | 260 |
1 files changed, 149 insertions, 111 deletions
diff --git a/channels/chan_h323.c b/channels/chan_h323.c index c64a6e254..351ea4cc0 100755 --- a/channels/chan_h323.c +++ b/channels/chan_h323.c @@ -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 struct ast_channel *oh323_request(char *type, int format, void *data) +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); + if (create_addr(p, host) { + oh323_destroy(p); + return NULL; + } + ast_mutex_lock(&p->lock); tmpc = oh323_new(p, AST_STATE_DOWN, host); - if (!tmpc) + 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")) { |