mirror of
https://github.com/asterisk/asterisk.git
synced 2025-10-14 08:31:02 +00:00
Merged revisions 291192 via svnmerge from
https://origsvn.digium.com/svn/asterisk/branches/1.8 ........ r291192 | dvossel | 2010-10-11 16:38:39 -0500 (Mon, 11 Oct 2010) | 19 lines Gtalk enhancements and general code cleanup. This patch includes several chan_gtalk enhancements. Two new gtalk.conf options have been added, externip and stunadd. Setting externip allows us to manually specify what the external IP address is outside of a NAT environment. Setting the stunaddr option to a valid stun server allows for that external ip to be retrieved via a STUN server automatically. This external IP is then advertised during call setup as a possible candidate. I have also attempted to clean up chan_gtalk's code so it meets our coding guidelines. During this cleanup I noticed several things that need to be done in the code and made a TODO section at the top of the file. ........ git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@291193 65c4cc65-6c06-0410-ace0-fbb531ad65f3
This commit is contained in:
@@ -25,6 +25,10 @@
|
|||||||
* \brief Gtalk Channel Driver, until google/libjingle works with jingle spec
|
* \brief Gtalk Channel Driver, until google/libjingle works with jingle spec
|
||||||
*
|
*
|
||||||
* \ingroup channel_drivers
|
* \ingroup channel_drivers
|
||||||
|
*
|
||||||
|
* ********** General TODO:s
|
||||||
|
* \todo Support config reloading.
|
||||||
|
* \todo Fix native bridging.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*** MODULEINFO
|
/*** MODULEINFO
|
||||||
@@ -33,6 +37,7 @@
|
|||||||
<use>openssl</use>
|
<use>openssl</use>
|
||||||
***/
|
***/
|
||||||
|
|
||||||
|
|
||||||
#include "asterisk.h"
|
#include "asterisk.h"
|
||||||
|
|
||||||
ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
|
ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
|
||||||
@@ -193,8 +198,10 @@ static int gtalk_indicate(struct ast_channel *ast, int condition, const void *da
|
|||||||
static int gtalk_fixup(struct ast_channel *oldchan, struct ast_channel *newchan);
|
static int gtalk_fixup(struct ast_channel *oldchan, struct ast_channel *newchan);
|
||||||
static int gtalk_sendhtml(struct ast_channel *ast, int subclass, const char *data, int datalen);
|
static int gtalk_sendhtml(struct ast_channel *ast, int subclass, const char *data, int datalen);
|
||||||
static struct gtalk_pvt *gtalk_alloc(struct gtalk *client, const char *us, const char *them, const char *sid);
|
static struct gtalk_pvt *gtalk_alloc(struct gtalk *client, const char *us, const char *them, const char *sid);
|
||||||
static char *gtalk_do_reload(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a);
|
static int gtalk_update_stun(struct gtalk *client, struct gtalk_pvt *p);
|
||||||
|
/* static char *gtalk_do_reload(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a); */
|
||||||
static char *gtalk_show_channels(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a);
|
static char *gtalk_show_channels(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a);
|
||||||
|
static int gtalk_update_externip(void);
|
||||||
|
|
||||||
/*! \brief PBX interface structure for channel registration */
|
/*! \brief PBX interface structure for channel registration */
|
||||||
static const struct ast_channel_tech gtalk_tech = {
|
static const struct ast_channel_tech gtalk_tech = {
|
||||||
@@ -228,11 +235,12 @@ static struct io_context *io; /*!< The IO context */
|
|||||||
static struct in_addr __ourip;
|
static struct in_addr __ourip;
|
||||||
|
|
||||||
static struct ast_cli_entry gtalk_cli[] = {
|
static struct ast_cli_entry gtalk_cli[] = {
|
||||||
AST_CLI_DEFINE(gtalk_do_reload, "Reload GoogleTalk configuration"),
|
/* AST_CLI_DEFINE(gtalk_do_reload, "Reload GoogleTalk configuration"), XXX TODO reloads are not possible yet. */
|
||||||
AST_CLI_DEFINE(gtalk_show_channels, "Show GoogleTalk channels"),
|
AST_CLI_DEFINE(gtalk_show_channels, "Show GoogleTalk channels"),
|
||||||
};
|
};
|
||||||
|
|
||||||
static char externip[16];
|
static char externip[16];
|
||||||
|
static struct sockaddr_in stunaddr; /*!< the stun server we get the externip from */
|
||||||
|
|
||||||
static struct gtalk_container gtalk_list;
|
static struct gtalk_container gtalk_list;
|
||||||
|
|
||||||
@@ -631,7 +639,7 @@ static int gtalk_is_answered(struct gtalk *client, ikspak *pak)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (tmp == 0) {
|
if (!tmp) {
|
||||||
ast_log(LOG_WARNING, "Could not find session in iq\n");
|
ast_log(LOG_WARNING, "Could not find session in iq\n");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
@@ -662,14 +670,14 @@ static int gtalk_is_answered(struct gtalk *client, ikspak *pak)
|
|||||||
}
|
}
|
||||||
|
|
||||||
from = iks_find_attrib(pak->x, "to");
|
from = iks_find_attrib(pak->x, "to");
|
||||||
if(!from)
|
if (!from) {
|
||||||
from = client->connection->jid->full;
|
from = client->connection->jid->full;
|
||||||
|
}
|
||||||
|
|
||||||
if (tmp) {
|
if (tmp->owner) {
|
||||||
if (tmp->owner)
|
ast_queue_control(tmp->owner, AST_CONTROL_ANSWER);
|
||||||
ast_queue_control(tmp->owner, AST_CONTROL_ANSWER);
|
}
|
||||||
} else
|
gtalk_update_stun(tmp->parent, tmp);
|
||||||
ast_log(LOG_NOTICE, "Whoa, didn't find call!\n");
|
|
||||||
gtalk_response(client, from, pak, NULL, NULL);
|
gtalk_response(client, from, pak, NULL, NULL);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
@@ -682,16 +690,21 @@ static int gtalk_is_accepted(struct gtalk *client, ikspak *pak)
|
|||||||
ast_log(LOG_DEBUG, "The client is %s\n", client->name);
|
ast_log(LOG_DEBUG, "The client is %s\n", client->name);
|
||||||
/* find corresponding call */
|
/* find corresponding call */
|
||||||
for (tmp = client->p; tmp; tmp = tmp->next) {
|
for (tmp = client->p; tmp; tmp = tmp->next) {
|
||||||
if (iks_find_with_attrib(pak->x, "session", "id", tmp->sid))
|
if (iks_find_with_attrib(pak->x, "session", "id", tmp->sid)) {
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
from = iks_find_attrib(pak->x, "to");
|
from = iks_find_attrib(pak->x, "to");
|
||||||
if(!from)
|
if (!from) {
|
||||||
from = client->connection->jid->full;
|
from = client->connection->jid->full;
|
||||||
|
}
|
||||||
|
|
||||||
if (!tmp)
|
if (tmp) {
|
||||||
ast_log(LOG_NOTICE, "Whoa, didn't find call!\n");
|
gtalk_update_stun(tmp->parent, tmp);
|
||||||
|
} else {
|
||||||
|
ast_log(LOG_NOTICE, "Whoa, didn't find call during accept?!\n");
|
||||||
|
}
|
||||||
|
|
||||||
/* answer 'iq' packet to let the remote peer know that we're alive */
|
/* answer 'iq' packet to let the remote peer know that we're alive */
|
||||||
gtalk_response(client, from, pak, NULL, NULL);
|
gtalk_response(client, from, pak, NULL, NULL);
|
||||||
@@ -710,9 +723,9 @@ static int gtalk_handle_dtmf(struct gtalk *client, ikspak *pak)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
from = iks_find_attrib(pak->x, "to");
|
from = iks_find_attrib(pak->x, "to");
|
||||||
if(!from)
|
if (!from) {
|
||||||
from = client->connection->jid->full;
|
from = client->connection->jid->full;
|
||||||
|
}
|
||||||
|
|
||||||
if (tmp) {
|
if (tmp) {
|
||||||
if(iks_find_with_attrib(pak->x, "dtmf-method", "method", "rtp")) {
|
if(iks_find_with_attrib(pak->x, "dtmf-method", "method", "rtp")) {
|
||||||
@@ -759,8 +772,9 @@ static int gtalk_handle_dtmf(struct gtalk *client, ikspak *pak)
|
|||||||
}
|
}
|
||||||
gtalk_response(client, from, pak, NULL, NULL);
|
gtalk_response(client, from, pak, NULL, NULL);
|
||||||
return 1;
|
return 1;
|
||||||
} else
|
} else {
|
||||||
ast_log(LOG_NOTICE, "Whoa, didn't find call!\n");
|
ast_log(LOG_NOTICE, "Whoa, didn't find call!\n");
|
||||||
|
}
|
||||||
|
|
||||||
gtalk_response(client, from, pak, NULL, NULL);
|
gtalk_response(client, from, pak, NULL, NULL);
|
||||||
return 1;
|
return 1;
|
||||||
@@ -778,15 +792,18 @@ static int gtalk_hangup_farend(struct gtalk *client, ikspak *pak)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
from = iks_find_attrib(pak->x, "to");
|
from = iks_find_attrib(pak->x, "to");
|
||||||
if(!from)
|
if (!from) {
|
||||||
from = client->connection->jid->full;
|
from = client->connection->jid->full;
|
||||||
|
}
|
||||||
|
|
||||||
if (tmp) {
|
if (tmp) {
|
||||||
tmp->alreadygone = 1;
|
tmp->alreadygone = 1;
|
||||||
if (tmp->owner)
|
if (tmp->owner) {
|
||||||
ast_queue_hangup(tmp->owner);
|
ast_queue_hangup(tmp->owner);
|
||||||
} else
|
}
|
||||||
ast_log(LOG_NOTICE, "Whoa, didn't find call!\n");
|
} else {
|
||||||
|
ast_log(LOG_NOTICE, "Whoa, didn't find call during hangup!\n");
|
||||||
|
}
|
||||||
gtalk_response(client, from, pak, NULL, NULL);
|
gtalk_response(client, from, pak, NULL, NULL);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
@@ -799,13 +816,11 @@ static int gtalk_create_candidates(struct gtalk *client, struct gtalk_pvt *p, ch
|
|||||||
struct sockaddr_in sin = { 0, };
|
struct sockaddr_in sin = { 0, };
|
||||||
struct ast_sockaddr sin_tmp;
|
struct ast_sockaddr sin_tmp;
|
||||||
struct ast_sockaddr bindaddr_tmp;
|
struct ast_sockaddr bindaddr_tmp;
|
||||||
struct sockaddr_in dest;
|
|
||||||
struct ast_sockaddr us;
|
struct ast_sockaddr us;
|
||||||
iks *iq, *gtalk, *candidate, *transport;
|
iks *iq, *gtalk, *candidate, *transport;
|
||||||
char user[17], pass[17], preference[5], port[7];
|
char user[17], pass[17], preference[5], port[7];
|
||||||
char *lowerfrom = NULL;
|
char *lowerfrom = NULL;
|
||||||
|
|
||||||
|
|
||||||
iq = iks_new("iq");
|
iq = iks_new("iq");
|
||||||
gtalk = iks_new("session");
|
gtalk = iks_new("session");
|
||||||
candidate = iks_new("candidate");
|
candidate = iks_new("candidate");
|
||||||
@@ -821,12 +836,14 @@ static int gtalk_create_candidates(struct gtalk *client, struct gtalk_pvt *p, ch
|
|||||||
|
|
||||||
iks_insert_attrib(transport, "xmlns",GOOGLE_TRANSPORT_NS);
|
iks_insert_attrib(transport, "xmlns",GOOGLE_TRANSPORT_NS);
|
||||||
iks_insert_node(iq, gtalk);
|
iks_insert_node(iq, gtalk);
|
||||||
|
|
||||||
if (p->ctype == AJI_CLIENT_GMAIL) {
|
if (p->ctype == AJI_CLIENT_GMAIL) {
|
||||||
iks_insert_node(gtalk,candidate);
|
iks_insert_node(gtalk,candidate);
|
||||||
} else {
|
} else {
|
||||||
iks_insert_node(gtalk,transport);
|
iks_insert_node(gtalk,transport);
|
||||||
iks_insert_node(gtalk,candidate);
|
iks_insert_node(gtalk,candidate);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (; p; p = p->next) {
|
for (; p; p = p->next) {
|
||||||
if (!strcasecmp(p->sid, sid))
|
if (!strcasecmp(p->sid, sid))
|
||||||
break;
|
break;
|
||||||
@@ -860,10 +877,11 @@ static int gtalk_create_candidates(struct gtalk *client, struct gtalk_pvt *p, ch
|
|||||||
ours1->generation = 0;
|
ours1->generation = 0;
|
||||||
p->ourcandidates = ours1;
|
p->ourcandidates = ours1;
|
||||||
|
|
||||||
|
/* XXX this is a blocking action. We send a STUN request to the server
|
||||||
|
* and wait for the response. If blocking here is a problem the STUN requests/responses
|
||||||
|
* for the externip may need to be done differently. */
|
||||||
|
gtalk_update_externip();
|
||||||
if (!ast_strlen_zero(externip)) {
|
if (!ast_strlen_zero(externip)) {
|
||||||
/* XXX We should really stun for this one not just go with externip XXX */
|
|
||||||
snprintf(user, sizeof(user), "%08lx%08lx", ast_random(), ast_random());
|
|
||||||
snprintf(pass, sizeof(pass), "%08lx%08lx", ast_random(), ast_random());
|
|
||||||
ast_copy_string(ours2->username, user, sizeof(ours2->username));
|
ast_copy_string(ours2->username, user, sizeof(ours2->username));
|
||||||
ast_copy_string(ours2->password, pass, sizeof(ours2->password));
|
ast_copy_string(ours2->password, pass, sizeof(ours2->password));
|
||||||
ast_copy_string(ours2->ip, externip, sizeof(ours2->ip));
|
ast_copy_string(ours2->ip, externip, sizeof(ours2->ip));
|
||||||
@@ -877,9 +895,6 @@ static int gtalk_create_candidates(struct gtalk *client, struct gtalk_pvt *p, ch
|
|||||||
ours2 = NULL;
|
ours2 = NULL;
|
||||||
}
|
}
|
||||||
ours1 = NULL;
|
ours1 = NULL;
|
||||||
dest.sin_addr = __ourip;
|
|
||||||
dest.sin_port = sin.sin_port;
|
|
||||||
|
|
||||||
|
|
||||||
for (tmp = p->ourcandidates; tmp; tmp = tmp->next) {
|
for (tmp = p->ourcandidates; tmp; tmp = tmp->next) {
|
||||||
snprintf(port, sizeof(port), "%d", tmp->port);
|
snprintf(port, sizeof(port), "%d", tmp->port);
|
||||||
@@ -1227,7 +1242,7 @@ static int gtalk_newcall(struct gtalk *client, ikspak *pak)
|
|||||||
|
|
||||||
/* Make sure our new call doesn't exist yet */
|
/* Make sure our new call doesn't exist yet */
|
||||||
from = iks_find_attrib(pak->x,"to");
|
from = iks_find_attrib(pak->x,"to");
|
||||||
if(!from) {
|
if (!from) {
|
||||||
from = client->connection->jid->full;
|
from = client->connection->jid->full;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1333,6 +1348,45 @@ static int gtalk_newcall(struct gtalk *client, ikspak *pak)
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int gtalk_update_externip(void)
|
||||||
|
{
|
||||||
|
int sock;
|
||||||
|
char *newaddr;
|
||||||
|
struct sockaddr_in answer = { 0, };
|
||||||
|
struct sockaddr_in *dst;
|
||||||
|
struct ast_sockaddr tmp_dst;
|
||||||
|
|
||||||
|
if (!stunaddr.sin_addr.s_addr) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
dst = &stunaddr;
|
||||||
|
|
||||||
|
sock = socket(AF_INET, SOCK_DGRAM, 0);
|
||||||
|
if (sock < 0) {
|
||||||
|
ast_log(LOG_WARNING, "Unable to create STUN socket: %s\n", strerror(errno));
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
ast_sockaddr_from_sin(&tmp_dst, dst);
|
||||||
|
if (ast_connect(sock, &tmp_dst) != 0) {
|
||||||
|
ast_log(LOG_WARNING, "STUN Failed to connect to %s\n", ast_sockaddr_stringify(&tmp_dst));
|
||||||
|
close(sock);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((ast_stun_request(sock, &stunaddr, NULL, &answer))) {
|
||||||
|
close(sock);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
newaddr = ast_strdupa(ast_inet_ntoa(answer.sin_addr));
|
||||||
|
memcpy(externip, newaddr, sizeof(externip));
|
||||||
|
|
||||||
|
close(sock);
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
static int gtalk_update_stun(struct gtalk *client, struct gtalk_pvt *p)
|
static int gtalk_update_stun(struct gtalk *client, struct gtalk_pvt *p)
|
||||||
{
|
{
|
||||||
struct gtalk_candidate *tmp;
|
struct gtalk_candidate *tmp;
|
||||||
@@ -1363,8 +1417,8 @@ static int gtalk_update_stun(struct gtalk *client, struct gtalk_pvt *p)
|
|||||||
ast_sockaddr_to_sin(&aux_tmp, &aux);
|
ast_sockaddr_to_sin(&aux_tmp, &aux);
|
||||||
|
|
||||||
/* If the STUN result is different from the IP of the hostname,
|
/* If the STUN result is different from the IP of the hostname,
|
||||||
lock on the stun IP of the hostname advertised by the
|
* lock on the stun IP of the hostname advertised by the
|
||||||
remote client */
|
* remote client */
|
||||||
if (aux.sin_addr.s_addr && (aux.sin_addr.s_addr != sin.sin_addr.s_addr)) {
|
if (aux.sin_addr.s_addr && (aux.sin_addr.s_addr != sin.sin_addr.s_addr)) {
|
||||||
ast_rtp_instance_stun_request(p->rtp, &aux_tmp, username);
|
ast_rtp_instance_stun_request(p->rtp, &aux_tmp, username);
|
||||||
} else {
|
} else {
|
||||||
@@ -1390,8 +1444,9 @@ static int gtalk_add_candidate(struct gtalk *client, ikspak *pak)
|
|||||||
char *from;
|
char *from;
|
||||||
|
|
||||||
from = iks_find_attrib(pak->x,"to");
|
from = iks_find_attrib(pak->x,"to");
|
||||||
if(!from)
|
if (!from) {
|
||||||
from = c->jid->full;
|
from = c->jid->full;
|
||||||
|
}
|
||||||
|
|
||||||
for (tmp = client->p; tmp; tmp = tmp->next) {
|
for (tmp = client->p; tmp; tmp = tmp->next) {
|
||||||
if (iks_find_with_attrib(pak->x, "session", "id", tmp->sid) || !strcmp(iks_find_attrib(pak->query, "id"), tmp->sid)) {
|
if (iks_find_with_attrib(pak->x, "session", "id", tmp->sid) || !strcmp(iks_find_attrib(pak->query, "id"), tmp->sid)) {
|
||||||
@@ -1472,8 +1527,9 @@ static struct ast_frame *gtalk_rtp_read(struct ast_channel *ast, struct gtalk_pv
|
|||||||
{
|
{
|
||||||
struct ast_frame *f;
|
struct ast_frame *f;
|
||||||
|
|
||||||
if (!p->rtp)
|
if (!p->rtp) {
|
||||||
return &ast_null_frame;
|
return &ast_null_frame;
|
||||||
|
}
|
||||||
f = ast_rtp_instance_read(p->rtp, 0);
|
f = ast_rtp_instance_read(p->rtp, 0);
|
||||||
gtalk_update_stun(p->parent, p);
|
gtalk_update_stun(p->parent, p);
|
||||||
if (p->owner) {
|
if (p->owner) {
|
||||||
@@ -1486,11 +1542,11 @@ static struct ast_frame *gtalk_rtp_read(struct ast_channel *ast, struct gtalk_pv
|
|||||||
ast_set_read_format(p->owner, p->owner->readformat);
|
ast_set_read_format(p->owner, p->owner->readformat);
|
||||||
ast_set_write_format(p->owner, p->owner->writeformat);
|
ast_set_write_format(p->owner, p->owner->writeformat);
|
||||||
}
|
}
|
||||||
/* if ((ast_test_flag(p, SIP_DTMF) == SIP_DTMF_INBAND) && p->vad) {
|
/* if ((ast_test_flag(p, SIP_DTMF) == SIP_DTMF_INBAND) && p->vad) {
|
||||||
f = ast_dsp_process(p->owner, p->vad, f);
|
f = ast_dsp_process(p->owner, p->vad, f);
|
||||||
if (option_debug && f && (f->frametype == AST_FRAME_DTMF))
|
if (option_debug && f && (f->frametype == AST_FRAME_DTMF))
|
||||||
ast_debug(1, "* Detected inband DTMF '%c'\n", f->subclass);
|
ast_debug(1, "* Detected inband DTMF '%c'\n", f->subclass);
|
||||||
} */
|
} */
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return f;
|
return f;
|
||||||
@@ -1668,8 +1724,8 @@ static int gtalk_digit(struct ast_channel *ast, char digit, unsigned int duratio
|
|||||||
ast_aji_increment_mid(client->connection->mid);
|
ast_aji_increment_mid(client->connection->mid);
|
||||||
iks_insert_attrib(gtalk, "xmlns", "http://jabber.org/protocol/gtalk");
|
iks_insert_attrib(gtalk, "xmlns", "http://jabber.org/protocol/gtalk");
|
||||||
iks_insert_attrib(gtalk, "action", "session-info");
|
iks_insert_attrib(gtalk, "action", "session-info");
|
||||||
/* put the initiator attribute to lower case if we receive the call
|
// put the initiator attribute to lower case if we receive the call
|
||||||
* otherwise GoogleTalk won't establish the session */
|
// otherwise GoogleTalk won't establish the session
|
||||||
if (!p->initiator) {
|
if (!p->initiator) {
|
||||||
char c;
|
char c;
|
||||||
char *t = lowerthem = ast_strdupa(p->them);
|
char *t = lowerthem = ast_strdupa(p->them);
|
||||||
@@ -1758,8 +1814,9 @@ static int gtalk_hangup(struct ast_channel *ast)
|
|||||||
client = p->parent;
|
client = p->parent;
|
||||||
p->owner = NULL;
|
p->owner = NULL;
|
||||||
ast->tech_pvt = NULL;
|
ast->tech_pvt = NULL;
|
||||||
if (!p->alreadygone)
|
if (!p->alreadygone) {
|
||||||
gtalk_action(client, p, "terminate");
|
gtalk_action(client, p, "terminate");
|
||||||
|
}
|
||||||
ast_mutex_unlock(&p->lock);
|
ast_mutex_unlock(&p->lock);
|
||||||
|
|
||||||
gtalk_free_pvt(client, p);
|
gtalk_free_pvt(client, p);
|
||||||
@@ -1878,7 +1935,9 @@ static char *gtalk_show_channels(struct ast_cli_entry *e, int cmd, struct ast_cl
|
|||||||
#undef FORMAT
|
#undef FORMAT
|
||||||
}
|
}
|
||||||
|
|
||||||
/*! \brief CLI command "gtalk reload" */
|
/*! \brief CLI command "gtalk reload"
|
||||||
|
* \todo XXX TODO make this work. */
|
||||||
|
#if 0
|
||||||
static char *gtalk_do_reload(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
|
static char *gtalk_do_reload(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
|
||||||
{
|
{
|
||||||
switch (cmd) {
|
switch (cmd) {
|
||||||
@@ -1895,6 +1954,7 @@ static char *gtalk_do_reload(struct ast_cli_entry *e, int cmd, struct ast_cli_ar
|
|||||||
ast_verbose("IT DOES WORK!\n");
|
ast_verbose("IT DOES WORK!\n");
|
||||||
return CLI_SUCCESS;
|
return CLI_SUCCESS;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
static int gtalk_parser(void *data, ikspak *pak)
|
static int gtalk_parser(void *data, ikspak *pak)
|
||||||
{
|
{
|
||||||
@@ -1929,53 +1989,6 @@ static int gtalk_parser(void *data, ikspak *pak)
|
|||||||
return IKS_FILTER_EAT;
|
return IKS_FILTER_EAT;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Not using this anymore probably take out soon
|
|
||||||
static struct gtalk_candidate *gtalk_create_candidate(char *args)
|
|
||||||
{
|
|
||||||
char *name, *type, *preference, *protocol;
|
|
||||||
struct gtalk_candidate *res;
|
|
||||||
res = ast_calloc(1, sizeof(*res));
|
|
||||||
if (args)
|
|
||||||
name = args;
|
|
||||||
if ((args = strchr(args, ','))) {
|
|
||||||
*args = '\0';
|
|
||||||
args++;
|
|
||||||
preference = args;
|
|
||||||
}
|
|
||||||
if ((args = strchr(args, ','))) {
|
|
||||||
*args = '\0';
|
|
||||||
args++;
|
|
||||||
protocol = args;
|
|
||||||
}
|
|
||||||
if ((args = strchr(args, ','))) {
|
|
||||||
*args = '\0';
|
|
||||||
args++;
|
|
||||||
type = args;
|
|
||||||
}
|
|
||||||
if (name)
|
|
||||||
ast_copy_string(res->name, name, sizeof(res->name));
|
|
||||||
if (preference) {
|
|
||||||
res->preference = atof(preference);
|
|
||||||
}
|
|
||||||
if (protocol) {
|
|
||||||
if (!strcasecmp("udp", protocol))
|
|
||||||
res->protocol = AJI_PROTOCOL_UDP;
|
|
||||||
if (!strcasecmp("ssltcp", protocol))
|
|
||||||
res->protocol = AJI_PROTOCOL_SSLTCP;
|
|
||||||
}
|
|
||||||
if (type) {
|
|
||||||
if (!strcasecmp("stun", type))
|
|
||||||
res->type = AJI_CONNECT_STUN;
|
|
||||||
if (!strcasecmp("local", type))
|
|
||||||
res->type = AJI_CONNECT_LOCAL;
|
|
||||||
if (!strcasecmp("relay", type))
|
|
||||||
res->type = AJI_CONNECT_RELAY;
|
|
||||||
}
|
|
||||||
|
|
||||||
return res;
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
|
|
||||||
static int gtalk_create_member(char *label, struct ast_variable *var, int allowguest,
|
static int gtalk_create_member(char *label, struct ast_variable *var, int allowguest,
|
||||||
struct ast_codec_pref prefs, char *context,
|
struct ast_codec_pref prefs, char *context,
|
||||||
struct gtalk *member)
|
struct gtalk *member)
|
||||||
@@ -1991,9 +2004,6 @@ static int gtalk_create_member(char *label, struct ast_variable *var, int allowg
|
|||||||
member->allowguest = allowguest;
|
member->allowguest = allowguest;
|
||||||
member->prefs = prefs;
|
member->prefs = prefs;
|
||||||
while (var) {
|
while (var) {
|
||||||
#if 0
|
|
||||||
struct gtalk_candidate *candidate = NULL;
|
|
||||||
#endif
|
|
||||||
if (!strcasecmp(var->name, "username"))
|
if (!strcasecmp(var->name, "username"))
|
||||||
ast_copy_string(member->user, var->value, sizeof(member->user));
|
ast_copy_string(member->user, var->value, sizeof(member->user));
|
||||||
else if (!strcasecmp(var->name, "disallow"))
|
else if (!strcasecmp(var->name, "disallow"))
|
||||||
@@ -2004,15 +2014,6 @@ static int gtalk_create_member(char *label, struct ast_variable *var, int allowg
|
|||||||
ast_copy_string(member->context, var->value, sizeof(member->context));
|
ast_copy_string(member->context, var->value, sizeof(member->context));
|
||||||
else if (!strcasecmp(var->name, "parkinglot"))
|
else if (!strcasecmp(var->name, "parkinglot"))
|
||||||
ast_copy_string(member->parkinglot, var->value, sizeof(member->parkinglot));
|
ast_copy_string(member->parkinglot, var->value, sizeof(member->parkinglot));
|
||||||
#if 0
|
|
||||||
else if (!strcasecmp(var->name, "candidate")) {
|
|
||||||
candidate = gtalk_create_candidate(var->value);
|
|
||||||
if (candidate) {
|
|
||||||
candidate->next = member->ourcandidates;
|
|
||||||
member->ourcandidates = candidate;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
else if (!strcasecmp(var->name, "connection")) {
|
else if (!strcasecmp(var->name, "connection")) {
|
||||||
if ((client = ast_aji_get_client(var->value))) {
|
if ((client = ast_aji_get_client(var->value))) {
|
||||||
member->connection = client;
|
member->connection = client;
|
||||||
@@ -2021,7 +2022,6 @@ static int gtalk_create_member(char *label, struct ast_variable *var, int allowg
|
|||||||
IKS_RULE_FROM_PARTIAL, member->user,
|
IKS_RULE_FROM_PARTIAL, member->user,
|
||||||
IKS_RULE_NS, GOOGLE_NS,
|
IKS_RULE_NS, GOOGLE_NS,
|
||||||
IKS_RULE_DONE);
|
IKS_RULE_DONE);
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
ast_log(LOG_ERROR, "connection referenced not found!\n");
|
ast_log(LOG_ERROR, "connection referenced not found!\n");
|
||||||
return 0;
|
return 0;
|
||||||
@@ -2064,40 +2064,39 @@ static int gtalk_load_config(void)
|
|||||||
/* Copy the default jb config over global_jbconf */
|
/* Copy the default jb config over global_jbconf */
|
||||||
memcpy(&global_jbconf, &default_jbconf, sizeof(struct ast_jb_conf));
|
memcpy(&global_jbconf, &default_jbconf, sizeof(struct ast_jb_conf));
|
||||||
|
|
||||||
|
/* set defaults */
|
||||||
|
memset(&stunaddr, 0, sizeof(stunaddr));
|
||||||
|
|
||||||
cat = ast_category_browse(cfg, NULL);
|
cat = ast_category_browse(cfg, NULL);
|
||||||
for (var = ast_variable_browse(cfg, "general"); var; var = var->next) {
|
for (var = ast_variable_browse(cfg, "general"); var; var = var->next) {
|
||||||
/* handle jb conf */
|
/* handle jb conf */
|
||||||
if (!ast_jb_read_conf(&global_jbconf, var->name, var->value))
|
if (!ast_jb_read_conf(&global_jbconf, var->name, var->value))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (!strcasecmp(var->name, "allowguest"))
|
if (!strcasecmp(var->name, "allowguest")) {
|
||||||
allowguest =
|
allowguest = (ast_true(ast_variable_retrieve(cfg, "general", "allowguest"))) ? 1 : 0;
|
||||||
(ast_true(ast_variable_retrieve(cfg, "general", "allowguest"))) ? 1 : 0;
|
} else if (!strcasecmp(var->name, "disallow")) {
|
||||||
else if (!strcasecmp(var->name, "disallow"))
|
|
||||||
ast_parse_allow_disallow(&prefs, &global_capability, var->value, 0);
|
ast_parse_allow_disallow(&prefs, &global_capability, var->value, 0);
|
||||||
else if (!strcasecmp(var->name, "allow"))
|
} else if (!strcasecmp(var->name, "allow")) {
|
||||||
ast_parse_allow_disallow(&prefs, &global_capability, var->value, 1);
|
ast_parse_allow_disallow(&prefs, &global_capability, var->value, 1);
|
||||||
else if (!strcasecmp(var->name, "context"))
|
} else if (!strcasecmp(var->name, "context")) {
|
||||||
ast_copy_string(context, var->value, sizeof(context));
|
ast_copy_string(context, var->value, sizeof(context));
|
||||||
else if (!strcasecmp(var->name, "parkinglot"))
|
} else if (!strcasecmp(var->name, "externip")) {
|
||||||
|
ast_copy_string(externip, var->value, sizeof(externip));
|
||||||
|
} else if (!strcasecmp(var->name, "parkinglot")) {
|
||||||
ast_copy_string(parkinglot, var->value, sizeof(parkinglot));
|
ast_copy_string(parkinglot, var->value, sizeof(parkinglot));
|
||||||
else if (!strcasecmp(var->name, "bindaddr")) {
|
} else if (!strcasecmp(var->name, "bindaddr")) {
|
||||||
if (!(hp = ast_gethostbyname(var->value, &ahp))) {
|
if (!(hp = ast_gethostbyname(var->value, &ahp))) {
|
||||||
ast_log(LOG_WARNING, "Invalid address: %s\n", var->value);
|
ast_log(LOG_WARNING, "Invalid address: %s\n", var->value);
|
||||||
} else {
|
} else {
|
||||||
memcpy(&bindaddr.sin_addr, hp->h_addr, sizeof(bindaddr.sin_addr));
|
memcpy(&bindaddr.sin_addr, hp->h_addr, sizeof(bindaddr.sin_addr));
|
||||||
}
|
}
|
||||||
}
|
} else if (!strcasecmp(var->name, "stunaddr")) {
|
||||||
/* Idea to allow for custom candidates */
|
stunaddr.sin_port = htons(STANDARD_STUN_PORT);
|
||||||
/*
|
if (ast_parse_arg(var->value, PARSE_INADDR, &stunaddr)) {
|
||||||
else if (!strcasecmp(var->name, "candidate")) {
|
ast_log(LOG_WARNING, "Invalid STUN server address: %s\n", var->value);
|
||||||
candidate = gtalk_create_candidate(var->value);
|
|
||||||
if (candidate) {
|
|
||||||
candidate->next = global_candidates;
|
|
||||||
global_candidates = candidate;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
*/
|
|
||||||
}
|
}
|
||||||
while (cat) {
|
while (cat) {
|
||||||
if (strcasecmp(cat, "general")) {
|
if (strcasecmp(cat, "general")) {
|
||||||
@@ -2113,28 +2112,19 @@ static int gtalk_load_config(void)
|
|||||||
member->allowguest = allowguest;
|
member->allowguest = allowguest;
|
||||||
member->prefs = prefs;
|
member->prefs = prefs;
|
||||||
while (var) {
|
while (var) {
|
||||||
if (!strcasecmp(var->name, "disallow"))
|
if (!strcasecmp(var->name, "disallow")) {
|
||||||
ast_parse_allow_disallow(&member->prefs, &member->capability,
|
ast_parse_allow_disallow(&member->prefs, &member->capability,
|
||||||
var->value, 0);
|
var->value, 0);
|
||||||
else if (!strcasecmp(var->name, "allow"))
|
} else if (!strcasecmp(var->name, "allow")) {
|
||||||
ast_parse_allow_disallow(&member->prefs, &member->capability,
|
ast_parse_allow_disallow(&member->prefs, &member->capability,
|
||||||
var->value, 1);
|
var->value, 1);
|
||||||
else if (!strcasecmp(var->name, "context"))
|
} else if (!strcasecmp(var->name, "context")) {
|
||||||
ast_copy_string(member->context, var->value,
|
ast_copy_string(member->context, var->value,
|
||||||
sizeof(member->context));
|
sizeof(member->context));
|
||||||
else if (!strcasecmp(var->name, "parkinglot"))
|
} else if (!strcasecmp(var->name, "parkinglot")) {
|
||||||
ast_copy_string(member->parkinglot, var->value,
|
ast_copy_string(member->parkinglot, var->value,
|
||||||
sizeof(member->parkinglot));
|
sizeof(member->parkinglot));
|
||||||
/* Idea to allow for custom candidates */
|
|
||||||
/*
|
|
||||||
else if (!strcasecmp(var->name, "candidate")) {
|
|
||||||
candidate = gtalk_create_candidate(var->value);
|
|
||||||
if (candidate) {
|
|
||||||
candidate->next = member->ourcandidates;
|
|
||||||
member->ourcandidates = candidate;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
*/
|
|
||||||
var = var->next;
|
var = var->next;
|
||||||
}
|
}
|
||||||
ASTOBJ_UNLOCK(member);
|
ASTOBJ_UNLOCK(member);
|
||||||
@@ -2164,6 +2154,8 @@ static int gtalk_load_config(void)
|
|||||||
}
|
}
|
||||||
cat = ast_category_browse(cfg, cat);
|
cat = ast_category_browse(cfg, cat);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
gtalk_update_externip();
|
||||||
gtalk_free_candidates(global_candidates);
|
gtalk_free_candidates(global_candidates);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
@@ -2193,12 +2185,14 @@ static int load_module(void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
sched = sched_context_create();
|
sched = sched_context_create();
|
||||||
if (!sched)
|
if (!sched) {
|
||||||
ast_log(LOG_WARNING, "Unable to create schedule context\n");
|
ast_log(LOG_WARNING, "Unable to create schedule context\n");
|
||||||
|
}
|
||||||
|
|
||||||
io = io_context_create();
|
io = io_context_create();
|
||||||
if (!io)
|
if (!io) {
|
||||||
ast_log(LOG_WARNING, "Unable to create I/O context\n");
|
ast_log(LOG_WARNING, "Unable to create I/O context\n");
|
||||||
|
}
|
||||||
|
|
||||||
ast_sockaddr_from_sin(&bindaddr_tmp, &bindaddr);
|
ast_sockaddr_from_sin(&bindaddr_tmp, &bindaddr);
|
||||||
if (ast_find_ourip(&ourip_tmp, &bindaddr_tmp)) {
|
if (ast_find_ourip(&ourip_tmp, &bindaddr_tmp)) {
|
||||||
@@ -2218,12 +2212,14 @@ static int load_module(void)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*! \brief Reload module */
|
/*! \brief Reload module
|
||||||
|
* \todo XXX TODO make this work. */
|
||||||
|
#if 0
|
||||||
static int reload(void)
|
static int reload(void)
|
||||||
{
|
{
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
/*! \brief Unload the gtalk channel from Asterisk */
|
/*! \brief Unload the gtalk channel from Asterisk */
|
||||||
static int unload_module(void)
|
static int unload_module(void)
|
||||||
{
|
{
|
||||||
@@ -2259,6 +2255,6 @@ static int unload_module(void)
|
|||||||
AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_LOAD_ORDER, "Gtalk Channel Driver",
|
AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_LOAD_ORDER, "Gtalk Channel Driver",
|
||||||
.load = load_module,
|
.load = load_module,
|
||||||
.unload = unload_module,
|
.unload = unload_module,
|
||||||
.reload = reload,
|
/* .reload = reload, */
|
||||||
.load_pri = AST_MODPRI_CHANNEL_DRIVER,
|
.load_pri = AST_MODPRI_CHANNEL_DRIVER,
|
||||||
);
|
);
|
||||||
|
@@ -1,20 +1,25 @@
|
|||||||
;[general]
|
;[general]
|
||||||
;context=default ;;Context to dump call into
|
;context=default ;Context to dump call into
|
||||||
;bindaddr=0.0.0.0 ;;Address to bind to
|
;bindaddr=0.0.0.0 ;Address to bind to
|
||||||
;allowguest=yes ;;Allow calls from people not in
|
;externip=127.0.0.1 ;Set your external ip if you are behind a NAT.
|
||||||
;;list of peers
|
|
||||||
|
;stunaddr=mystunserver.com ; Get your external ip from a STUN server.
|
||||||
|
; Note, if the STUN query is successful, this will
|
||||||
|
; replace any value placed in externip;
|
||||||
|
;allowguest=yes ;Allow calls from people not in
|
||||||
|
;list of peers
|
||||||
;
|
;
|
||||||
;[guest] ;;special account for options on guest account
|
;[guest] ;special account for options on guest account
|
||||||
;disallow=all
|
;disallow=all
|
||||||
;allow=ulaw
|
;allow=ulaw
|
||||||
;context=guest
|
;context=guest
|
||||||
;
|
;
|
||||||
;[ogorman]
|
;[ogorman]
|
||||||
;username=ogorman@gmail.com ;;username of the peer your
|
;username=ogorman@gmail.com ;username of the peer your
|
||||||
;;calling or accepting calls from
|
;calling or accepting calls from
|
||||||
;disallow=all
|
;disallow=all
|
||||||
;allow=ulaw
|
;allow=ulaw
|
||||||
;context=default
|
;context=default
|
||||||
;connection=asterisk ;;client or component in jabber.conf
|
;connection=asterisk ;client or component in jabber.conf
|
||||||
;;for the call to leave on.
|
;for the call to leave on.
|
||||||
;
|
;
|
||||||
|
@@ -32,6 +32,8 @@
|
|||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
static const int STANDARD_STUN_PORT = 3478;
|
||||||
|
|
||||||
enum ast_stun_result {
|
enum ast_stun_result {
|
||||||
AST_STUN_IGNORE = 0,
|
AST_STUN_IGNORE = 0,
|
||||||
AST_STUN_ACCEPT,
|
AST_STUN_ACCEPT,
|
||||||
|
@@ -36,7 +36,6 @@ ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
|
|||||||
#include "asterisk/lock.h"
|
#include "asterisk/lock.h"
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
|
|
||||||
static const int STANDARD_STUN_PORT = 3478;
|
|
||||||
static const int DEFAULT_MONITOR_REFRESH = 30;
|
static const int DEFAULT_MONITOR_REFRESH = 30;
|
||||||
|
|
||||||
static const char stun_conf_file[] = "res_stun_monitor.conf";
|
static const char stun_conf_file[] = "res_stun_monitor.conf";
|
||||||
|
Reference in New Issue
Block a user