[asterisk-commits] branch mogorman/asterisk-xmpp r19702 - in
/team/mogorman/asterisk-xmpp: chann...
asterisk-commits at lists.digium.com
asterisk-commits at lists.digium.com
Wed Apr 12 22:54:09 MST 2006
Author: markster
Date: Thu Apr 13 00:54:08 2006
New Revision: 19702
URL: http://svn.digium.com/view/asterisk?rev=19702&view=rev
Log:
Start making the channel driver look more like a real channel driver.
Modified:
team/mogorman/asterisk-xmpp/channels/chan_jingle.c
team/mogorman/asterisk-xmpp/include/asterisk/jingle.h
team/mogorman/asterisk-xmpp/res/res_jabber.c
Modified: team/mogorman/asterisk-xmpp/channels/chan_jingle.c
URL: http://svn.digium.com/view/asterisk/team/mogorman/asterisk-xmpp/channels/chan_jingle.c?rev=19702&r1=19701&r2=19702&view=diff
==============================================================================
--- team/mogorman/asterisk-xmpp/channels/chan_jingle.c (original)
+++ team/mogorman/asterisk-xmpp/channels/chan_jingle.c Thu Apr 13 00:54:08 2006
@@ -63,6 +63,7 @@
#include "asterisk/manager.h"
#include "asterisk/stringfields.h"
#include "asterisk/utils.h"
+#include "asterisk/causes.h"
#include "asterisk/jabber.h"
#include "asterisk/jingle.h"
@@ -89,13 +90,13 @@
static int jingle_call(struct ast_channel *ast, char *dest, int timeout);
static int jingle_hangup(struct ast_channel *ast);
static int jingle_answer(struct ast_channel *ast);
-static int jingle_answer2(struct jingle *client, ikspak *pak);
+static int jingle_newcall(struct jingle *client, ikspak *pak);
static struct ast_frame *jingle_read(struct ast_channel *ast);
static int jingle_write(struct ast_channel *ast, struct ast_frame *f);
static int jingle_indicate(struct ast_channel *ast, int condition);
static int jingle_fixup(struct ast_channel *oldchan, struct ast_channel *newchan);
static int jingle_sendhtml(struct ast_channel *ast, int subclass, const char *data, int datalen);
-static struct jingle_pvt *jingle_alloc(char *data, int format);
+static struct jingle_pvt *jingle_alloc(struct jingle *client, const char *from, const char *sid);
/* PBX interface structure for channel registration */
static const struct ast_channel_tech jingle_tech = {
@@ -125,7 +126,7 @@
static struct io_context *io; /*!< The IO context */
static struct in_addr __ourip;
/*----- RTP interface functions */
-static int jingle_set_rtp_peer(struct ast_channel *chan, struct ast_rtp *rtp, int codecs, int nat_active);
+static int jingle_set_rtp_peer(struct ast_channel *chan, struct ast_rtp *rtp, struct ast_rtp *vrtp, int codecs, int nat_active);
static struct ast_rtp *jingle_get_rtp_peer(struct ast_channel *chan);
static int jingle_get_codec(struct ast_channel *chan);
@@ -237,7 +238,7 @@
return p->peercapability;
}
-static int jingle_set_rtp_peer(struct ast_channel *chan, struct ast_rtp *rtp, int codecs, int nat_active)
+static int jingle_set_rtp_peer(struct ast_channel *chan, struct ast_rtp *rtp, struct ast_rtp *vrtp, int codecs, int nat_active)
{
struct jingle_pvt *p;
@@ -279,10 +280,10 @@
p = p->next;
}
- hp = ast_gethostbyname(p->candidates->ip, &ahp);
+ hp = ast_gethostbyname(p->theircandidates->ip, &ahp);
sin.sin_family = AF_INET;
memcpy(&sin.sin_addr, hp->h_addr, sizeof(sin.sin_addr));
- sin.sin_port = htons(p->candidates->port);
+ sin.sin_port = htons(p->theircandidates->port);
if (p->rtp && sin.sin_port) {
ast_rtp_set_peer(p->rtp, &sin);
ast_verbose("Peer audio RTP is at port %s:%d\n", ast_inet_ntoa(iabuf,sizeof(iabuf), sin.sin_addr), ntohs(sin.sin_port));
@@ -355,10 +356,9 @@
return 1;
}
-static int jingle_create_candidates(struct jingle *client,ikspak *pak)
+static int jingle_create_candidates(struct jingle *client, struct jingle_pvt *p, ikspak *pak)
{
struct jingle_candidate *tmp;
- struct jingle_pvt *p = client->p;
struct aji_client *c = client->connection;
struct sockaddr_in sin;
struct sockaddr_in dest;
@@ -366,14 +366,21 @@
iks *iq, *jingle, *candidate;
char user[17], pass[17], preference[5], port[7];
- tmp = p->candidates;
+
+
+ tmp = client->ourcandidates;
+
iq = iks_new("iq");
jingle = iks_new(GOOGLE_NODE);
candidate = iks_new("candidate");
+ if (!iq || !jingle || !candidate) {
+ ast_log(LOG_WARNING, "out of memory!\n");
+ goto safeout;
+ }
+
iks_insert_node(iq,jingle);
iks_insert_node(jingle,candidate);
-
-
+
while(p) {
if(!strcasecmp(p->sid,iks_find_attrib(pak->query,GOOGLE_SID))) {
break;
@@ -424,7 +431,7 @@
iks_send(c->p,iq);
tmp=tmp->next;
}
- if(!p->candidates) { /*send default stun, and local, and relay */
+ if(!p->theircandidates) { /*send default stun, and local, and relay */
snprintf(user, sizeof(user),"%08x%08x",thread_safe_rand(),thread_safe_rand());
snprintf(pass, sizeof(pass),"%08x%08x",thread_safe_rand(),thread_safe_rand());
iks_insert_attrib(iq,"from", c->jid->full);
@@ -473,9 +480,13 @@
iks_insert_attrib(candidate, "type", "relay");
iks_send(c->p,iq);
}
- iks_delete(candidate);
- iks_delete(jingle);
- iks_delete(iq);
+safeout:
+ if (iq)
+ iks_delete(iq);
+ if (jingle)
+ iks_delete(jingle);
+ if (candidate)
+ iks_delete(candidate);
return 1;
}
@@ -612,7 +623,7 @@
return 1;
}
-static struct jingle_pvt *jingle_alloc2(struct jingle *client, ikspak *pak)
+static struct jingle_pvt *jingle_alloc(struct jingle *client, const char *from, const char *sid)
{
struct jingle_pvt *tmp = client->p;
@@ -620,7 +631,16 @@
return NULL;
}
tmp->rtp = ast_rtp_new_with_bindaddr(sched, io, 1, 0, bindaddr.sin_addr);
-
+ if (!tmp->rtp) {
+ ast_log(LOG_WARNING, "Out of RTP sessions?\n");
+ free(tmp);
+ return NULL;
+ }
+ ast_copy_string(tmp->from, from, sizeof(tmp->from));
+ if (sid)
+ ast_copy_string(tmp->sid, sid, sizeof(tmp->sid));
+ else
+ snprintf(tmp->sid, sizeof(tmp->sid), "%08lx%08lx", ast_random(), ast_random());
ast_mutex_init(&tmp->lock);
ast_mutex_lock(&jinglelock);
tmp->next = client->p;
@@ -629,49 +649,232 @@
return tmp;
}
-static int jingle_answer2(struct jingle *client,ikspak *pak)
+/*! \brief Start new jingle channel */
+static struct ast_channel *jingle_new(struct jingle *client, struct jingle_pvt *i, int state, const char *title)
+{
+ struct ast_channel *tmp;
+ int fmt;
+ int what;
+
+ tmp = ast_channel_alloc(1);
+ if (!tmp) {
+ ast_log(LOG_WARNING, "Unable to allocate Jingle channel structure!\n");
+ return NULL;
+ }
+ tmp->tech = &jingle_tech;
+
+ /* Select our native format based on codec preference until we receive
+ something from another device to the contrary. */
+ if (i->jointcapability)
+ what = i->jointcapability;
+ else if (i->capability)
+ what = i->capability;
+ else
+ what = global_capability;
+ tmp->nativeformats = ast_codec_choose(&i->prefs, what, 1) | (i->jointcapability & AST_FORMAT_VIDEO_MASK);
+ fmt = ast_best_codec(tmp->nativeformats);
+
+ if (title)
+ ast_string_field_build(tmp, name, "Jingle/%s-%04lx", title, ast_random() & 0xffff);
+ else
+ ast_string_field_build(tmp, name, "Jingle/%s-%04lx", i->from, ast_random() & 0xffff);
+
+ if (i->rtp) {
+ tmp->fds[0] = ast_rtp_fd(i->rtp);
+ tmp->fds[1] = ast_rtcp_fd(i->rtp);
+ }
+ if (i->vrtp) {
+ tmp->fds[2] = ast_rtp_fd(i->vrtp);
+ tmp->fds[3] = ast_rtcp_fd(i->vrtp);
+ }
+ if (state == AST_STATE_RING)
+ tmp->rings = 1;
+ tmp->adsicpe = AST_ADSI_UNAVAILABLE;
+ tmp->writeformat = fmt;
+ tmp->rawwriteformat = fmt;
+ tmp->readformat = fmt;
+ tmp->rawreadformat = fmt;
+ tmp->tech_pvt = i;
+
+ tmp->callgroup = client->callgroup;
+ tmp->pickupgroup = client->pickupgroup;
+ tmp->cid.cid_pres = client->callingpres;
+ if (!ast_strlen_zero(client->accountcode))
+ ast_string_field_set(tmp, accountcode, client->accountcode);
+ if (client->amaflags)
+ tmp->amaflags = client->amaflags;
+ if (!ast_strlen_zero(client->language))
+ ast_string_field_set(tmp, language, client->language);
+ if (!ast_strlen_zero(client->musicclass))
+ ast_string_field_set(tmp, musicclass, client->musicclass);
+ i->owner = tmp;
+ ast_mutex_lock(&usecnt_lock);
+ usecnt++;
+ ast_mutex_unlock(&usecnt_lock);
+ ast_copy_string(tmp->context, client->context, sizeof(tmp->context));
+ ast_copy_string(tmp->exten, i->exten, sizeof(tmp->exten));
+ if (!ast_strlen_zero(i->cid_num))
+ tmp->cid.cid_num = ast_strdup(i->cid_num);
+ if (!ast_strlen_zero(i->cid_name))
+ tmp->cid.cid_name = ast_strdup(i->cid_name);
+ if (!ast_strlen_zero(i->exten) && strcmp(i->exten, "s"))
+ tmp->cid.cid_dnid = ast_strdup(i->exten);
+ tmp->priority = 1;
+ ast_setstate(tmp, state);
+ if (state != AST_STATE_DOWN && ast_pbx_start(tmp)) {
+ ast_log(LOG_WARNING, "Unable to start PBX on %s\n", tmp->name);
+ tmp->hangupcause = AST_CAUSE_SWITCH_CONGESTION;
+ ast_hangup(tmp);
+ tmp = NULL;
+ }
+ return tmp;
+}
+
+static int jingle_response(struct jingle *client, ikspak *pak, const char *reasonstr)
+{
+ iks *response, *error=NULL, *reason=NULL;
+ int res = -1;
+
+ response = iks_new("iq");
+ if (response) {
+ iks_insert_attrib(response,"type","result");
+ iks_insert_attrib(response,"from", client->connection->jid->full);
+ iks_insert_attrib(response,"to",iks_find_attrib(pak->x,"from"));
+ iks_insert_attrib(response,"id",iks_find_attrib(pak->x,"id"));
+ if (reasonstr) {
+ error = iks_new("error");
+ if (error) {
+ iks_insert_attrib(error, "type", "cancel");
+ reason = iks_new(reasonstr);
+ if (reason)
+ iks_insert_node(error, reason);
+ iks_insert_node(response, error);
+ }
+ }
+ iks_send(client->connection->p, response);
+ if (reason)
+ iks_delete(reason);
+ if (error)
+ iks_delete(error);
+ iks_delete(response);
+ res = 0;
+ }
+ return res;
+}
+
+static void jingle_free_candidates(struct jingle_candidate *candidate)
+{
+ struct jingle_candidate *last;
+ while (candidate) {
+ last = candidate;
+ candidate = candidate->next;
+ free(last);
+ }
+}
+
+static struct jingle_candidate *jingle_dup_candidates(struct jingle_candidate *candidate)
+{
+ struct jingle_candidate *newcan=NULL, *prev=NULL, *tmp;
+ while (candidate) {
+ tmp = malloc(sizeof(struct jingle_candidate));
+ if (tmp) {
+ memcpy(tmp, candidate, sizeof(struct jingle_candidate));
+ tmp->next = NULL;
+ if (prev)
+ prev->next = tmp;
+ else
+ newcan = tmp;
+ prev = tmp;
+ }
+ candidate = candidate->next;
+ }
+ return newcan;
+}
+
+static void jingle_free(struct jingle *client, struct jingle_pvt *p)
+{
+ struct jingle_pvt *cur, *prev = NULL;
+ cur = client->p;
+ while (cur) {
+ if (cur == p) {
+ if (prev)
+ prev->next = p->next;
+ else
+ client->p = p->next;
+ break;
+ }
+ prev = cur;
+ cur = cur->next;
+ }
+ if (p->owner)
+ ast_log(LOG_WARNING, "Uh oh, there's an owner, this is going to be messy.\n");
+ if (p->rtp)
+ ast_rtp_destroy(p->rtp);
+ if (p->vrtp)
+ ast_rtp_destroy(p->vrtp);
+ jingle_free_candidates(p->theircandidates);
+ free(p);
+}
+
+
+static int jingle_newcall(struct jingle *client, ikspak *pak)
{
struct jingle_pvt *p ,*tmp = client->p;
- struct aji_client *c = client->connection;
struct ast_channel *chan;
- iks *accept, *codec;
-
-
- codec = iks_child(iks_child(iks_child(pak->x)));
- chan = ast_channel_alloc(1);
- chan->tech = &jingle_tech;
+ int res;
+ iks *codec;
+
+ /* Make sure our new call doesn't exist yet */
while(tmp) {
- if(iks_find_with_attrib(pak->x,GOOGLE_NODE,GOOGLE_SID,tmp->sid))
- {
+ if (iks_find_with_attrib(pak->x, GOOGLE_NODE,GOOGLE_SID, tmp->sid)) {
+ ast_log(LOG_NOTICE, "Ignoring duplicate call setup on SID %s\n", tmp->sid);
+ jingle_response(client, pak, "out-of-order");
return -1;
}
tmp=tmp->next;
}
- p = jingle_alloc2(client, pak);
- ast_mutex_lock(&p->lock);
- if(iks_find_attrib(pak->x,"from"))
- ast_copy_string(p->from,iks_find_attrib(pak->x,"from"),sizeof(p->from));
- if(iks_find_attrib(pak->query,GOOGLE_SID)) {
- ast_copy_string(p->sid,iks_find_attrib(pak->query,GOOGLE_SID),sizeof(p->sid));
- }
-
- while(codec) {
- ast_rtp_set_m_type(p->rtp, atoi(iks_find_attrib(codec,"id")));
- ast_rtp_set_rtpmap_type(p->rtp, atoi(iks_find_attrib(codec,"id")), "audio", iks_find_attrib(codec,"name"));
- ast_verbose("yatta!!\n");
- codec= iks_next(codec);
- }
- ast_pbx_start(chan);
- p->owner = chan;
- ast_mutex_unlock(&p->lock);
- accept = iks_new("iq");
- iks_insert_attrib(accept,"type","result");
- iks_insert_attrib(accept,"from",c->jid->full);
- iks_insert_attrib(accept,"to",iks_find_attrib(pak->x,"from"));
- iks_insert_attrib(accept,"id",iks_find_attrib(pak->x,"id"));
- iks_send(c->p,accept);
- iks_delete(accept);
- jingle_create_candidates(client,pak);
+
+ p = jingle_alloc(client, pak->from->partial, iks_find_attrib(pak->query,GOOGLE_SID));
+ if (!p) {
+ ast_log(LOG_WARNING, "Unable to allocate jingle structure!\n");
+ return -1;
+ }
+ chan = jingle_new(client, p, AST_STATE_DOWN, pak->from->user);
+ if (chan) {
+ ast_mutex_lock(&p->lock);
+ ast_copy_string(p->from, pak->from->full, sizeof(p->from));
+ if(iks_find_attrib(pak->query,GOOGLE_SID)) {
+ ast_copy_string(p->sid,iks_find_attrib(pak->query,GOOGLE_SID),sizeof(p->sid));
+ }
+
+ codec = iks_child(iks_child(iks_child(pak->x)));
+ while(codec) {
+ ast_rtp_set_m_type(p->rtp, atoi(iks_find_attrib(codec,"id")));
+ ast_rtp_set_rtpmap_type(p->rtp, atoi(iks_find_attrib(codec,"id")), "audio", iks_find_attrib(codec,"name"));
+ ast_verbose("yatta!!\n");
+ codec= iks_next(codec);
+ }
+ ast_mutex_unlock(&p->lock);
+ res = ast_pbx_start(chan);
+ jingle_create_candidates(client, p, pak);
+
+ switch (res) {
+ case AST_PBX_FAILED:
+ ast_log(LOG_WARNING, "Failed to start PBX :(\n");
+ jingle_response(client, pak, "service-unavailable");
+ break;
+ case AST_PBX_CALL_LIMIT:
+ ast_log(LOG_WARNING, "Failed to start PBX (call limit reached) \n");
+ jingle_response(client, pak, "service-unavailable");
+ break;
+ case AST_PBX_SUCCESS:
+ jingle_response(client, pak, NULL);
+ /* nothing to do */
+ break;
+ }
+ } else {
+ jingle_free(client, p);
+ }
return 1;
}
@@ -732,8 +935,8 @@
ast_rtp_set_peer(p->rtp, &sin);
ast_verbose("Peer audio RTP is at port %s:%d\n", ast_inet_ntoa(iabuf,sizeof(iabuf), sin.sin_addr), ntohs(sin.sin_port));
}
- newcandidate->next = p->candidates;
- p->candidates = newcandidate;
+ newcandidate->next = p->theircandidates;
+ p->theircandidates = newcandidate;
ast_verbose("sending\n");
receipt = iks_new("iq");
iks_insert_attrib(receipt,"type","result");
@@ -789,24 +992,44 @@
return fr;
}
-static int jingle_write(struct ast_channel *ast, struct ast_frame *f)
+/*! \brief Send frame to media channel (rtp) */
+static int jingle_write(struct ast_channel *ast, struct ast_frame *frame)
{
struct jingle_pvt *p = ast->tech_pvt;
- int res = -1;
- int isoutbound;
-
- /* Just queue for delivery to the other side */
- ast_mutex_lock(&p->lock);
-// isoutbound = IS_OUTBOUND(ast, p);
- if (f && (f->frametype == AST_FRAME_VOICE))
- check_bridge(p, isoutbound);
-// if (!p->alreadymasqed)
-// res = jingle_queue_frame(p, isoutbound, f, ast);
-// else {
-// ast_log(LOG_DEBUG, "Not posting to queue since already masked on '%s'\n", ast->name);
-// res = 0;
-// }
- ast_mutex_unlock(&p->lock);
+ int res = 0;
+
+ switch (frame->frametype) {
+ case AST_FRAME_VOICE:
+ if (!(frame->subclass & ast->nativeformats)) {
+ ast_log(LOG_WARNING, "Asked to transmit frame type %d, while native formats is %d (read/write = %d/%d)\n",
+ frame->subclass, ast->nativeformats, ast->readformat, ast->writeformat);
+ return 0;
+ }
+ if (p) {
+ ast_mutex_lock(&p->lock);
+ if (p->rtp) {
+ res = ast_rtp_write(p->rtp, frame);
+ }
+ ast_mutex_unlock(&p->lock);
+ }
+ break;
+ case AST_FRAME_VIDEO:
+ if (p) {
+ ast_mutex_lock(&p->lock);
+ if (p->vrtp) {
+ res = ast_rtp_write(p->vrtp, frame);
+ }
+ ast_mutex_unlock(&p->lock);
+ }
+ break;
+ case AST_FRAME_IMAGE:
+ return 0;
+ break;
+ default:
+ ast_log(LOG_WARNING, "Can't send %d type frames with Jingle write\n", frame->frametype);
+ return 0;
+ }
+
return res;
}
@@ -941,10 +1164,9 @@
/*! \brief Hangup a call through the jingle proxy channel */
static int jingle_hangup(struct ast_channel *ast)
{
-#if 0
struct jingle_pvt *p = ast->tech_pvt;
struct jingle *peer = NULL;
- struct aji_client *client = NULL;
+ struct jingle *client = NULL;
client = ast_aji_get_client("asterisk");
int isoutbound;
struct ast_frame f = { AST_FRAME_CONTROL, AST_CONTROL_HANGUP };
@@ -954,67 +1176,19 @@
const char *status;
ast_mutex_lock(&p->lock);
- if (isoutbound) {
-// status = pbx_builtin_getvar_helper(p->chan, "DIALSTATUS");
- if(status)
- pbx_builtin_setvar_helper(p->owner, "CHANLOCALSTATUS", status);
-// p->chan = NULL;
-// p->launchedpbx = 0;
- } else
- p->owner = NULL;
+ p->owner = NULL;
ast->tech_pvt = NULL;
-
+ if (!p->alreadygone) {
+
+ }
+ ast_mutex_unlock(&p->lock);
ast_mutex_lock(&usecnt_lock);
usecnt--;
ast_mutex_unlock(&usecnt_lock);
-
- if (!p->owner ) {
- /* Okay, done with the private part now, too. */
-// glaredetect = p->glaredetect;
- /* If we have a queue holding, don't actually destroy p yet, but
- let jingle_queue do it. */
-// if (p->glaredetect)
-// p->cancelqueue = 1;
- ast_mutex_unlock(&p->lock);
- /* Remove from list */
- ast_mutex_lock(&jinglelock);
-
- if((peer = find_jingle(client,pak)))
- cur = peer->p;
- while(cur) {
- if (cur == p) {
- if (prev)
- prev->next = cur->next;
- else
- peer->p = cur->next;
- break;
- }
- prev = cur;
- cur = cur->next;
- }
- ast_mutex_unlock(&jinglelock);
- /* Grab / release lock just in case */
- ast_mutex_lock(&p->lock);
- ast_mutex_unlock(&p->lock);
- /* And destroy */
-/* if (!glaredetect) {
- ast_mutex_destroy(&p->lock);
- free(p);
- }*/
- return 0;
- }
-// if (p->chan )
-// /* Need to actually hangup since there is no PBX */
-// ochan = p->chan;
-// else
-// jingle_queue_frame(p, isoutbound, &f, NULL);
- ast_mutex_unlock(&p->lock);
- if (ochan)
- ast_hangup(ochan);
-#endif
return 0;
}
+#if 0
/*! \brief Create a call structure */
static struct jingle_pvt *jingle_alloc(char *data, int format)
{
@@ -1025,31 +1199,22 @@
}
return tmp;
}
-
-/*! \brief Start new jingle channel */
-static struct ast_channel *jingle_new(struct jingle_pvt *p, int state)
-{
- struct ast_channel *tmp;
-
- tmp = ast_channel_alloc(1);
- ast_mutex_lock(&usecnt_lock);
- usecnt++;
- ast_mutex_unlock(&usecnt_lock);
- ast_update_use_count();
- return tmp;
-}
-
+#endif
/*! \brief Part of PBX interface */
static struct ast_channel *jingle_request(const char *type, int format, void *data, int *cause)
{
+#if 0
struct jingle_pvt *p;
struct ast_channel *chan = NULL;
-
+
p = jingle_alloc(data, format);
if (p)
chan = jingle_new(p, AST_STATE_DOWN);
return chan;
+#endif
+
+ return NULL;
}
#if 0
@@ -1059,7 +1224,7 @@
struct jingle_pvt *p=NULL;
struct jingle *peer=NULL;
struct jingle_candidate *tmp;
- struct aji_client *client = NULL;
+ struct jingle *client = NULL;
client = ast_aji_get_client("asterisk");
if (argc != 3)
return RESULT_SHOWUSAGE;
@@ -1097,9 +1262,10 @@
struct jingle *client= ASTOBJ_REF((struct jingle *) udata);;
ast_verbose("WOOHOO!!!\n");
- if(iks_find_with_attrib(pak->x,GOOGLE_NODE,"type",JINGLE_INITIATE))
- jingle_answer2(client, pak);
- else if(iks_find_with_attrib(pak->x,GOOGLE_NODE,"type",GOOGLE_NEGOTIATE)) {
+ if(iks_find_with_attrib(pak->x,GOOGLE_NODE,"type",JINGLE_INITIATE)) {
+ /* New call */
+ jingle_newcall(client, pak);
+ } else if(iks_find_with_attrib(pak->x,GOOGLE_NODE,"type",GOOGLE_NEGOTIATE)) {
jingle_add_candidate(client,pak);
if(flipflop == 2) {
flipflop = 0;
@@ -1123,9 +1289,9 @@
static struct jingle_candidate *jingle_create_candidate(char *args)
{
char *name, *type, *preference, *protocol;
- struct axi_candidate *res;
- res= malloc(sizeof(struct axi_candidate));
- memset(res,0,sizeof(struct axi_candidate));
+ struct jingle_candidate *res;
+ res= malloc(sizeof(struct jingle_candidate));
+ memset(res,0,sizeof(struct jingle_candidate));
if(args)
name = args;
if((args = strchr(args,','))) {
@@ -1150,17 +1316,17 @@
}
if(protocol) {
if(!strcasecmp("udp",protocol))
- res->protocol=AXI_PROTOCOL_UDP;
+ res->protocol=AJI_PROTOCOL_UDP;
if(!strcasecmp("ssltcp",protocol))
- res->protocol=AXI_PROTOCOL_SSLTCP;
+ res->protocol=AJI_PROTOCOL_SSLTCP;
}
if(type) {
if(!strcasecmp("stun",type))
- res->type = AXI_CONNECT_STUN;
+ res->type = AJI_CONNECT_STUN;
if(!strcasecmp("local",type))
- res->type = AXI_CONNECT_LOCAL;
+ res->type = AJI_CONNECT_LOCAL;
if(!strcasecmp("relay",type))
- res->type = AXI_CONNECT_RELAY;
+ res->type = AJI_CONNECT_RELAY;
}
return res;
@@ -1168,7 +1334,7 @@
static int jingle_create_member(char *label, struct ast_variable *var, int allowguest, struct ast_codec_pref prefs, char *context, struct jingle *member)
{
- struct aji_client *client=NULL;
+ struct aji_client *client;
if(!member)
ast_log(LOG_WARNING, "Out of memory.\n");
ast_copy_string(member->name, label, sizeof(member->name));
@@ -1189,8 +1355,8 @@
else if (!strcasecmp(var->name, "candidate")) {
candidate = jingle_create_candidate(var->value);
if(candidate) {
- candidate->next = client->ourcandidates;
- client->ourcandidates = canidate;
+ candidate->next = member->ourcandidates;
+ member->ourcandidates = candidate;
}
}
else if (!strcasecmp(var->name, "connection")) {
@@ -1223,6 +1389,7 @@
struct jingle *member;
struct ast_codec_pref prefs;
struct aji_client_container *clients;
+ struct jingle_candidate *global_candidates = NULL;
cfg = ast_config_load(JINGLE_CONFIG);
if(!cfg) {
@@ -1246,8 +1413,8 @@
else if (!strcasecmp(var->name, "candidate")) {
candidate = jingle_create_candidate(var->value);
if(candidate) {
- candidate->next = client->ourcandidates;
- client->ourcandidates = canidate;
+ candidate->next = global_candidates;
+ global_candidates = candidate;
}
}
@@ -1265,6 +1432,7 @@
ast_copy_string(member->user, "guest", sizeof(member->user));
ast_copy_string(member->context, context, sizeof(member->context));
member->allowguest=allowguest;
+ member->ourcandidates = jingle_dup_candidates(global_candidates);
member->prefs=prefs;
while(var) {
if(!strcasecmp(var->name,"disallow"))
@@ -1276,8 +1444,8 @@
else if (!strcasecmp(var->name, "candidate")) {
candidate = jingle_create_candidate(var->value);
if(candidate) {
- candidate->next = client->ourcandidates;
- client->ourcandidates = canidate;
+ candidate->next = member->ourcandidates;
+ member->ourcandidates = candidate;
}
}
@@ -1313,6 +1481,7 @@
}
cat = ast_category_browse(cfg,cat);
}
+ jingle_free_candidates(global_candidates);
return 1;
}
Modified: team/mogorman/asterisk-xmpp/include/asterisk/jingle.h
URL: http://svn.digium.com/view/asterisk/team/mogorman/asterisk-xmpp/include/asterisk/jingle.h?rev=19702&r1=19701&r2=19702&view=diff
==============================================================================
--- team/mogorman/asterisk-xmpp/include/asterisk/jingle.h (original)
+++ team/mogorman/asterisk-xmpp/include/asterisk/jingle.h Thu Apr 13 00:54:08 2006
@@ -53,24 +53,37 @@
ast_mutex_t lock; /* Channel private lock */
char sid[100];
char from[100];
- struct jingle_candidate *candidates;
+ int capability;
+ struct ast_codec_pref prefs;
+ struct jingle_candidate *theircandidates;
+ char cid_num[80]; /*!< Caller ID num */
+ char cid_name[80]; /*!< Caller ID name */
+ char exten[80]; /* Called extension */
struct ast_channel *owner; /* Master Channel */
struct ast_rtp *rtp; /*!< RTP Session */
+ struct ast_rtp *vrtp;
int jointcapability; /*!< Supported capability at both ends (codecs ) */
int peercapability;
-
struct jingle_pvt *next; /* Next entity */
};
struct jingle {
ASTOBJ_COMPONENTS(struct jingle);
- void *connection;
+ struct jingle_candidate *ourcandidates;
+ struct aji_client *connection;
struct jingle_pvt *p;
struct ast_codec_pref prefs;
+ int amaflags; /*!< AMA Flags */
char user[100];
char context[100];
+ char accountcode[AST_MAX_ACCOUNT_CODE]; /* Account code */
int capability;
+ ast_group_t callgroup; /*!< Call group */
+ ast_group_t pickupgroup; /*!< Pickup group */
+ int callingpres; /*!< Calling presentation */
int allowguest;
+ char language[MAX_LANGUAGE]; /*!< Default language for prompts */
+ char musicclass[MAX_MUSICCLASS];/*!< Music on Hold class */
};
struct jingle_container {
Modified: team/mogorman/asterisk-xmpp/res/res_jabber.c
URL: http://svn.digium.com/view/asterisk/team/mogorman/asterisk-xmpp/res/res_jabber.c?rev=19702&r1=19701&r2=19702&view=diff
==============================================================================
--- team/mogorman/asterisk-xmpp/res/res_jabber.c (original)
+++ team/mogorman/asterisk-xmpp/res/res_jabber.c Thu Apr 13 00:54:08 2006
@@ -286,15 +286,16 @@
ikspak *pak;
pak=iks_packet(node);
- client = (struct aji_client *)malloc(sizeof(struct aji_client));
- memset(client,0,sizeof(struct aji_client));
client = ASTOBJ_REF((struct aji_client *) udata);
if(client->component == AJI_CLIENT) {
switch(type) {
case IKS_NODE_START:
if(client->usetls &&!iks_is_secure(client->p)) {
- iks_start_tls(client->p);
+ if (iks_has_tls())
+ iks_start_tls(client->p);
+ else
+ ast_log(LOG_ERROR, "gnuTLS not installed.\n");
break;
}
if(!client->usesasl) {
@@ -395,11 +396,13 @@
sprintf(buffer2,"%s%s",pak->id,client->password);
ast_sha1_hash(buffer3,buffer2);
ast_verbose("Oh Really... %s\n",buffer2);
- handshake = (char *)malloc((strlen("<handshake></handshake>")+strlen(buffer3)+1)*sizeof(char));
- sprintf(handshake,"<handshake>%s</handshake>",buffer3);
- iks_send_raw(client->p,handshake);
- free(handshake);
- handshake=NULL;
+ handshake = NULL;
+ asprintf(&handshake, "<handshake>%s</handshake>",buffer3);
+ if (handshake) {
+ iks_send_raw(client->p,handshake);
+ free(handshake);
+ handshake=NULL;
+ }
client->state=AJI_CONNECTED;
iks_filter_add_rule (client->f, aji_dinfo_handler, client, IKS_RULE_NS, "http://jabber.org/protocol/disco#info", IKS_RULE_DONE);
iks_filter_add_rule (client->f, aji_ditems_handler, client, IKS_RULE_NS, "http://jabber.org/protocol/disco#items", IKS_RULE_DONE);
@@ -471,12 +474,10 @@
static int aji_register_approve_handler(void *udata,ikspak *pak)
{
- int res=0;
struct aji_client *client;
iks *iq, *query;
- client = (struct aji_client *)malloc(sizeof(struct aji_client));
- memset(client,0,sizeof(struct aji_client));
- client =ASTOBJ_REF((struct aji_client *) udata);
+
+ client = ASTOBJ_REF((struct aji_client *) udata);
iq = iks_new("iq");
query = iks_new("query");
@@ -501,8 +502,7 @@
int res=0;
struct aji_client *client;
char *node = NULL;
- client = (struct aji_client *)malloc(sizeof(struct aji_client));
- memset(client,0,sizeof(struct aji_client));
+
client =ASTOBJ_REF((struct aji_client *) udata);
if(!(node = iks_find_attrib(pak->query,"node"))) {
@@ -534,8 +534,7 @@
int res=0;
struct aji_client *client;
char *node = NULL;
- client = (struct aji_client *)malloc(sizeof(struct aji_client));
- memset(client,0,sizeof(struct aji_client));
+
client =ASTOBJ_REF((struct aji_client *) udata);
if(!(node = iks_find_attrib(pak->query,"node"))) {
iks *iq, *query, *item;
@@ -614,8 +613,7 @@
int res=0;
struct aji_client *client;
char *node= NULL;
- client = (struct aji_client *)malloc(sizeof(struct aji_client));
- memset(client,0,sizeof(struct aji_client));
+
client =ASTOBJ_REF((struct aji_client *) udata);
if(!(node = iks_find_attrib(pak->query,"node"))) {
iks *iq, *query, *identity, *disco, *reg, *commands, *gateway, *version, *vcard, *search;
@@ -871,7 +869,7 @@
int res=0;
struct aji_client *client = ASTOBJ_REF((struct aji_client *) data);
while (res == IKS_OK) {
- res =iks_recv(client->p,1);
+ res = iks_recv(client->p,1);
if(res==IKS_HOOK) {
ast_verbose("JABBER: Got hook event.\n");
break;
@@ -927,9 +925,7 @@
struct aji_client *client;
struct aji_buddy *buddy=NULL;
iks *send;
- client = (struct aji_client *)malloc(sizeof(struct aji_client));
- memset(client,0,sizeof(struct aji_client));
- client =ASTOBJ_REF((struct aji_client *) udata);
+ client = ASTOBJ_REF((struct aji_client *) udata);
ASTOBJ_CONTAINER_TRAVERSE(&client->buddies,1, {
ASTOBJ_RDLOCK(iterator);
if(iterator->btype==AJI_TRANS ) {
@@ -967,9 +963,7 @@
struct aji_client *client;
struct aji_buddy *buddy=NULL;
iks *regquery, *reguser, *regpass, *regiq;
- client = (struct aji_client *)malloc(sizeof(struct aji_client));
- memset(client,0,sizeof(struct aji_client));
- client =ASTOBJ_REF((struct aji_client *) udata);
+ client = ASTOBJ_REF((struct aji_client *) udata);
ASTOBJ_CONTAINER_TRAVERSE(&client->buddies,1, {
ASTOBJ_RDLOCK(iterator);
if(iterator->btype==AJI_TRANS)
@@ -1076,9 +1070,8 @@
iks *x;
struct aji_client *client;
struct aji_buddy *buddy;
- client = (struct aji_client *)malloc(sizeof(struct aji_client));
- memset(client,0,sizeof(struct aji_client));
- client =ASTOBJ_REF((struct aji_client *) udata);
+
+ client = ASTOBJ_REF((struct aji_client *) udata);
ASTOBJ_CONTAINER_TRAVERSE(&client->buddies,1, {
ASTOBJ_RDLOCK(iterator);
@@ -1167,9 +1160,7 @@
int res=0;
struct aji_client *client;
iks *roster;
- client = (struct aji_client *)malloc(sizeof(struct aji_client));
- memset(client,0,sizeof(struct aji_client));
- client =ASTOBJ_REF((struct aji_client *) udata);
+ client = ASTOBJ_REF((struct aji_client *) udata);
if(client->state==AJI_DISCONNECTED) {
client->state=AJI_CONNECTING;
@@ -1204,8 +1195,6 @@
char buffer[41],*handshake;
iksha *sha;
- client = (struct aji_client *)malloc(sizeof(struct aji_client));
- memset(client,0,sizeof(struct aji_client));
client = ASTOBJ_REF((struct aji_client *) udata);
ast_verbose(" so long, state %d\n", client->state);
@@ -1218,11 +1207,14 @@
iks_sha_hash (sha,client->sid,strlen(client->sid),0);
iks_sha_hash (sha, (const unsigned char*)client->password, strlen (client->password), 1);
iks_sha_print (sha, buffer);
- handshake = (char *)malloc((strlen("<handshake></handshake>")+strlen(buffer)+1)*sizeof(char));
- sprintf(handshake,"<handshake>%s</handshake>",buffer);
iks_sha_delete (sha);
- res = iks_send_raw(client->p,handshake);
- free(handshake);
+
+ handshake = NULL;
+ asprintf(&handshake, "<handshake>%s</handshake>",buffer);
+ if (handshake) {
+ res = iks_send_raw(client->p,handshake);
+ free(handshake);
+ }
handshake=NULL;
client->state=AJI_ALMOST;
break;
@@ -1252,22 +1244,38 @@
char *resource;
int connected = 0;
client->p = iks_stream_new(IKS_NS_CLIENT, client,aji_act_hook);
+ if (!client->p) {
+ ast_log(LOG_WARNING, "Failed to create stream for client '%s'!\n", client->name);
+ goto failed;
+ }
client->stack = iks_stack_new(8192,8192);
-
- if(!client->f)
- client->f= iks_filter_new();
- else
+ if (!client->stack) {
+ ast_log(LOG_WARNING, "Failed to allocate stack for client '%s'\n", client->name);
+ goto failedstack;
+ }
+
+ if (client->f)
iks_filter_delete(client->f);
+
+ client->f = iks_filter_new();
+
+ if (!client->f) {
+ ast_log(LOG_WARNING, "Failed to create filter for client '%s'\n", client->name);
+ goto failedfilter;
+ }
iks_set_log_hook(client->p,aji_log_hook);
if(!strchr(client->user,'/')) {
- resource = (char *)malloc(strlen(client->user) + 9); /*+ 9 for asterisk / */
- sprintf(resource,"%s/asterisk", client->user);
- client->jid = iks_id_new(client->stack,resource);
- free(resource);
+ resource = NULL;
+ asprintf(&resource,"%s/asterisk", client->user);
+ if (resource) {
+ client->jid = iks_id_new(client->stack,resource);
+ free(resource);
+ }
} else {
client->jid = iks_id_new(client->stack,client->user);
}
+
connected = iks_connect_via(client->p, client->serverhost, client->port, client->server);
if(connected== IKS_NET_NOCONN)
@@ -1275,6 +1283,17 @@
if(connected == IKS_NET_NODNS)
ast_verbose("JABBER ERROR: No DNS");
return 1;
+
+failedfilter:
+ iks_stack_delete(client->stack);
+ client->stack = NULL;
+
+failedstack:
+ iks_parser_delete(client->p);
+ client->p = NULL;
+
+failed:
+ return -1;
}
/*!
@@ -1594,7 +1613,7 @@
if(strcasecmp(cat, "general")) {
utype = ast_variable_retrieve(cfg, cat, "type");
if(utype) {
- var =ast_variable_browse(cfg, cat);
+ var = ast_variable_browse(cfg, cat);
client = (struct aji_client *) malloc(sizeof(struct aji_client));
memset(client,0,sizeof(struct aji_client));
ASTOBJ_INIT(client);
More information about the asterisk-commits
mailing list