Wed Oct 28 11:45:56 2009

Asterisk developer's documentation


chan_jingle.c File Reference

Jingle Channel Driver. More...

#include "asterisk.h"
#include <sys/socket.h>
#include <fcntl.h>
#include <netdb.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <sys/signal.h>
#include <iksemel.h>
#include <pthread.h>
#include "asterisk/lock.h"
#include "asterisk/channel.h"
#include "asterisk/config.h"
#include "asterisk/module.h"
#include "asterisk/pbx.h"
#include "asterisk/sched.h"
#include "asterisk/io.h"
#include "asterisk/rtp.h"
#include "asterisk/acl.h"
#include "asterisk/callerid.h"
#include "asterisk/file.h"
#include "asterisk/cli.h"
#include "asterisk/app.h"
#include "asterisk/musiconhold.h"
#include "asterisk/manager.h"
#include "asterisk/stringfields.h"
#include "asterisk/utils.h"
#include "asterisk/causes.h"
#include "asterisk/astobj.h"
#include "asterisk/abstract_jb.h"
#include "asterisk/jabber.h"
#include "asterisk/jingle.h"

Include dependency graph for chan_jingle.c:

Go to the source code of this file.

Data Structures

struct  jingle
struct  jingle_candidate
struct  jingle_container
struct  jingle_pvt

Defines

#define FORMAT   "%-30.30s %-30.30s %-15.15s %-5.5s %-5.5s \n"
#define JINGLE_CONFIG   "jingle.conf"

Enumerations

enum  jingle_connect_type { AJI_CONNECT_HOST, AJI_CONNECT_PRFLX, AJI_CONNECT_RELAY, AJI_CONNECT_SRFLX }
enum  jingle_protocol { AJI_PROTOCOL_UDP, AJI_PROTOCOL_SSLTCP }

Functions

static void __reg_module (void)
static void __unreg_module (void)
static void add_codec_to_answer (const struct jingle_pvt *p, int codec, iks *dcodecs)
static struct jinglefind_jingle (char *name, char *connection)
static int jingle_accept_call (struct jingle *client, struct jingle_pvt *p)
static int jingle_action (struct jingle *client, struct jingle_pvt *p, const char *action)
static int jingle_add_candidate (struct jingle *client, ikspak *pak)
static struct jingle_pvtjingle_alloc (struct jingle *client, const char *from, const char *sid)
static int jingle_answer (struct ast_channel *ast)
static int jingle_call (struct ast_channel *ast, char *dest, int timeout)
 Initiate new call, part of PBX interface dest is the dial string.
static int jingle_create_candidates (struct jingle *client, struct jingle_pvt *p, char *sid, char *from)
static int jingle_create_member (char *label, struct ast_variable *var, int allowguest, struct ast_codec_pref prefs, char *context, struct jingle *member)
static int jingle_digit (struct ast_channel *ast, char digit, unsigned int duration)
static int jingle_digit_begin (struct ast_channel *ast, char digit)
static int jingle_digit_end (struct ast_channel *ast, char digit, unsigned int duration)
static char * jingle_do_reload (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 CLI command "jingle reload".
static int jingle_fixup (struct ast_channel *oldchan, struct ast_channel *newchan)
static void jingle_free_candidates (struct jingle_candidate *candidate)
static void jingle_free_pvt (struct jingle *client, struct jingle_pvt *p)
static int jingle_get_codec (struct ast_channel *chan)
static enum ast_rtp_get_result jingle_get_rtp_peer (struct ast_channel *chan, struct ast_rtp **rtp)
static int jingle_handle_dtmf (struct jingle *client, ikspak *pak)
static int jingle_hangup (struct ast_channel *ast)
 Hangup a call through the jingle proxy channel.
static int jingle_hangup_farend (struct jingle *client, ikspak *pak)
static int jingle_indicate (struct ast_channel *ast, int condition, const void *data, size_t datalen)
static int jingle_is_answered (struct jingle *client, ikspak *pak)
static int jingle_load_config (void)
static void jingle_member_destroy (struct jingle *obj)
static struct ast_channeljingle_new (struct jingle *client, struct jingle_pvt *i, int state, const char *title)
 Start new jingle channel.
static int jingle_newcall (struct jingle *client, ikspak *pak)
static int jingle_parser (void *data, ikspak *pak)
static struct ast_framejingle_read (struct ast_channel *ast)
static struct ast_channeljingle_request (const char *type, int format, void *data, int *cause)
 Part of PBX interface.
static int jingle_response (struct jingle *client, ikspak *pak, const char *reasonstr, const char *reasonstr2)
static int jingle_ringing_ack (void *data, ikspak *pak)
static struct ast_framejingle_rtp_read (struct ast_channel *ast, struct jingle_pvt *p)
static int jingle_sendhtml (struct ast_channel *ast, int subclass, const char *data, int datalen)
static int jingle_set_rtp_peer (struct ast_channel *chan, struct ast_rtp *rtp, struct ast_rtp *vrtp, struct ast_rtp *tpeer, int codecs, int nat_active)
static char * jingle_show_channels (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 CLI command "jingle show channels".
static int jingle_transmit_invite (struct jingle_pvt *p)
static int jingle_update_stun (struct jingle *client, struct jingle_pvt *p)
static int jingle_write (struct ast_channel *ast, struct ast_frame *frame)
 Send frame to media channel (rtp).
static int load_module (void)
 Load module into PBX, register channel.
static int reload (void)
 Reload module.
static int unload_module (void)
 Unload the jingle channel from Asterisk.

Variables

static struct ast_module_info __mod_info = { .name = AST_MODULE, .flags = AST_MODFLAG_DEFAULT , .description = "Jingle Channel Driver" , .key = "This paragraph is copyright (c) 2006 by Digium, Inc. \In order for your module to load, it must return this \key via a function called \"key\". Any code which \includes this paragraph must be licensed under the GNU \General Public License version 2 or later (at your \option). In addition to Digium's general reservations \of rights, Digium expressly reserves the right to \allow other parties to license this paragraph under \different terms. Any use of Digium, Inc. trademarks or \logos (including \"Asterisk\" or \"Digium\") without \express written permission of Digium, Inc. is prohibited.\n" , .buildopt_sum = AST_BUILDOPT_SUM, .load = load_module, .unload = unload_module, .reload = reload, }
static struct in_addr __ourip
static const struct
ast_module_info
ast_module_info = &__mod_info
static struct sockaddr_in bindaddr = { 0, }
static struct ast_jb_conf default_jbconf
static const char desc [] = "Jingle Channel"
static char externip [16]
static int global_capability = AST_FORMAT_ULAW | AST_FORMAT_ALAW | AST_FORMAT_GSM | AST_FORMAT_H263
static struct ast_jb_conf global_jbconf
static struct io_contextio
static struct ast_cli_entry jingle_cli []
static struct jingle_container jingle_list
static struct ast_rtp_protocol jingle_rtp
 RTP driver interface.
static struct ast_channel_tech jingle_tech
 PBX interface structure for channel registration.
static ast_mutex_t jinglelock = ((ast_mutex_t) PTHREAD_MUTEX_INITIALIZER )
static struct sched_contextsched
static const char type [] = "Jingle"


Detailed Description

Jingle Channel Driver.

Author:
Matt O'Gorman <mogorman@digium.com>
ExtRef:
Iksemel http://iksemel.jabberstudio.org/

Definition in file chan_jingle.c.


Define Documentation

#define FORMAT   "%-30.30s %-30.30s %-15.15s %-5.5s %-5.5s \n"

#define JINGLE_CONFIG   "jingle.conf"

Definition at line 72 of file chan_jingle.c.

Referenced by jingle_load_config(), and load_module().


Enumeration Type Documentation

Enumerator:
AJI_CONNECT_HOST 
AJI_CONNECT_PRFLX 
AJI_CONNECT_RELAY 
AJI_CONNECT_SRFLX 

Definition at line 89 of file chan_jingle.c.

00089                          {
00090    AJI_CONNECT_HOST,
00091    AJI_CONNECT_PRFLX,
00092    AJI_CONNECT_RELAY,
00093    AJI_CONNECT_SRFLX,
00094 };

Enumerator:
AJI_PROTOCOL_UDP 
AJI_PROTOCOL_SSLTCP 

Definition at line 84 of file chan_jingle.c.

00084                      {
00085    AJI_PROTOCOL_UDP,
00086    AJI_PROTOCOL_SSLTCP,
00087 };


Function Documentation

static void __reg_module ( void   )  [static]

Definition at line 1929 of file chan_jingle.c.

static void __unreg_module ( void   )  [static]

Definition at line 1929 of file chan_jingle.c.

static void add_codec_to_answer ( const struct jingle_pvt p,
int  codec,
iks *  dcodecs 
) [static]

Definition at line 268 of file chan_jingle.c.

References ast_getformatname(), ast_rtp_lookup_code(), format, and jingle_pvt::rtp.

00269 {
00270    char *format = ast_getformatname(codec);
00271 
00272    if (!strcasecmp("ulaw", format)) {
00273       iks *payload_eg711u, *payload_pcmu;
00274       payload_pcmu = iks_new("payload-type");
00275       iks_insert_attrib(payload_pcmu, "id", "0");
00276       iks_insert_attrib(payload_pcmu, "name", "PCMU");
00277       payload_eg711u = iks_new("payload-type");
00278       iks_insert_attrib(payload_eg711u, "id", "100");
00279       iks_insert_attrib(payload_eg711u, "name", "EG711U");
00280       iks_insert_node(dcodecs, payload_pcmu);
00281       iks_insert_node(dcodecs, payload_eg711u);
00282    }
00283    if (!strcasecmp("alaw", format)) {
00284       iks *payload_eg711a;
00285       iks *payload_pcma = iks_new("payload-type");
00286       iks_insert_attrib(payload_pcma, "id", "8");
00287       iks_insert_attrib(payload_pcma, "name", "PCMA");
00288       payload_eg711a = iks_new("payload-type");
00289       iks_insert_attrib(payload_eg711a, "id", "101");
00290       iks_insert_attrib(payload_eg711a, "name", "EG711A");
00291       iks_insert_node(dcodecs, payload_pcma);
00292       iks_insert_node(dcodecs, payload_eg711a);
00293    }
00294    if (!strcasecmp("ilbc", format)) {
00295       iks *payload_ilbc = iks_new("payload-type");
00296       iks_insert_attrib(payload_ilbc, "id", "97");
00297       iks_insert_attrib(payload_ilbc, "name", "iLBC");
00298       iks_insert_node(dcodecs, payload_ilbc);
00299    }
00300    if (!strcasecmp("g723", format)) {
00301       iks *payload_g723 = iks_new("payload-type");
00302       iks_insert_attrib(payload_g723, "id", "4");
00303       iks_insert_attrib(payload_g723, "name", "G723");
00304       iks_insert_node(dcodecs, payload_g723);
00305    }
00306    ast_rtp_lookup_code(p->rtp, 1, codec);
00307 }

static struct jingle* find_jingle ( char *  name,
char *  connection 
) [static, read]

Definition at line 242 of file chan_jingle.c.

References ASTOBJ_CONTAINER_FIND, ASTOBJ_CONTAINER_FIND_FULL, ASTOBJ_CONTAINER_TRAVERSE, ASTOBJ_RDLOCK, ASTOBJ_UNLOCK, and jingle_list.

Referenced by jingle_request().

00243 {
00244    struct jingle *jingle = NULL;
00245 
00246    jingle = ASTOBJ_CONTAINER_FIND(&jingle_list, name);
00247    if (!jingle && strchr(name, '@'))
00248       jingle = ASTOBJ_CONTAINER_FIND_FULL(&jingle_list, name, user,,, strcasecmp);
00249 
00250    if (!jingle) {          
00251       /* guest call */
00252       ASTOBJ_CONTAINER_TRAVERSE(&jingle_list, 1, {
00253          ASTOBJ_RDLOCK(iterator);
00254          if (!strcasecmp(iterator->name, "guest")) {
00255             jingle = iterator;
00256          }
00257          ASTOBJ_UNLOCK(iterator);
00258 
00259          if (jingle)
00260             break;
00261       });
00262 
00263    }
00264    return jingle;
00265 }

static int jingle_accept_call ( struct jingle client,
struct jingle_pvt p 
) [static]

Definition at line 309 of file chan_jingle.c.

References add_codec_to_answer(), ast_aji_increment_mid(), ast_aji_send(), ast_codec_pref_index(), jingle::capability, jingle::connection, jingle_pvt::initiator, aji_client::jid, JINGLE_ACCEPT, JINGLE_AUDIO_RTP_NS, JINGLE_NODE, JINGLE_NS, JINGLE_SID, aji_client::mid, jingle::p, jingle::prefs, jingle_pvt::sid, jingle_pvt::them, and jingle::user.

Referenced by jingle_answer().

00310 {
00311    struct jingle_pvt *tmp = client->p;
00312    struct aji_client *c = client->connection;
00313    iks *iq, *jingle, *dcodecs, *payload_red, *payload_audio, *payload_cn;
00314    int x;
00315    int pref_codec = 0;
00316    int alreadysent = 0;
00317 
00318    if (p->initiator)
00319       return 1;
00320 
00321    iq = iks_new("iq");
00322    jingle = iks_new(JINGLE_NODE);
00323    dcodecs = iks_new("description");
00324    if (iq && jingle && dcodecs) {
00325       iks_insert_attrib(dcodecs, "xmlns", JINGLE_AUDIO_RTP_NS);
00326 
00327       for (x = 0; x < 32; x++) {
00328          if (!(pref_codec = ast_codec_pref_index(&client->prefs, x)))
00329             break;
00330          if (!(client->capability & pref_codec))
00331             continue;
00332          if (alreadysent & pref_codec)
00333             continue;
00334          add_codec_to_answer(p, pref_codec, dcodecs);
00335          alreadysent |= pref_codec;
00336       }
00337       payload_red = iks_new("payload-type");
00338       iks_insert_attrib(payload_red, "id", "117");
00339       iks_insert_attrib(payload_red, "name", "red");
00340       payload_audio = iks_new("payload-type");
00341       iks_insert_attrib(payload_audio, "id", "106");
00342       iks_insert_attrib(payload_audio, "name", "audio/telephone-event");
00343       payload_cn = iks_new("payload-type");
00344       iks_insert_attrib(payload_cn, "id", "13");
00345       iks_insert_attrib(payload_cn, "name", "CN");
00346 
00347 
00348       iks_insert_attrib(iq, "type", "set");
00349       iks_insert_attrib(iq, "to", (p->them) ? p->them : client->user);
00350       iks_insert_attrib(iq, "id", client->connection->mid);
00351       ast_aji_increment_mid(client->connection->mid);
00352 
00353       iks_insert_attrib(jingle, "xmlns", JINGLE_NS);
00354       iks_insert_attrib(jingle, "action", JINGLE_ACCEPT);
00355       iks_insert_attrib(jingle, "initiator", p->initiator ? client->connection->jid->full : p->them);
00356       iks_insert_attrib(jingle, JINGLE_SID, tmp->sid);
00357       iks_insert_node(iq, jingle);
00358       iks_insert_node(jingle, dcodecs);
00359       iks_insert_node(dcodecs, payload_red);
00360       iks_insert_node(dcodecs, payload_audio);
00361       iks_insert_node(dcodecs, payload_cn);
00362 
00363       ast_aji_send(c, iq);
00364 
00365       iks_delete(payload_red);
00366       iks_delete(payload_audio);
00367       iks_delete(payload_cn);
00368       iks_delete(dcodecs);
00369       iks_delete(jingle);
00370       iks_delete(iq);
00371    }
00372    return 1;
00373 }

static int jingle_action ( struct jingle client,
struct jingle_pvt p,
const char *  action 
) [static]

Definition at line 881 of file chan_jingle.c.

References ast_aji_increment_mid(), ast_aji_send(), jingle::connection, jingle_pvt::initiator, aji_client::jid, JINGLE_NS, JINGLE_SID, aji_client::mid, jingle_pvt::sid, and jingle_pvt::them.

Referenced by jingle_hangup().

00882 {
00883    iks *iq, *jingle = NULL;
00884    int res = -1;
00885 
00886    iq = iks_new("iq");
00887    jingle = iks_new("jingle");
00888    
00889    if (iq) {
00890       iks_insert_attrib(iq, "type", "set");
00891       iks_insert_attrib(iq, "from", client->connection->jid->full);
00892       iks_insert_attrib(iq, "to", p->them);
00893       iks_insert_attrib(iq, "id", client->connection->mid);
00894       ast_aji_increment_mid(client->connection->mid);
00895       if (jingle) {
00896          iks_insert_attrib(jingle, "action", action);
00897          iks_insert_attrib(jingle, JINGLE_SID, p->sid);
00898          iks_insert_attrib(jingle, "initiator", p->initiator ? client->connection->jid->full : p->them);
00899          iks_insert_attrib(jingle, "xmlns", JINGLE_NS);
00900 
00901          iks_insert_node(iq, jingle);
00902 
00903          ast_aji_send(client->connection, iq);
00904          res = 0;
00905       }
00906    }
00907    
00908    iks_delete(jingle);
00909    iks_delete(iq);
00910    
00911    return res;
00912 }

static int jingle_add_candidate ( struct jingle client,
ikspak *  pak 
) [static]

Definition at line 1087 of file chan_jingle.c.

References AJI_CONNECT_HOST, AJI_CONNECT_PRFLX, AJI_CONNECT_RELAY, AJI_CONNECT_SRFLX, AJI_PROTOCOL_SSLTCP, AJI_PROTOCOL_UDP, ast_aji_send(), ast_calloc, ast_copy_string(), jingle::connection, jingle_candidate::generation, jingle_candidate::ip, aji_client::jid, JINGLE_NODE, JINGLE_SID, jingle_update_stun(), jingle_pvt::laststun, jingle_candidate::network, jingle_candidate::next, jingle_pvt::next, jingle::p, jingle_pvt::parent, jingle_candidate::password, jingle_candidate::port, jingle_candidate::protocol, jingle_pvt::theircandidates, and jingle_candidate::type.

Referenced by jingle_parser().

01088 {
01089    struct jingle_pvt *p = NULL, *tmp = NULL;
01090    struct aji_client *c = client->connection;
01091    struct jingle_candidate *newcandidate = NULL;
01092    iks *traversenodes = NULL, *receipt = NULL;
01093 
01094    for (tmp = client->p; tmp; tmp = tmp->next) {
01095       if (iks_find_with_attrib(pak->x, JINGLE_NODE, JINGLE_SID, tmp->sid)) {
01096          p = tmp;
01097          break;
01098       }
01099    }
01100 
01101    if (!p)
01102       return -1;
01103 
01104    traversenodes = pak->query;
01105    while(traversenodes) {
01106       if(!strcasecmp(iks_name(traversenodes), "jingle")) {
01107          traversenodes = iks_child(traversenodes);
01108          continue;
01109       }
01110       if(!strcasecmp(iks_name(traversenodes), "content")) {
01111          traversenodes = iks_child(traversenodes);
01112          continue;
01113       }
01114       if(!strcasecmp(iks_name(traversenodes), "transport")) {
01115          traversenodes = iks_child(traversenodes);
01116          continue;
01117       }
01118 
01119       if(!strcasecmp(iks_name(traversenodes), "candidate")) {
01120          newcandidate = ast_calloc(1, sizeof(*newcandidate));
01121          if (!newcandidate)
01122             return 0;
01123          ast_copy_string(newcandidate->ip, iks_find_attrib(traversenodes, "ip"), sizeof(newcandidate->ip));
01124          newcandidate->port = atoi(iks_find_attrib(traversenodes, "port"));
01125          ast_copy_string(newcandidate->password, iks_find_attrib(traversenodes, "pwd"), sizeof(newcandidate->password));
01126          if (!strcasecmp(iks_find_attrib(traversenodes, "protocol"), "udp"))
01127             newcandidate->protocol = AJI_PROTOCOL_UDP;
01128          else if (!strcasecmp(iks_find_attrib(traversenodes, "protocol"), "ssltcp"))
01129             newcandidate->protocol = AJI_PROTOCOL_SSLTCP;
01130          
01131          if (!strcasecmp(iks_find_attrib(traversenodes, "type"), "host"))
01132             newcandidate->type = AJI_CONNECT_HOST;
01133          else if (!strcasecmp(iks_find_attrib(traversenodes, "type"), "prflx"))
01134             newcandidate->type = AJI_CONNECT_PRFLX;
01135          else if (!strcasecmp(iks_find_attrib(traversenodes, "type"), "relay"))
01136             newcandidate->type = AJI_CONNECT_RELAY;
01137          else if (!strcasecmp(iks_find_attrib(traversenodes, "type"), "srflx"))
01138             newcandidate->type = AJI_CONNECT_SRFLX;
01139 
01140          newcandidate->network = atoi(iks_find_attrib(traversenodes, "network"));
01141          newcandidate->generation = atoi(iks_find_attrib(traversenodes, "generation"));
01142          newcandidate->next = NULL;
01143       
01144          newcandidate->next = p->theircandidates;
01145          p->theircandidates = newcandidate;
01146          p->laststun = 0;
01147          jingle_update_stun(p->parent, p);
01148          newcandidate = NULL;
01149       }
01150       traversenodes = iks_next(traversenodes);
01151    }
01152    
01153    receipt = iks_new("iq");
01154    iks_insert_attrib(receipt, "type", "result");
01155    iks_insert_attrib(receipt, "from", c->jid->full);
01156    iks_insert_attrib(receipt, "to", iks_find_attrib(pak->x, "from"));
01157    iks_insert_attrib(receipt, "id", iks_find_attrib(pak->x, "id"));
01158    ast_aji_send(c, receipt);
01159 
01160    iks_delete(receipt);
01161 
01162    return 1;
01163 }

static struct jingle_pvt * jingle_alloc ( struct jingle client,
const char *  from,
const char *  sid 
) [static, read]

Definition at line 739 of file chan_jingle.c.

References ast_calloc, ast_copy_string(), ast_debug, ast_free, ast_log(), ast_mutex_init(), ast_mutex_lock(), ast_mutex_unlock(), ast_random(), ast_rtp_new_with_bindaddr(), ASTOBJ_CONTAINER_FIND, aji_client::buddies, jingle::buddy, aji_resource::cap, jingle::connection, jingle_pvt::exten, jingle_pvt::initiator, aji_version::jingle, jinglelock, jingle_pvt::lock, LOG_ERROR, LOG_WARNING, jingle::name, jingle_pvt::next, aji_resource::next, jingle::p, jingle_pvt::parent, jingle::prefs, jingle_pvt::prefs, aji_resource::resource, aji_buddy::resources, jingle_pvt::rtp, jingle_pvt::sid, and jingle_pvt::them.

Referenced by jingle_newcall(), and jingle_request().

00740 {
00741    struct jingle_pvt *tmp = NULL;
00742    struct aji_resource *resources = NULL;
00743    struct aji_buddy *buddy;
00744    char idroster[200];
00745 
00746    ast_debug(1, "The client is %s for alloc\n", client->name);
00747    if (!sid && !strchr(from, '/')) {   /* I started call! */
00748       if (!strcasecmp(client->name, "guest")) {
00749          buddy = ASTOBJ_CONTAINER_FIND(&client->connection->buddies, from);
00750          if (buddy)
00751             resources = buddy->resources;
00752       } else if (client->buddy)
00753          resources = client->buddy->resources;
00754       while (resources) {
00755          if (resources->cap->jingle) {
00756             break;
00757          }
00758          resources = resources->next;
00759       }
00760       if (resources)
00761          snprintf(idroster, sizeof(idroster), "%s/%s", from, resources->resource);
00762       else {
00763          ast_log(LOG_ERROR, "no jingle capable clients to talk to.\n");
00764          return NULL;
00765       }
00766    }
00767    if (!(tmp = ast_calloc(1, sizeof(*tmp)))) {
00768       return NULL;
00769    }
00770 
00771    memcpy(&tmp->prefs, &client->prefs, sizeof(tmp->prefs));
00772 
00773    if (sid) {
00774       ast_copy_string(tmp->sid, sid, sizeof(tmp->sid));
00775       ast_copy_string(tmp->them, from, sizeof(tmp->them));
00776    } else {
00777       snprintf(tmp->sid, sizeof(tmp->sid), "%08lx%08lx", ast_random(), ast_random());
00778       ast_copy_string(tmp->them, idroster, sizeof(tmp->them));
00779       tmp->initiator = 1;
00780    }
00781    tmp->rtp = ast_rtp_new_with_bindaddr(sched, io, 1, 0, bindaddr.sin_addr);
00782    tmp->parent = client;
00783    if (!tmp->rtp) {
00784       ast_log(LOG_WARNING, "Out of RTP sessions?\n");
00785       ast_free(tmp);
00786       return NULL;
00787    }
00788    ast_copy_string(tmp->exten, "s", sizeof(tmp->exten));
00789    ast_mutex_init(&tmp->lock);
00790    ast_mutex_lock(&jinglelock);
00791    tmp->next = client->p;
00792    client->p = tmp;
00793    ast_mutex_unlock(&jinglelock);
00794    return tmp;
00795 }

static int jingle_answer ( struct ast_channel ast  )  [static]

Definition at line 387 of file chan_jingle.c.

References ast_debug, ast_mutex_lock(), ast_mutex_unlock(), jingle_accept_call(), jingle_pvt::lock, jingle_pvt::parent, and ast_channel::tech_pvt.

00388 {
00389    struct jingle_pvt *p = ast->tech_pvt;
00390    struct jingle *client = p->parent;
00391    int res = 0;
00392 
00393    ast_debug(1, "Answer!\n");
00394    ast_mutex_lock(&p->lock);
00395    jingle_accept_call(client, p);
00396    ast_mutex_unlock(&p->lock);
00397    return res;
00398 }

static int jingle_call ( struct ast_channel ast,
char *  dest,
int  timeout 
) [static]

Initiate new call, part of PBX interface dest is the dial string.

Definition at line 1422 of file chan_jingle.c.

References ast_channel::_state, ast_copy_string(), ast_log(), ast_setstate(), AST_STATE_DOWN, AST_STATE_RESERVED, AST_STATE_RING, jingle_pvt::capability, jingle::connection, aji_client::f, jingle_create_candidates(), jingle_ringing_ack(), jingle_transmit_invite(), jingle_pvt::jointcapability, LOG_WARNING, aji_client::mid, ast_channel::name, jingle_pvt::parent, jingle_pvt::ring, jingle_pvt::ringrule, jingle_pvt::sid, ast_channel::tech_pvt, and jingle_pvt::them.

01423 {
01424    struct jingle_pvt *p = ast->tech_pvt;
01425 
01426    if ((ast->_state != AST_STATE_DOWN) && (ast->_state != AST_STATE_RESERVED)) {
01427       ast_log(LOG_WARNING, "jingle_call called on %s, neither down nor reserved\n", ast->name);
01428       return -1;
01429    }
01430 
01431    ast_setstate(ast, AST_STATE_RING);
01432    p->jointcapability = p->capability;
01433    if (!p->ringrule) {
01434       ast_copy_string(p->ring, p->parent->connection->mid, sizeof(p->ring));
01435       p->ringrule = iks_filter_add_rule(p->parent->connection->f, jingle_ringing_ack, p,
01436                      IKS_RULE_ID, p->ring, IKS_RULE_DONE);
01437    } else
01438       ast_log(LOG_WARNING, "Whoa, already have a ring rule!\n");
01439 
01440    jingle_transmit_invite(p);
01441    jingle_create_candidates(p->parent, p, p->sid, p->them);
01442 
01443    return 0;
01444 }

static int jingle_create_candidates ( struct jingle client,
struct jingle_pvt p,
char *  sid,
char *  from 
) [static]

Definition at line 581 of file chan_jingle.c.

References __ourip, AJI_CONNECT_HOST, AJI_CONNECT_PRFLX, AJI_CONNECT_RELAY, AJI_CONNECT_SRFLX, AJI_PROTOCOL_SSLTCP, AJI_PROTOCOL_UDP, ast_aji_increment_mid(), ast_aji_send(), ast_calloc, ast_copy_string(), ast_find_ourip(), ast_free, ast_inet_ntoa(), ast_log(), ast_random(), ast_rtp_get_us(), ast_strlen_zero(), jingle_candidate::component, jingle::connection, jingle_candidate::foundation, jingle_candidate::generation, inet_aton(), jingle_pvt::initiator, jingle_candidate::ip, aji_client::jid, JINGLE_ICE_UDP_NS, JINGLE_NEGOTIATE, JINGLE_NODE, JINGLE_NS, JINGLE_SID, jingle_pvt::laststun, LOG_ERROR, LOG_NOTICE, LOG_WARNING, aji_client::mid, jingle_candidate::network, jingle_candidate::next, jingle_pvt::next, jingle_pvt::ourcandidates, pass, jingle_candidate::password, jingle_candidate::port, jingle_candidate::priority, jingle_candidate::protocol, jingle_pvt::rtp, jingle_pvt::sid, jingle_candidate::type, and jingle_candidate::ufrag.

Referenced by jingle_call(), and jingle_newcall().

00582 {
00583    struct jingle_candidate *tmp;
00584    struct aji_client *c = client->connection;
00585    struct jingle_candidate *ours1 = NULL, *ours2 = NULL;
00586    struct sockaddr_in sin;
00587    struct sockaddr_in dest;
00588    struct in_addr us;
00589    struct in_addr externaddr;
00590    iks *iq, *jingle, *content, *transport, *candidate;
00591    char component[16], foundation[16], generation[16], network[16], pass[16], port[7], priority[16], user[16];
00592 
00593 
00594    iq = iks_new("iq");
00595    jingle = iks_new(JINGLE_NODE);
00596    content = iks_new("content");
00597    transport = iks_new("transport");
00598    candidate = iks_new("candidate");
00599    if (!iq || !jingle || !content || !transport || !candidate) {
00600       ast_log(LOG_ERROR, "Memory allocation error\n");
00601       goto safeout;
00602    }
00603    ours1 = ast_calloc(1, sizeof(*ours1));
00604    ours2 = ast_calloc(1, sizeof(*ours2));
00605    if (!ours1 || !ours2)
00606       goto safeout;
00607 
00608    iks_insert_node(iq, jingle);
00609    iks_insert_node(jingle, content);
00610    iks_insert_node(content, transport);
00611    iks_insert_node(transport, candidate);
00612 
00613    for (; p; p = p->next) {
00614       if (!strcasecmp(p->sid, sid))
00615          break;
00616    }
00617 
00618    if (!p) {
00619       ast_log(LOG_NOTICE, "No matching jingle session - SID %s!\n", sid);
00620       goto safeout;
00621    }
00622 
00623    ast_rtp_get_us(p->rtp, &sin);
00624    ast_find_ourip(&us, bindaddr);
00625 
00626    /* Setup our first jingle candidate */
00627    ours1->component = 1;
00628    ours1->foundation = (unsigned int)bindaddr.sin_addr.s_addr | AJI_CONNECT_HOST | AJI_PROTOCOL_UDP;
00629    ours1->generation = 0;
00630    ast_copy_string(ours1->ip, ast_inet_ntoa(us), sizeof(ours1->ip));
00631    ours1->network = 0;
00632    ours1->port = ntohs(sin.sin_port);
00633    ours1->priority = 1678246398;
00634    ours1->protocol = AJI_PROTOCOL_UDP;
00635    snprintf(pass, sizeof(pass), "%08lx%08lx", ast_random(), ast_random());
00636    ast_copy_string(ours1->password, pass, sizeof(ours1->password));
00637    ours1->type = AJI_CONNECT_HOST;
00638    snprintf(user, sizeof(user), "%08lx%08lx", ast_random(), ast_random());
00639    ast_copy_string(ours1->ufrag, user, sizeof(ours1->ufrag));
00640    p->ourcandidates = ours1;
00641 
00642    if (!ast_strlen_zero(externip)) {
00643       /* XXX We should really stun for this one not just go with externip XXX */
00644       if (inet_aton(externip, &externaddr))
00645          ast_log(LOG_WARNING, "Invalid extern IP : %s\n", externip);
00646 
00647       ours2->component = 1;
00648       ours2->foundation = (unsigned int)externaddr.s_addr | AJI_CONNECT_PRFLX | AJI_PROTOCOL_UDP;
00649       ours2->generation = 0;
00650       ast_copy_string(ours2->ip, externip, sizeof(ours2->ip));
00651       ours2->network = 0;
00652       ours2->port = ntohs(sin.sin_port);
00653       ours2->priority = 1678246397;
00654       ours2->protocol = AJI_PROTOCOL_UDP;
00655       snprintf(pass, sizeof(pass), "%08lx%08lx", ast_random(), ast_random());
00656       ast_copy_string(ours2->password, pass, sizeof(ours2->password));
00657       ours2->type = AJI_CONNECT_PRFLX;
00658 
00659       snprintf(user, sizeof(user), "%08lx%08lx", ast_random(), ast_random());
00660       ast_copy_string(ours2->ufrag, user, sizeof(ours2->ufrag));
00661       ours1->next = ours2;
00662       ours2 = NULL;
00663    }
00664    ours1 = NULL;
00665    dest.sin_addr = __ourip;
00666    dest.sin_port = sin.sin_port;
00667 
00668 
00669    for (tmp = p->ourcandidates; tmp; tmp = tmp->next) {
00670       snprintf(component, sizeof(component), "%u", tmp->component);
00671       snprintf(foundation, sizeof(foundation), "%u", tmp->foundation);
00672       snprintf(generation, sizeof(generation), "%u", tmp->generation);
00673       snprintf(network, sizeof(network), "%u", tmp->network);
00674       snprintf(port, sizeof(port), "%u", tmp->port);
00675       snprintf(priority, sizeof(priority), "%u", tmp->priority);
00676 
00677       iks_insert_attrib(iq, "from", c->jid->full);
00678       iks_insert_attrib(iq, "to", from);
00679       iks_insert_attrib(iq, "type", "set");
00680       iks_insert_attrib(iq, "id", c->mid);
00681       ast_aji_increment_mid(c->mid);
00682       iks_insert_attrib(jingle, "action", JINGLE_NEGOTIATE);
00683       iks_insert_attrib(jingle, JINGLE_SID, sid);
00684       iks_insert_attrib(jingle, "initiator", (p->initiator) ? c->jid->full : from);
00685       iks_insert_attrib(jingle, "xmlns", JINGLE_NS);
00686       iks_insert_attrib(content, "creator", p->initiator ? "initiator" : "responder");
00687       iks_insert_attrib(content, "name", "asterisk-audio-content");
00688       iks_insert_attrib(transport, "xmlns", JINGLE_ICE_UDP_NS);
00689       iks_insert_attrib(candidate, "component", component);
00690       iks_insert_attrib(candidate, "foundation", foundation);
00691       iks_insert_attrib(candidate, "generation", generation);
00692       iks_insert_attrib(candidate, "ip", tmp->ip);
00693       iks_insert_attrib(candidate, "network", network);
00694       iks_insert_attrib(candidate, "port", port);
00695       iks_insert_attrib(candidate, "priority", priority);
00696       switch (tmp->protocol) {
00697       case AJI_PROTOCOL_UDP:
00698          iks_insert_attrib(candidate, "protocol", "udp");
00699          break;
00700       case AJI_PROTOCOL_SSLTCP:
00701          iks_insert_attrib(candidate, "protocol", "ssltcp");
00702          break;
00703       }
00704       iks_insert_attrib(candidate, "pwd", tmp->password);
00705       switch (tmp->type) {
00706       case AJI_CONNECT_HOST:
00707          iks_insert_attrib(candidate, "type", "host");
00708          break;
00709       case AJI_CONNECT_PRFLX:
00710          iks_insert_attrib(candidate, "type", "prflx");
00711          break;
00712       case AJI_CONNECT_RELAY:
00713          iks_insert_attrib(candidate, "type", "relay");
00714          break;
00715       case AJI_CONNECT_SRFLX:
00716          iks_insert_attrib(candidate, "type", "srflx");
00717          break;
00718       }
00719       iks_insert_attrib(candidate, "ufrag", tmp->ufrag);
00720 
00721       ast_aji_send(c, iq);
00722    }
00723    p->laststun = 0;
00724 
00725 safeout:
00726    if (ours1)
00727       ast_free(ours1);
00728    if (ours2)
00729       ast_free(ours2);
00730    iks_delete(iq);
00731    iks_delete(jingle);
00732    iks_delete(content);
00733    iks_delete(transport);
00734    iks_delete(candidate);
00735 
00736    return 1;
00737 }

static int jingle_create_member ( char *  label,
struct ast_variable var,
int  allowguest,
struct ast_codec_pref  prefs,
char *  context,
struct jingle member 
) [static]

Definition at line 1664 of file chan_jingle.c.

References jingle::allowguest, ast_aji_get_client(), ast_copy_string(), ast_log(), ast_parse_allow_disallow(), ASTOBJ_CONTAINER_FIND, aji_client::buddies, jingle::buddy, jingle::capability, jingle::connection, jingle::context, aji_client::f, JINGLE_NS, jingle_parser(), LOG_ERROR, LOG_WARNING, ast_variable::name, jingle::name, ast_variable::next, jingle_candidate::next, jingle::prefs, jingle::user, and ast_variable::value.

Referenced by jingle_load_config().

01667 {
01668    struct aji_client *client;
01669 
01670    if (!member)
01671       ast_log(LOG_WARNING, "Out of memory.\n");
01672 
01673    ast_copy_string(member->name, label, sizeof(member->name));
01674    ast_copy_string(member->user, label, sizeof(member->user));
01675    ast_copy_string(member->context, context, sizeof(member->context));
01676    member->allowguest = allowguest;
01677    member->prefs = prefs;
01678    while (var) {
01679 #if 0
01680       struct jingle_candidate *candidate = NULL;
01681 #endif
01682       if (!strcasecmp(var->name, "username"))
01683          ast_copy_string(member->user, var->value, sizeof(member->user));
01684       else if (!strcasecmp(var->name, "disallow"))
01685          ast_parse_allow_disallow(&member->prefs, &member->capability, var->value, 0);
01686       else if (!strcasecmp(var->name, "allow"))
01687          ast_parse_allow_disallow(&member->prefs, &member->capability, var->value, 1);
01688       else if (!strcasecmp(var->name, "context"))
01689          ast_copy_string(member->context, var->value, sizeof(member->context));
01690 #if 0
01691       else if (!strcasecmp(var->name, "candidate")) {
01692          candidate = jingle_create_candidate(var->value);
01693          if (candidate) {
01694             candidate->next = member->ourcandidates;
01695             member->ourcandidates = candidate;
01696          }
01697       }
01698 #endif
01699       else if (!strcasecmp(var->name, "connection")) {
01700          if ((client = ast_aji_get_client(var->value))) {
01701             member->connection = client;
01702             iks_filter_add_rule(client->f, jingle_parser, member,
01703                       IKS_RULE_TYPE, IKS_PAK_IQ,
01704                       IKS_RULE_FROM_PARTIAL, member->user,
01705                       IKS_RULE_NS, JINGLE_NS,
01706                       IKS_RULE_DONE);
01707          } else {
01708             ast_log(LOG_ERROR, "connection referenced not found!\n");
01709             return 0;
01710          }
01711       }
01712       var = var->next;
01713    }
01714    if (member->connection && member->user)
01715       member->buddy = ASTOBJ_CONTAINER_FIND(&member->connection->buddies, member->user);
01716    else {
01717       ast_log(LOG_ERROR, "No Connection or Username!\n");
01718    }
01719    return 1;
01720 }

static int jingle_digit ( struct ast_channel ast,
char  digit,
unsigned int  duration 
) [static]

Definition at line 1282 of file chan_jingle.c.

References ast_aji_increment_mid(), ast_aji_send(), AST_FRAME_DTMF_BEGIN, AST_FRAME_DTMF_END, ast_log(), ast_mutex_lock(), ast_mutex_unlock(), jingle::connection, ast_channel::dtmff, ast_frame::frametype, jingle_pvt::initiator, aji_client::jid, JINGLE_DTMF_NS, JINGLE_NS, jingle_pvt::lock, LOG_ERROR, aji_client::mid, jingle_pvt::parent, jingle_pvt::sid, ast_channel::tech_pvt, and jingle_pvt::them.

Referenced by jingle_digit_begin(), and jingle_digit_end().

01283 {
01284    struct jingle_pvt *p = ast->tech_pvt;
01285    struct jingle *client = p->parent;
01286    iks *iq, *jingle, *dtmf;
01287    char buffer[2] = {digit, '\0'};
01288    iq = iks_new("iq");
01289    jingle = iks_new("jingle");
01290    dtmf = iks_new("dtmf");
01291    if(!iq || !jingle || !dtmf) {
01292       iks_delete(iq);
01293       iks_delete(jingle);
01294       iks_delete(dtmf);
01295       ast_log(LOG_ERROR, "Did not send dtmf do to memory issue\n");
01296       return -1;
01297    }
01298 
01299    iks_insert_attrib(iq, "type", "set");
01300    iks_insert_attrib(iq, "to", p->them);
01301    iks_insert_attrib(iq, "from", client->connection->jid->full);
01302    iks_insert_attrib(iq, "id", client->connection->mid);
01303    ast_aji_increment_mid(client->connection->mid);
01304    iks_insert_attrib(jingle, "xmlns", JINGLE_NS);
01305    iks_insert_attrib(jingle, "action", "session-info");
01306    iks_insert_attrib(jingle, "initiator", p->initiator ? client->connection->jid->full : p->them);
01307    iks_insert_attrib(jingle, "sid", p->sid);
01308    iks_insert_attrib(dtmf, "xmlns", JINGLE_DTMF_NS);
01309    iks_insert_attrib(dtmf, "code", buffer);
01310    iks_insert_node(iq, jingle);
01311    iks_insert_node(jingle, dtmf);
01312 
01313    ast_mutex_lock(&p->lock);
01314    if (ast->dtmff.frametype == AST_FRAME_DTMF_BEGIN || duration == 0) {
01315       iks_insert_attrib(dtmf, "action", "button-down");
01316    } else if (ast->dtmff.frametype == AST_FRAME_DTMF_END || duration != 0) {
01317       iks_insert_attrib(dtmf, "action", "button-up");
01318    }
01319    ast_aji_send(client->connection, iq);
01320 
01321    iks_delete(iq);
01322    iks_delete(jingle);
01323    iks_delete(dtmf);
01324    ast_mutex_unlock(&p->lock);
01325    return 0;
01326 }

static int jingle_digit_begin ( struct ast_channel ast,
char  digit 
) [static]

Definition at line 1328 of file chan_jingle.c.

References jingle_digit().

01329 {
01330    return jingle_digit(chan, digit, 0);
01331 }

static int jingle_digit_end ( struct ast_channel ast,
char  digit,
unsigned int  duration 
) [static]

Definition at line 1333 of file chan_jingle.c.

References jingle_digit().

01334 {
01335    return jingle_digit(ast, digit, duration);
01336 }

static char * jingle_do_reload ( struct ast_cli_entry e,
int  cmd,
struct ast_cli_args a 
) [static]

CLI command "jingle reload".

Definition at line 1575 of file chan_jingle.c.

References CLI_GENERATE, CLI_INIT, CLI_SUCCESS, ast_cli_entry::command, and ast_cli_entry::usage.

01576 {
01577    switch (cmd) {
01578    case CLI_INIT:
01579       e->command = "jingle reload";
01580       e->usage =
01581          "Usage: jingle reload\n"
01582          "       Reload jingle channel driver.\n";
01583       return NULL;
01584    case CLI_GENERATE:
01585       return NULL;
01586    }  
01587    
01588    return CLI_SUCCESS;
01589 }

static int jingle_fixup ( struct ast_channel oldchan,
struct ast_channel newchan 
) [static]

Definition at line 1248 of file chan_jingle.c.

References ast_mutex_lock(), ast_mutex_unlock(), jingle_pvt::lock, jingle_pvt::owner, and ast_channel::tech_pvt.

01249 {
01250    struct jingle_pvt *p = newchan->tech_pvt;
01251    ast_mutex_lock(&p->lock);
01252 
01253    if ((p->owner != oldchan)) {
01254       ast_mutex_unlock(&p->lock);
01255       return -1;
01256    }
01257    if (p->owner == oldchan)
01258       p->owner = newchan;
01259    ast_mutex_unlock(&p->lock);
01260    return 0;
01261 }

static void jingle_free_candidates ( struct jingle_candidate candidate  )  [static]

Definition at line 914 of file chan_jingle.c.

References ast_free, last, and jingle_candidate::next.

Referenced by jingle_free_pvt(), and jingle_load_config().

00915 {
00916    struct jingle_candidate *last;
00917    while (candidate) {
00918       last = candidate;
00919       candidate = candidate->next;
00920       ast_free(last);
00921    }
00922 }

static void jingle_free_pvt ( struct jingle client,
struct jingle_pvt p 
) [static]

Definition at line 924 of file chan_jingle.c.

References ast_free, ast_log(), ast_rtp_destroy(), jingle::connection, aji_client::f, jingle_free_candidates(), LOG_WARNING, jingle_pvt::next, jingle_pvt::owner, jingle::p, jingle_pvt::parent, jingle_pvt::ringrule, jingle_pvt::rtp, jingle_pvt::theircandidates, and jingle_pvt::vrtp.

Referenced by jingle_hangup(), and jingle_newcall().

00925 {
00926    struct jingle_pvt *cur, *prev = NULL;
00927    cur = client->p;
00928    while (cur) {
00929       if (cur == p) {
00930          if (prev)
00931             prev->next = p->next;
00932          else
00933             client->p = p->next;
00934          break;
00935       }
00936       prev = cur;
00937       cur = cur->next;
00938    }
00939    if (p->ringrule)
00940       iks_filter_remove_rule(p->parent->connection->f, p->ringrule);
00941    if (p->owner)
00942       ast_log(LOG_WARNING, "Uh oh, there's an owner, this is going to be messy.\n");
00943    if (p->rtp)
00944       ast_rtp_destroy(p->rtp);
00945    if (p->vrtp)
00946       ast_rtp_destroy(p->vrtp);
00947    jingle_free_candidates(p->theircandidates);
00948    ast_free(p);
00949 }

static int jingle_get_codec ( struct ast_channel chan  )  [static]

Definition at line 418 of file chan_jingle.c.

References jingle_pvt::peercapability, and ast_channel::tech_pvt.

00419 {
00420    struct jingle_pvt *p = chan->tech_pvt;
00421    return p->peercapability;
00422 }

static enum ast_rtp_get_result jingle_get_rtp_peer ( struct ast_channel chan,
struct ast_rtp **  rtp 
) [static]

Definition at line 400 of file chan_jingle.c.

References ast_mutex_lock(), ast_mutex_unlock(), AST_RTP_GET_FAILED, AST_RTP_TRY_PARTIAL, jingle_pvt::lock, jingle_pvt::rtp, and ast_channel::tech_pvt.

00401 {
00402    struct jingle_pvt *p = chan->tech_pvt;
00403    enum ast_rtp_get_result res = AST_RTP_GET_FAILED;
00404 
00405    if (!p)
00406       return res;
00407 
00408    ast_mutex_lock(&p->lock);
00409    if (p->rtp) {
00410       *rtp = p->rtp;
00411       res = AST_RTP_TRY_PARTIAL;
00412    }
00413    ast_mutex_unlock(&p->lock);
00414 
00415    return res;
00416 }

static int jingle_handle_dtmf ( struct jingle client,
ikspak *  pak 
) [static]

Definition at line 496 of file chan_jingle.c.

References AST_FRAME_DTMF, AST_FRAME_DTMF_BEGIN, AST_FRAME_DTMF_END, ast_log(), ast_queue_frame(), ast_verbose(), JINGLE_NODE, jingle_response(), JINGLE_SID, LOG_NOTICE, jingle_pvt::next, jingle_pvt::owner, jingle::p, jingle_pvt::sid, and ast_frame::subclass.

Referenced by jingle_parser().

00497 {
00498    struct jingle_pvt *tmp;
00499    iks *dtmfnode = NULL, *dtmfchild = NULL;
00500    char *dtmf;
00501    /* Make sure our new call doesn't exist yet */
00502    for (tmp = client->p; tmp; tmp = tmp->next) {
00503       if (iks_find_with_attrib(pak->x, JINGLE_NODE, JINGLE_SID, tmp->sid))
00504          break;
00505    }
00506 
00507    if (tmp) {
00508       if(iks_find_with_attrib(pak->x, "dtmf-method", "method", "rtp")) {
00509          jingle_response(client,pak,
00510                "feature-not-implemented xmlns='urn:ietf:params:xml:ns:xmpp-stanzas'",
00511                "unsupported-dtmf-method xmlns='http://www.xmpp.org/extensions/xep-0181.html#ns-errors'");
00512          return -1;
00513       }
00514       if ((dtmfnode = iks_find(pak->x, "dtmf"))) {
00515          if((dtmf = iks_find_attrib(dtmfnode, "code"))) {
00516             if(iks_find_with_attrib(pak->x, "dtmf", "action", "button-up")) {
00517                struct ast_frame f = {AST_FRAME_DTMF_BEGIN, };
00518                f.subclass = dtmf[0];
00519                ast_queue_frame(tmp->owner, &f);
00520                ast_verbose("JINGLE! DTMF-relay event received: %c\n", f.subclass);
00521             } else if(iks_find_with_attrib(pak->x, "dtmf", "action", "button-down")) {
00522                struct ast_frame f = {AST_FRAME_DTMF_END, };
00523                f.subclass = dtmf[0];
00524                ast_queue_frame(tmp->owner, &f);
00525                ast_verbose("JINGLE! DTMF-relay event received: %c\n", f.subclass);
00526             } else if(iks_find_attrib(pak->x, "dtmf")) { /* 250 millasecond default */
00527                struct ast_frame f = {AST_FRAME_DTMF, };
00528                f.subclass = dtmf[0];
00529                ast_queue_frame(tmp->owner, &f);
00530                ast_verbose("JINGLE! DTMF-relay event received: %c\n", f.subclass);
00531             }
00532          }
00533       } else if ((dtmfnode = iks_find_with_attrib(pak->x, JINGLE_NODE, "action", "session-info"))) {
00534          if((dtmfchild = iks_find(dtmfnode, "dtmf"))) {
00535             if((dtmf = iks_find_attrib(dtmfchild, "code"))) {
00536                if(iks_find_with_attrib(dtmfnode, "dtmf", "action", "button-up")) {
00537                   struct ast_frame f = {AST_FRAME_DTMF_END, };
00538                   f.subclass = dtmf[0];
00539                   ast_queue_frame(tmp->owner, &f);
00540                   ast_verbose("JINGLE! DTMF-relay event received: %c\n", f.subclass);
00541                } else if(iks_find_with_attrib(dtmfnode, "dtmf", "action", "button-down")) {
00542                   struct ast_frame f = {AST_FRAME_DTMF_BEGIN, };
00543                   f.subclass = dtmf[0];
00544                   ast_queue_frame(tmp->owner, &f);
00545                   ast_verbose("JINGLE! DTMF-relay event received: %c\n", f.subclass);
00546                }
00547             }
00548          }
00549       }
00550       jingle_response(client, pak, NULL, NULL);
00551       return 1;
00552    } else
00553       ast_log(LOG_NOTICE, "Whoa, didn't find call!\n");
00554 
00555    jingle_response(client, pak, NULL, NULL);
00556    return 1;
00557 }

static int jingle_hangup ( struct ast_channel ast  )  [static]

Hangup a call through the jingle proxy channel.

Definition at line 1447 of file chan_jingle.c.

References jingle_pvt::alreadygone, ast_mutex_lock(), ast_mutex_unlock(), jingle_action(), jingle_free_pvt(), JINGLE_TERMINATE, jingle_pvt::lock, jingle_pvt::owner, jingle_pvt::parent, and ast_channel::tech_pvt.

01448 {
01449    struct jingle_pvt *p = ast->tech_pvt;
01450    struct jingle *client;
01451 
01452    ast_mutex_lock(&p->lock);
01453    client = p->parent;
01454    p->owner = NULL;
01455    ast->tech_pvt = NULL;
01456    if (!p->alreadygone)
01457       jingle_action(client, p, JINGLE_TERMINATE);
01458    ast_mutex_unlock(&p->lock);
01459 
01460    jingle_free_pvt(client, p);
01461 
01462    return 0;
01463 }

static int jingle_hangup_farend ( struct jingle client,
ikspak *  pak 
) [static]

Definition at line 560 of file chan_jingle.c.

References jingle_pvt::alreadygone, ast_debug, ast_log(), ast_queue_hangup(), JINGLE_NODE, jingle_response(), JINGLE_SID, LOG_NOTICE, jingle::name, jingle_pvt::next, jingle_pvt::owner, jingle::p, and jingle_pvt::sid.

Referenced by jingle_parser().

00561 {
00562    struct jingle_pvt *tmp;
00563 
00564    ast_debug(1, "The client is %s\n", client->name);
00565    /* Make sure our new call doesn't exist yet */
00566    for (tmp = client->p; tmp; tmp = tmp->next) {
00567       if (iks_find_with_attrib(pak->x, JINGLE_NODE, JINGLE_SID, tmp->sid))
00568          break;
00569    }
00570 
00571    if (tmp) {
00572       tmp->alreadygone = 1;
00573       if (tmp->owner)
00574          ast_queue_hangup(tmp->owner);
00575    } else
00576       ast_log(LOG_NOTICE, "Whoa, didn't find call!\n");
00577    jingle_response(client, pak, NULL, NULL);
00578    return 1;
00579 }

static int jingle_indicate ( struct ast_channel ast,
int  condition,
const void *  data,
size_t  datalen 
) [static]

Definition at line 1263 of file chan_jingle.c.

References AST_CONTROL_HOLD, AST_CONTROL_UNHOLD, ast_log(), ast_moh_start(), ast_moh_stop(), and LOG_NOTICE.

01264 {
01265    int res = 0;
01266 
01267    switch (condition) {
01268    case AST_CONTROL_HOLD:
01269       ast_moh_start(ast, data, NULL);
01270       break;
01271    case AST_CONTROL_UNHOLD:
01272       ast_moh_stop(ast);
01273       break;
01274    default:
01275       ast_log(LOG_NOTICE, "Don't know how to indicate condition '%d'\n", condition);
01276       res = -1;
01277    }
01278 
01279    return res;
01280 }

static int jingle_is_answered ( struct jingle client,
ikspak *  pak 
) [static]

Definition at line 476 of file chan_jingle.c.

References AST_CONTROL_ANSWER, ast_debug, ast_log(), ast_queue_control(), JINGLE_NODE, jingle_response(), JINGLE_SID, LOG_NOTICE, jingle::name, jingle_pvt::next, jingle_pvt::owner, jingle::p, and jingle_pvt::sid.

Referenced by jingle_parser().

00477 {
00478    struct jingle_pvt *tmp;
00479 
00480    ast_debug(1, "The client is %s\n", client->name);
00481    /* Make sure our new call doesn't exist yet */
00482    for (tmp = client->p; tmp; tmp = tmp->next) {
00483       if (iks_find_with_attrib(pak->x, JINGLE_NODE, JINGLE_SID, tmp->sid))
00484          break;
00485    }
00486 
00487    if (tmp) {
00488       if (tmp->owner)
00489          ast_queue_control(tmp->owner, AST_CONTROL_ANSWER);
00490    } else
00491       ast_log(LOG_NOTICE, "Whoa, didn't find call!\n");
00492    jingle_response(client, pak, NULL, NULL);
00493    return 1;
00494 }

static int jingle_load_config ( void   )  [static]

Definition at line 1722 of file chan_jingle.c.

References jingle::allowguest, ast_aji_get_clients(), ast_calloc, ast_category_browse(), ast_config_load, ast_copy_string(), ast_gethostbyname(), ast_jb_read_conf(), ast_log(), ast_parse_allow_disallow(), ast_true(), ast_variable_browse(), ast_variable_retrieve(), ASTOBJ_CONTAINER_LINK, ASTOBJ_CONTAINER_TRAVERSE, ASTOBJ_INIT, ASTOBJ_UNLOCK, ASTOBJ_UNREF, ASTOBJ_WRLOCK, jingle::capability, clients, jingle::connection, jingle::context, context, global_jbconf, hp, JINGLE_CONFIG, jingle_create_member(), JINGLE_DTMF_NS, jingle_free_candidates(), jingle_list, jingle_member_destroy(), JINGLE_NS, jingle_parser(), LOG_WARNING, jingle::name, ast_variable::name, ast_variable::next, jingle::prefs, jingle::user, ast_variable::value, and var.

Referenced by load_module().

01723 {
01724    char *cat = NULL;
01725    struct ast_config *cfg = NULL;
01726    char context[100];
01727    int allowguest = 1;
01728    struct ast_variable *var;
01729    struct jingle *member;
01730    struct hostent *hp;
01731    struct ast_hostent ahp;
01732    struct ast_codec_pref prefs;
01733    struct aji_client_container *clients;
01734    struct jingle_candidate *global_candidates = NULL;
01735    struct ast_flags config_flags = { 0 };
01736 
01737    cfg = ast_config_load(JINGLE_CONFIG, config_flags);
01738    if (!cfg)
01739       return 0;
01740 
01741    /* Copy the default jb config over global_jbconf */
01742    memcpy(&global_jbconf, &default_jbconf, sizeof(struct ast_jb_conf));
01743 
01744    cat = ast_category_browse(cfg, NULL);
01745    for (var = ast_variable_browse(cfg, "general"); var; var = var->next) {
01746       /* handle jb conf */
01747       if (!ast_jb_read_conf(&global_jbconf, var->name, var->value))
01748          continue;
01749 
01750       if (!strcasecmp(var->name, "allowguest"))
01751          allowguest =
01752             (ast_true(ast_variable_retrieve(cfg, "general", "allowguest"))) ? 1 : 0;
01753       else if (!strcasecmp(var->name, "disallow"))
01754          ast_parse_allow_disallow(&prefs, &global_capability, var->value, 0);
01755       else if (!strcasecmp(var->name, "allow"))
01756          ast_parse_allow_disallow(&prefs, &global_capability, var->value, 1);
01757       else if (!strcasecmp(var->name, "context"))
01758          ast_copy_string(context, var->value, sizeof(context));
01759       else if (!strcasecmp(var->name, "externip"))
01760          ast_copy_string(externip, var->value, sizeof(externip));
01761       else if (!strcasecmp(var->name, "bindaddr")) {
01762          if (!(hp = ast_gethostbyname(var->value, &ahp))) {
01763             ast_log(LOG_WARNING, "Invalid address: %s\n", var->value);
01764          } else {
01765             memcpy(&bindaddr.sin_addr, hp->h_addr, sizeof(bindaddr.sin_addr));
01766          }
01767       }
01768 /*  Idea to allow for custom candidates  */
01769 /*
01770       else if (!strcasecmp(var->name, "candidate")) {
01771          candidate = jingle_create_candidate(var->value);
01772          if (candidate) {
01773             candidate->next = global_candidates;
01774             global_candidates = candidate;
01775          }
01776       }
01777 */
01778    }
01779    while (cat) {
01780       if (strcasecmp(cat, "general")) {
01781          var = ast_variable_browse(cfg, cat);
01782          member = ast_calloc(1, sizeof(*member));
01783          ASTOBJ_INIT(member);
01784          ASTOBJ_WRLOCK(member);
01785          if (!strcasecmp(cat, "guest")) {
01786             ast_copy_string(member->name, "guest", sizeof(member->name));
01787             ast_copy_string(member->user, "guest", sizeof(member->user));
01788             ast_copy_string(member->context, context, sizeof(member->context));
01789             member->allowguest = allowguest;
01790             member->prefs = prefs;
01791             while (var) {
01792                if (!strcasecmp(var->name, "disallow"))
01793                   ast_parse_allow_disallow(&member->prefs, &member->capability,
01794                                      var->value, 0);
01795                else if (!strcasecmp(var->name, "allow"))
01796                   ast_parse_allow_disallow(&member->prefs, &member->capability,
01797                                      var->value, 1);
01798                else if (!strcasecmp(var->name, "context"))
01799                   ast_copy_string(member->context, var->value,
01800                               sizeof(member->context));
01801 /*  Idea to allow for custom candidates  */
01802 /*
01803                else if (!strcasecmp(var->name, "candidate")) {
01804                   candidate = jingle_create_candidate(var->value);
01805                   if (candidate) {
01806                      candidate->next = member->ourcandidates;
01807                      member->ourcandidates = candidate;
01808                   }
01809                }
01810 */
01811                var = var->next;
01812             }
01813             ASTOBJ_UNLOCK(member);
01814             clients = ast_aji_get_clients();
01815             if (clients) {
01816                ASTOBJ_CONTAINER_TRAVERSE(clients, 1, {
01817                   ASTOBJ_WRLOCK(iterator);
01818                   ASTOBJ_WRLOCK(member);
01819                   member->connection = NULL;
01820                   iks_filter_add_rule(iterator->f, jingle_parser, member, IKS_RULE_TYPE, IKS_PAK_IQ, IKS_RULE_NS, JINGLE_NS, IKS_RULE_DONE);
01821                   iks_filter_add_rule(iterator->f, jingle_parser, member, IKS_RULE_TYPE, IKS_PAK_IQ, IKS_RULE_NS, JINGLE_DTMF_NS, IKS_RULE_DONE);
01822                   ASTOBJ_UNLOCK(member);
01823                   ASTOBJ_UNLOCK(iterator);
01824                });
01825                ASTOBJ_CONTAINER_LINK(&jingle_list, member);
01826             } else {
01827                ASTOBJ_UNLOCK(member);
01828                ASTOBJ_UNREF(member, jingle_member_destroy);
01829             }
01830          } else {
01831             ASTOBJ_UNLOCK(member);
01832             if (jingle_create_member(cat, var, allowguest, prefs, context, member))
01833                ASTOBJ_CONTAINER_LINK(&jingle_list, member);
01834             ASTOBJ_UNREF(member, jingle_member_destroy);
01835          }
01836       }
01837       cat = ast_category_browse(cfg, cat);
01838    }
01839    jingle_free_candidates(global_candidates);
01840    return 1;
01841 }

static void jingle_member_destroy ( struct jingle obj  )  [static]

Definition at line 237 of file chan_jingle.c.

References ast_free.

Referenced by jingle_load_config(), jingle_parser(), and unload_module().

00238 {
00239    ast_free(obj);
00240 }

static struct ast_channel* jingle_new ( struct jingle client,
struct jingle_pvt i,
int  state,
const char *  title 
) [static, read]

Start new jingle channel.

Definition at line 798 of file chan_jingle.c.

References accountcode, jingle::accountcode, ast_channel::adsicpe, ast_channel::amaflags, jingle::amaflags, AST_ADSI_UNAVAILABLE, ast_best_codec(), AST_CAUSE_SWITCH_CONGESTION, ast_channel_alloc, ast_channel_set_fd(), ast_codec_choose(), ast_copy_string(), AST_FORMAT_VIDEO_MASK, ast_hangup(), ast_jb_configure(), ast_log(), ast_pbx_start(), ast_random(), ast_rtcp_fd(), ast_rtp_codec_setpref(), ast_rtp_fd(), AST_STATE_DOWN, AST_STATE_RING, ast_strdup, ast_string_field_set, ast_strlen_zero(), jingle::callgroup, ast_channel::callgroup, jingle::callingpres, jingle_pvt::capability, ast_channel::cid, ast_callerid::cid_ani, ast_callerid::cid_dnid, jingle_pvt::cid_name, jingle_pvt::cid_num, ast_callerid::cid_pres, jingle::context, ast_channel::context, jingle_pvt::exten, ast_channel::exten, global_jbconf, ast_channel::hangupcause, jingle_pvt::jointcapability, language, jingle::language, LOG_WARNING, musicclass, jingle::musicclass, ast_channel::name, ast_channel::nativeformats, jingle_pvt::owner, jingle::pickupgroup, ast_channel::pickupgroup, jingle_pvt::prefs, ast_channel::priority, ast_channel::rawreadformat, ast_channel::rawwriteformat, ast_channel::readformat, ast_channel::rings, jingle_pvt::rtp, str, ast_channel::tech, ast_channel::tech_pvt, jingle_pvt::them, jingle_pvt::vrtp, and ast_channel::writeformat.

Referenced by jingle_newcall(), and jingle_request().

00799 {
00800    struct ast_channel *tmp;
00801    int fmt;
00802    int what;
00803    const char *str;
00804 
00805    if (title)
00806       str = title;
00807    else
00808       str = i->them;
00809    tmp = ast_channel_alloc(1, state, i->cid_num, i->cid_name, "", "", "", 0, "Jingle/%s-%04lx", str, ast_random() & 0xffff);
00810    if (!tmp) {
00811       ast_log(LOG_WARNING, "Unable to allocate Jingle channel structure!\n");
00812       return NULL;
00813    }
00814    tmp->tech = &jingle_tech;
00815 
00816    /* Select our native format based on codec preference until we receive
00817       something from another device to the contrary. */
00818    if (i->jointcapability)
00819       what = i->jointcapability;
00820    else if (i->capability)
00821       what = i->capability;
00822    else
00823       what = global_capability;
00824 
00825    /* Set Frame packetization */
00826    if (i->rtp)
00827       ast_rtp_codec_setpref(i->rtp, &i->prefs);
00828 
00829    tmp->nativeformats = ast_codec_choose(&i->prefs, what, 1) | (i->jointcapability & AST_FORMAT_VIDEO_MASK);
00830    fmt = ast_best_codec(tmp->nativeformats);
00831 
00832    if (i->rtp) {
00833       ast_channel_set_fd(tmp, 0, ast_rtp_fd(i->rtp));
00834       ast_channel_set_fd(tmp, 1, ast_rtcp_fd(i->rtp));
00835    }
00836    if (i->vrtp) {
00837       ast_channel_set_fd(tmp, 2, ast_rtp_fd(i->vrtp));
00838       ast_channel_set_fd(tmp, 3, ast_rtcp_fd(i->vrtp));
00839    }
00840    if (state == AST_STATE_RING)
00841       tmp->rings = 1;
00842    tmp->adsicpe = AST_ADSI_UNAVAILABLE;
00843    tmp->writeformat = fmt;
00844    tmp->rawwriteformat = fmt;
00845    tmp->readformat = fmt;
00846    tmp->rawreadformat = fmt;
00847    tmp->tech_pvt = i;
00848 
00849    tmp->callgroup = client->callgroup;
00850    tmp->pickupgroup = client->pickupgroup;
00851    tmp->cid.cid_pres = client->callingpres;
00852    if (!ast_strlen_zero(client->accountcode))
00853       ast_string_field_set(tmp, accountcode, client->accountcode);
00854    if (client->amaflags)
00855       tmp->amaflags = client->amaflags;
00856    if (!ast_strlen_zero(client->language))
00857       ast_string_field_set(tmp, language, client->language);
00858    if (!ast_strlen_zero(client->musicclass))
00859       ast_string_field_set(tmp, musicclass, client->musicclass);
00860    i->owner = tmp;
00861    ast_copy_string(tmp->context, client->context, sizeof(tmp->context));
00862    ast_copy_string(tmp->exten, i->exten, sizeof(tmp->exten));
00863    /* Don't use ast_set_callerid() here because it will
00864     * generate an unnecessary NewCallerID event  */
00865    tmp->cid.cid_ani = ast_strdup(i->cid_num);
00866    if (!ast_strlen_zero(i->exten) && strcmp(i->exten, "s"))
00867       tmp->cid.cid_dnid = ast_strdup(i->exten);
00868    tmp->priority = 1;
00869    if (i->rtp)
00870       ast_jb_configure(tmp, &global_jbconf);
00871    if (state != AST_STATE_DOWN && ast_pbx_start(tmp)) {
00872       ast_log(LOG_WARNING, "Unable to start PBX on %s\n", tmp->name);
00873       tmp->hangupcause = AST_CAUSE_SWITCH_CONGESTION;
00874       ast_hangup(tmp);
00875       tmp = NULL;
00876    }
00877 
00878    return tmp;
00879 }

static int jingle_newcall ( struct jingle client,
ikspak *  pak 
) [static]

Definition at line 952 of file chan_jingle.c.

References ast_aji_get_client(), ast_copy_string(), ast_log(), ast_mutex_lock(), ast_mutex_unlock(), AST_PBX_CALL_LIMIT, AST_PBX_FAILED, ast_pbx_start(), AST_PBX_SUCCESS, ast_rtp_set_m_type(), ast_rtp_set_rtpmap_type(), ast_setstate(), AST_STATE_DOWN, AST_STATE_RING, jingle_pvt::audio_content_name, chan, jingle::connection, description, aji_client::jid, jingle_alloc(), JINGLE_AUDIO_RTP_NS, jingle_create_candidates(), jingle_free_pvt(), jingle_new(), JINGLE_NODE, jingle_response(), JINGLE_SID, JINGLE_VIDEO_RTP_NS, jingle_pvt::lock, LOG_ERROR, LOG_NOTICE, LOG_WARNING, jingle::name, jingle_pvt::next, jingle::p, jingle_pvt::rtp, jingle_pvt::sid, jingle_pvt::them, and jingle_pvt::video_content_name.

Referenced by jingle_parser().

00953 {
00954    struct jingle_pvt *p, *tmp = client->p;
00955    struct ast_channel *chan;
00956    int res;
00957    iks *codec, *content, *description;
00958    char *from = NULL;
00959 
00960    /* Make sure our new call doesn't exist yet */
00961    from = iks_find_attrib(pak->x,"to");
00962    if(!from)
00963       from = client->connection->jid->full;
00964 
00965    while (tmp) {
00966       if (iks_find_with_attrib(pak->x, JINGLE_NODE, JINGLE_SID, tmp->sid)) {
00967          ast_log(LOG_NOTICE, "Ignoring duplicate call setup on SID %s\n", tmp->sid);
00968          jingle_response(client, pak, "out-of-order", NULL);
00969          return -1;
00970       }
00971       tmp = tmp->next;
00972    }
00973 
00974    if (!strcasecmp(client->name, "guest")){
00975       /* the guest account is not tied to any configured XMPP client,
00976          let's set it now */
00977       client->connection = ast_aji_get_client(from);
00978       if (!client->connection) {
00979          ast_log(LOG_ERROR, "No XMPP client to talk to, us (partial JID) : %s\n", from);
00980          return -1;
00981       }
00982    }
00983 
00984    p = jingle_alloc(client, pak->from->partial, iks_find_attrib(pak->query, JINGLE_SID));
00985    if (!p) {
00986       ast_log(LOG_WARNING, "Unable to allocate jingle structure!\n");
00987       return -1;
00988    }
00989    chan = jingle_new(client, p, AST_STATE_DOWN, pak->from->user);
00990    if (!chan) {
00991       jingle_free_pvt(client, p);
00992       return -1;
00993    }
00994    ast_mutex_lock(&p->lock);
00995    ast_copy_string(p->them, pak->from->full, sizeof(p->them));
00996    if (iks_find_attrib(pak->query, JINGLE_SID)) {
00997       ast_copy_string(p->sid, iks_find_attrib(pak->query, JINGLE_SID),
00998             sizeof(p->sid));
00999    }
01000    
01001    /* content points to the first <content/> tag */   
01002    content = iks_child(iks_child(pak->x));
01003    while (content) {
01004       description = iks_find_with_attrib(content, "description", "xmlns", JINGLE_AUDIO_RTP_NS);
01005       if (description) {
01006          /* audio content found */
01007          codec = iks_child(iks_child(content));
01008               ast_copy_string(p->audio_content_name, iks_find_attrib(content, "name"), sizeof(p->audio_content_name));
01009 
01010          while (codec) {
01011             ast_rtp_set_m_type(p->rtp, atoi(iks_find_attrib(codec, "id")));
01012             ast_rtp_set_rtpmap_type(p->rtp, atoi(iks_find_attrib(codec, "id")), "audio", iks_find_attrib(codec, "name"), 0);
01013             codec = iks_next(codec);
01014          }
01015       }
01016       
01017       description = NULL;
01018       codec = NULL;
01019 
01020       description = iks_find_with_attrib(content, "description", "xmlns", JINGLE_VIDEO_RTP_NS);
01021       if (description) {
01022          /* video content found */
01023          codec = iks_child(iks_child(content));
01024               ast_copy_string(p->video_content_name, iks_find_attrib(content, "name"), sizeof(p->video_content_name));
01025 
01026          while (codec) {
01027             ast_rtp_set_m_type(p->rtp, atoi(iks_find_attrib(codec, "id")));
01028             ast_rtp_set_rtpmap_type(p->rtp, atoi(iks_find_attrib(codec, "id")), "audio", iks_find_attrib(codec, "name"), 0);
01029             codec = iks_next(codec);
01030          }
01031       }
01032       
01033       content = iks_next(content);
01034    }
01035 
01036    ast_mutex_unlock(&p->lock);
01037    ast_setstate(chan, AST_STATE_RING);
01038    res = ast_pbx_start(chan);
01039    
01040    switch (res) {
01041    case AST_PBX_FAILED:
01042       ast_log(LOG_WARNING, "Failed to start PBX :(\n");
01043       jingle_response(client, pak, "service-unavailable", NULL);
01044       break;
01045    case AST_PBX_CALL_LIMIT:
01046       ast_log(LOG_WARNING, "Failed to start PBX (call limit reached) \n");
01047       jingle_response(client, pak, "service-unavailable", NULL);
01048       break;
01049    case AST_PBX_SUCCESS:
01050       jingle_response(client, pak, NULL, NULL);
01051       jingle_create_candidates(client, p,
01052                 iks_find_attrib(pak->query, JINGLE_SID),
01053                 iks_find_attrib(pak->x, "from"));
01054       /* nothing to do */
01055       break;
01056    }
01057 
01058    return 1;
01059 }

static int jingle_parser ( void *  data,
ikspak *  pak 
) [static]

Definition at line 1591 of file chan_jingle.c.

References ast_debug, ast_log(), ASTOBJ_REF, ASTOBJ_UNREF, JINGLE_ACCEPT, jingle_add_candidate(), jingle_handle_dtmf(), jingle_hangup_farend(), JINGLE_INFO, JINGLE_INITIATE, jingle_is_answered(), jingle_member_destroy(), JINGLE_NEGOTIATE, jingle_newcall(), JINGLE_NODE, JINGLE_TERMINATE, and LOG_NOTICE.

Referenced by jingle_create_member(), and jingle_load_config().

01592 {
01593    struct jingle *client = ASTOBJ_REF((struct jingle *) data);
01594    ast_log(LOG_NOTICE, "Filter matched\n");
01595 
01596    if (iks_find_with_attrib(pak->x, JINGLE_NODE, "action", JINGLE_INITIATE)) {
01597       /* New call */
01598       jingle_newcall(client, pak);
01599    } else if (iks_find_with_attrib(pak->x, JINGLE_NODE, "action", JINGLE_NEGOTIATE)) {
01600       ast_debug(3, "About to add candidate!\n");
01601       jingle_add_candidate(client, pak);
01602       ast_debug(3, "Candidate Added!\n");
01603    } else if (iks_find_with_attrib(pak->x, JINGLE_NODE, "action", JINGLE_ACCEPT)) {
01604       jingle_is_answered(client, pak);
01605    } else if (iks_find_with_attrib(pak->x, JINGLE_NODE, "action", JINGLE_INFO)) {
01606       jingle_handle_dtmf(client, pak);
01607    } else if (iks_find_with_attrib(pak->x, JINGLE_NODE, "action", JINGLE_TERMINATE)) {
01608       jingle_hangup_farend(client, pak);
01609    } else if (iks_find_with_attrib(pak->x, JINGLE_NODE, "action", "reject")) {
01610       jingle_hangup_farend(client, pak);
01611    }
01612    ASTOBJ_UNREF(client, jingle_member_destroy);
01613    return IKS_FILTER_EAT;
01614 }

static struct ast_frame * jingle_read ( struct ast_channel ast  )  [static, read]

Definition at line 1193 of file chan_jingle.c.

References ast_mutex_lock(), ast_mutex_unlock(), jingle_rtp_read(), jingle_pvt::lock, and ast_channel::tech_pvt.

01194 {
01195    struct ast_frame *fr;
01196    struct jingle_pvt *p = ast->tech_pvt;
01197 
01198    ast_mutex_lock(&p->lock);
01199    fr = jingle_rtp_read(ast, p);
01200    ast_mutex_unlock(&p->lock);
01201    return fr;
01202 }

static struct ast_channel * jingle_request ( const char *  type,
int  format,
void *  data,
int *  cause 
) [static, read]

Part of PBX interface.

Definition at line 1466 of file chan_jingle.c.

References ast_aji_get_client(), ast_log(), AST_STATE_DOWN, ast_strdupa, ASTOBJ_UNLOCK, ASTOBJ_WRLOCK, chan, jingle::connection, find_jingle(), jingle_alloc(), jingle_new(), LOG_ERROR, LOG_WARNING, jingle::name, s, and strsep().

01467 {
01468    struct jingle_pvt *p = NULL;
01469    struct jingle *client = NULL;
01470    char *sender = NULL, *to = NULL, *s = NULL;
01471    struct ast_channel *chan = NULL;
01472 
01473    if (data) {
01474       s = ast_strdupa(data);
01475       if (s) {
01476          sender = strsep(&s, "/");
01477          if (sender && (sender[0] != '\0'))
01478             to = strsep(&s, "/");
01479          if (!to) {
01480             ast_log(LOG_ERROR, "Bad arguments in Jingle Dialstring: %s\n", (char*) data);
01481             return NULL;
01482          }
01483       }
01484    }
01485 
01486    client = find_jingle(to, sender);
01487    if (!client) {
01488       ast_log(LOG_WARNING, "Could not find recipient.\n");
01489       return NULL;
01490    }
01491    if (!strcasecmp(client->name, "guest")){
01492       /* the guest account is not tied to any configured XMPP client,
01493          let's set it now */
01494       client->connection = ast_aji_get_client(sender);
01495       if (!client->connection) {
01496          ast_log(LOG_ERROR, "No XMPP client to talk to, us (partial JID) : %s\n", sender);
01497          return NULL;
01498       }
01499    }
01500        
01501    ASTOBJ_WRLOCK(client);
01502    p = jingle_alloc(client, to, NULL);
01503    if (p)
01504       chan = jingle_new(client, p, AST_STATE_DOWN, to);
01505    ASTOBJ_UNLOCK(client);
01506 
01507    return chan;
01508 }

static int jingle_response ( struct jingle client,
ikspak *  pak,
const char *  reasonstr,
const char *  reasonstr2 
) [static]

Definition at line 444 of file chan_jingle.c.

References ast_aji_send(), jingle::connection, and aji_client::jid.

Referenced by jingle_handle_dtmf(), jingle_hangup_farend(), jingle_is_answered(), and jingle_newcall().

00445 {
00446    iks *response = NULL, *error = NULL, *reason = NULL;
00447    int res = -1;
00448 
00449    response = iks_new("iq");
00450    if (response) {
00451       iks_insert_attrib(response, "type", "result");
00452       iks_insert_attrib(response, "from", client->connection->jid->full);
00453       iks_insert_attrib(response, "to", iks_find_attrib(pak->x, "from"));
00454       iks_insert_attrib(response, "id", iks_find_attrib(pak->x, "id"));
00455       if (reasonstr) {
00456          error = iks_new("error");
00457          if (error) {
00458             iks_insert_attrib(error, "type", "cancel");
00459             reason = iks_new(reasonstr);
00460             if (reason)
00461                iks_insert_node(error, reason);
00462             iks_insert_node(response, error);
00463          }
00464       }
00465       ast_aji_send(client->connection, response);
00466       res = 0;
00467    }
00468    
00469    iks_delete(reason);
00470    iks_delete(error);
00471    iks_delete(response);
00472 
00473    return res;
00474 }

static int jingle_ringing_ack ( void *  data,
ikspak *  pak 
) [static]

Definition at line 375 of file chan_jingle.c.

References AST_CONTROL_RINGING, ast_queue_control(), jingle::connection, aji_client::f, jingle_pvt::owner, jingle_pvt::parent, and jingle_pvt::ringrule.

Referenced by jingle_call().

00376 {
00377    struct jingle_pvt *p = data;
00378 
00379    if (p->ringrule)
00380       iks_filter_remove_rule(p->parent->connection->f, p->ringrule);
00381    p->ringrule = NULL;
00382    if (p->owner)
00383       ast_queue_control(p->owner, AST_CONTROL_RINGING);
00384    return IKS_FILTER_EAT;
00385 }

static struct ast_frame* jingle_rtp_read ( struct ast_channel ast,
struct jingle_pvt p 
) [static, read]

Definition at line 1165 of file chan_jingle.c.

References ast_debug, AST_FORMAT_AUDIO_MASK, AST_FORMAT_VIDEO_MASK, AST_FRAME_VOICE, ast_null_frame, ast_rtp_read(), ast_set_read_format(), ast_set_write_format(), f, ast_frame::frametype, jingle_update_stun(), ast_channel::nativeformats, jingle_pvt::owner, jingle_pvt::parent, ast_channel::readformat, jingle_pvt::rtp, ast_frame::subclass, and ast_channel::writeformat.

Referenced by jingle_read().

01166 {
01167    struct ast_frame *f;
01168 
01169    if (!p->rtp)
01170       return &ast_null_frame;
01171    f = ast_rtp_read(p->rtp);
01172    jingle_update_stun(p->parent, p);
01173    if (p->owner) {
01174       /* We already hold the channel lock */
01175       if (f->frametype == AST_FRAME_VOICE) {
01176          if (f->subclass != (p->owner->nativeformats & AST_FORMAT_AUDIO_MASK)) {
01177             ast_debug(1, "Oooh, format changed to %d\n", f->subclass);
01178             p->owner->nativeformats =
01179                (p->owner->nativeformats & AST_FORMAT_VIDEO_MASK) | f->subclass;
01180             ast_set_read_format(p->owner, p->owner->readformat);
01181             ast_set_write_format(p->owner, p->owner->writeformat);
01182          }
01183 /*       if ((ast_test_flag(p, SIP_DTMF) == SIP_DTMF_INBAND) && p->vad) {
01184             f = ast_dsp_process(p->owner, p->vad, f);
01185             if (f && (f->frametype == AST_FRAME_DTMF))
01186                ast_debug(1, "* Detected inband DTMF '%c'\n", f->subclass);
01187               } */
01188       }
01189    }
01190    return f;
01191 }

static int jingle_sendhtml ( struct ast_channel ast,
int  subclass,
const char *  data,
int  datalen 
) [static]

Definition at line 1338 of file chan_jingle.c.

References ast_log(), and LOG_NOTICE.

01339 {
01340    ast_log(LOG_NOTICE, "XXX Implement jingle sendhtml XXX\n");
01341 
01342    return -1;
01343 }

static int jingle_set_rtp_peer ( struct ast_channel chan,
struct ast_rtp rtp,
struct ast_rtp vrtp,
struct ast_rtp tpeer,
int  codecs,
int  nat_active 
) [static]

Definition at line 424 of file chan_jingle.c.

References ast_mutex_lock(), ast_mutex_unlock(), jingle_pvt::lock, and ast_channel::tech_pvt.

00425 {
00426    struct jingle_pvt *p;
00427 
00428    p = chan->tech_pvt;
00429    if (!p)
00430       return -1;
00431    ast_mutex_lock(&p->lock);
00432 
00433 /* if (rtp)
00434       ast_rtp_get_peer(rtp, &p->redirip);
00435    else
00436       memset(&p->redirip, 0, sizeof(p->redirip));
00437    p->redircodecs = codecs; */
00438 
00439    /* Reset lastrtprx timer */
00440    ast_mutex_unlock(&p->lock);
00441    return 0;
00442 }

static char * jingle_show_channels ( struct ast_cli_entry e,
int  cmd,
struct ast_cli_args a 
) [static]

CLI command "jingle show channels".

Definition at line 1511 of file chan_jingle.c.

References AJI_MAX_JIDLEN, ast_cli_args::argc, ast_cli(), ast_copy_string(), ast_getformatname(), ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ASTOBJ_CONTAINER_TRAVERSE, ASTOBJ_UNLOCK, ASTOBJ_WRLOCK, chan, CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, ast_cli_args::fd, FORMAT, jingle_list, jinglelock, LOG_WARNING, ast_channel::name, jingle_pvt::next, jingle_pvt::owner, ast_channel::readformat, jingle_pvt::them, ast_cli_entry::usage, and ast_channel::writeformat.

01512 {
01513 #define FORMAT  "%-30.30s  %-30.30s  %-15.15s  %-5.5s %-5.5s \n"
01514    struct jingle_pvt *p;
01515    struct ast_channel *chan;
01516    int numchans = 0;
01517    char them[AJI_MAX_JIDLEN];
01518    char *jid = NULL;
01519    char *resource = NULL;
01520 
01521    switch (cmd) {
01522    case CLI_INIT:
01523       e->command = "jingle show channels";
01524       e->usage =
01525          "Usage: jingle show channels\n"
01526          "       Shows current state of the Jingle channels.\n";
01527       return NULL;
01528    case CLI_GENERATE:
01529       return NULL;
01530    }
01531 
01532    if (a->argc != 3)
01533       return CLI_SHOWUSAGE;
01534 
01535    ast_mutex_lock(&jinglelock);
01536    ast_cli(a->fd, FORMAT, "Channel", "Jabber ID", "Resource", "Read", "Write");
01537    ASTOBJ_CONTAINER_TRAVERSE(&jingle_list, 1, {
01538       ASTOBJ_WRLOCK(iterator);
01539       p = iterator->p;
01540       while(p) {
01541          chan = p->owner;
01542          ast_copy_string(them, p->them, sizeof(them));
01543          jid = them;
01544          resource = strchr(them, '/');
01545          if (!resource)
01546             resource = "None";
01547          else {
01548             *resource = '\0';
01549             resource ++;
01550          }
01551          if (chan)
01552             ast_cli(a->fd, FORMAT, 
01553                chan->name,
01554                jid,
01555                resource,
01556                ast_getformatname(chan->readformat),
01557                ast_getformatname(chan->writeformat)               
01558                );
01559          else 
01560             ast_log(LOG_WARNING, "No available channel\n");
01561          numchans ++;
01562          p = p->next;
01563       }
01564       ASTOBJ_UNLOCK(iterator);
01565    });
01566 
01567    ast_mutex_unlock(&jinglelock);
01568 
01569    ast_cli(a->fd, "%d active jingle channel%s\n", numchans, (numchans != 1) ? "s" : "");
01570    return CLI_SUCCESS;
01571 #undef FORMAT
01572 }

static int jingle_transmit_invite ( struct jingle_pvt p  )  [static]

Definition at line 1344 of file chan_jingle.c.

References ast_aji_increment_mid(), ast_aji_send(), ast_copy_string(), jingle_pvt::audio_content_name, jingle::connection, description, aji_client::jid, JINGLE_AUDIO_RTP_NS, JINGLE_ICE_UDP_NS, JINGLE_INITIATE, JINGLE_NODE, JINGLE_NS, JINGLE_SID, aji_client::mid, jingle_pvt::parent, jingle_pvt::sid, and jingle_pvt::them.

Referenced by jingle_call().

01345 {
01346    struct jingle *aux = NULL;
01347    struct aji_client *client = NULL;
01348    iks *iq, *jingle, *content, *description, *transport;
01349    iks *payload_eg711u, *payload_pcmu;
01350 
01351    aux = p->parent;
01352    client = aux->connection;
01353    iq = iks_new("iq");
01354    jingle = iks_new(JINGLE_NODE);
01355    content = iks_new("content");
01356    description = iks_new("description");
01357    transport = iks_new("transport");
01358    payload_pcmu = iks_new("payload-type");
01359    payload_eg711u = iks_new("payload-type");
01360 
01361    ast_copy_string(p->audio_content_name, "asterisk-audio-content", sizeof(p->audio_content_name));
01362 
01363    iks_insert_attrib(iq, "type", "set");
01364    iks_insert_attrib(iq, "to", p->them);
01365    iks_insert_attrib(iq, "from", client->jid->full);
01366    iks_insert_attrib(iq, "id", client->mid);
01367    ast_aji_increment_mid(client->mid);
01368    iks_insert_attrib(jingle, "action", JINGLE_INITIATE);
01369    iks_insert_attrib(jingle, JINGLE_SID, p->sid);
01370    iks_insert_attrib(jingle, "initiator", client->jid->full);
01371    iks_insert_attrib(jingle, "xmlns", JINGLE_NS);
01372 
01373    /* For now, we only send one audio based content */
01374    iks_insert_attrib(content, "creator", "initiator");
01375    iks_insert_attrib(content, "name", p->audio_content_name);
01376    iks_insert_attrib(content, "profile", "RTP/AVP");
01377    iks_insert_attrib(description, "xmlns", JINGLE_AUDIO_RTP_NS);
01378    iks_insert_attrib(transport, "xmlns", JINGLE_ICE_UDP_NS);
01379    iks_insert_attrib(payload_pcmu, "id", "0");
01380    iks_insert_attrib(payload_pcmu, "name", "PCMU");
01381    iks_insert_attrib(payload_eg711u, "id", "100");
01382    iks_insert_attrib(payload_eg711u, "name", "EG711U");
01383    iks_insert_node(description, payload_pcmu);
01384    iks_insert_node(description, payload_eg711u);
01385    iks_insert_node(content, description);
01386    iks_insert_node(content, transport);
01387    iks_insert_node(jingle, content);
01388    iks_insert_node(iq, jingle);
01389 
01390    ast_aji_send(client, iq);
01391 
01392    iks_delete(iq);
01393    iks_delete(jingle);
01394    iks_delete(content);
01395    iks_delete(description);
01396    iks_delete(transport);
01397    iks_delete(payload_eg711u);
01398    iks_delete(payload_pcmu);
01399    return 0;
01400 }

static int jingle_update_stun ( struct jingle client,
struct jingle_pvt p 
) [static]

Definition at line 1061 of file chan_jingle.c.

References ast_gethostbyname(), ast_rtp_stun_request(), hp, jingle_candidate::ip, jingle_pvt::laststun, jingle_candidate::next, jingle_pvt::ourcandidates, jingle_candidate::port, jingle_pvt::rtp, jingle_pvt::theircandidates, and jingle_candidate::ufrag.

Referenced by jingle_add_candidate(), and jingle_rtp_read().

01062 {
01063    struct jingle_candidate *tmp;
01064    struct hostent *hp;
01065    struct ast_hostent ahp;
01066    struct sockaddr_in sin;
01067 
01068    if (time(NULL) == p->laststun)
01069       return 0;
01070 
01071    tmp = p->theircandidates;
01072    p->laststun = time(NULL);
01073    while (tmp) {
01074       char username[256];
01075       hp = ast_gethostbyname(tmp->ip, &ahp);
01076       sin.sin_family = AF_INET;
01077       memcpy(&sin.sin_addr, hp->h_addr, sizeof(sin.sin_addr));
01078       sin.sin_port = htons(tmp->port);
01079       snprintf(username, sizeof(username), "%s:%s", tmp->ufrag, p->ourcandidates->ufrag);
01080 
01081       ast_rtp_stun_request(p->rtp, &sin, username);
01082       tmp = tmp->next;
01083    }
01084    return 1;
01085 }

static int jingle_write ( struct ast_channel ast,
struct ast_frame f 
) [static]

Send frame to media channel (rtp).

Definition at line 1205 of file chan_jingle.c.

References AST_FRAME_IMAGE, AST_FRAME_VIDEO, AST_FRAME_VOICE, ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_rtp_write(), ast_frame::frametype, jingle_pvt::lock, LOG_WARNING, ast_channel::nativeformats, ast_channel::readformat, jingle_pvt::rtp, ast_frame::subclass, ast_channel::tech_pvt, jingle_pvt::vrtp, and ast_channel::writeformat.

01206 {
01207    struct jingle_pvt *p = ast->tech_pvt;
01208    int res = 0;
01209 
01210    switch (frame->frametype) {
01211    case AST_FRAME_VOICE:
01212       if (!(frame->subclass & ast->nativeformats)) {
01213          ast_log(LOG_WARNING,
01214                "Asked to transmit frame type %d, while native formats is %d (read/write = %d/%d)\n",
01215                frame->subclass, ast->nativeformats, ast->readformat,
01216                ast->writeformat);
01217          return 0;
01218       }
01219       if (p) {
01220          ast_mutex_lock(&p->lock);
01221          if (p->rtp) {
01222             res = ast_rtp_write(p->rtp, frame);
01223          }
01224          ast_mutex_unlock(&p->lock);
01225       }
01226       break;
01227    case AST_FRAME_VIDEO:
01228       if (p) {
01229          ast_mutex_lock(&p->lock);
01230          if (p->vrtp) {
01231             res = ast_rtp_write(p->vrtp, frame);
01232          }
01233          ast_mutex_unlock(&p->lock);
01234       }
01235       break;
01236    case AST_FRAME_IMAGE:
01237       return 0;
01238       break;
01239    default:
01240       ast_log(LOG_WARNING, "Can't send %d type frames with Jingle write\n",
01241             frame->frametype);
01242       return 0;
01243    }
01244 
01245    return res;
01246 }

static int load_module ( void   )  [static]

Load module into PBX, register channel.

Definition at line 1844 of file chan_jingle.c.

References __ourip, ARRAY_LEN, ast_channel_register(), ast_cli_register_multiple(), ast_find_ourip(), ast_log(), ast_module_helper(), AST_MODULE_LOAD_DECLINE, ast_rtp_proto_register(), ASTOBJ_CONTAINER_INIT, free, io_context_create(), JINGLE_CONFIG, jingle_list, jingle_load_config(), LOG_ERROR, LOG_WARNING, and sched_context_create().

01845 {
01846    char *jabber_loaded = ast_module_helper("", "res_jabber.so", 0, 0, 0, 0);
01847    free(jabber_loaded);
01848    if (!jabber_loaded) {
01849       /* Dependency module has a different name, if embedded */
01850       jabber_loaded = ast_module_helper("", "res_jabber", 0, 0, 0, 0);
01851       free(jabber_loaded);
01852       if (!jabber_loaded) {
01853          ast_log(LOG_ERROR, "chan_jingle.so depends upon res_jabber.so\n");
01854          return AST_MODULE_LOAD_DECLINE;
01855       }
01856    }
01857 
01858    ASTOBJ_CONTAINER_INIT(&jingle_list);
01859    if (!jingle_load_config()) {
01860       ast_log(LOG_ERROR, "Unable to read config file %s. Not loading module.\n", JINGLE_CONFIG);
01861       return AST_MODULE_LOAD_DECLINE;
01862    }
01863 
01864    sched = sched_context_create();
01865    if (!sched) 
01866       ast_log(LOG_WARNING, "Unable to create schedule context\n");
01867 
01868    io = io_context_create();
01869    if (!io) 
01870       ast_log(LOG_WARNING, "Unable to create I/O context\n");
01871 
01872    if (ast_find_ourip(&__ourip, bindaddr)) {
01873       ast_log(LOG_WARNING, "Unable to get own IP address, Jingle disabled\n");
01874       return 0;
01875    }
01876 
01877    ast_rtp_proto_register(&jingle_rtp);
01878    ast_cli_register_multiple(jingle_cli, ARRAY_LEN(jingle_cli));
01879    /* Make sure we can register our channel type */
01880    if (ast_channel_register(&jingle_tech)) {
01881       ast_log(LOG_ERROR, "Unable to register channel class %s\n", type);
01882       return -1;
01883    }
01884    return 0;
01885 }

static int reload ( void   )  [static]

Reload module.

Definition at line 1888 of file chan_jingle.c.

01889 {
01890    return 0;
01891 }

static int unload_module ( void   )  [static]

Unload the jingle channel from Asterisk.

Definition at line 1894 of file chan_jingle.c.

References ARRAY_LEN, ast_channel_unregister(), ast_cli_unregister_multiple(), ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_rtp_proto_unregister(), ast_softhangup(), AST_SOFTHANGUP_APPUNLOAD, ASTOBJ_CONTAINER_DESTROY, ASTOBJ_CONTAINER_DESTROYALL, ASTOBJ_CONTAINER_TRAVERSE, ASTOBJ_UNLOCK, ASTOBJ_WRLOCK, jingle_list, jingle_member_destroy(), jinglelock, LOG_WARNING, jingle_pvt::next, and jingle_pvt::owner.

01895 {
01896    struct jingle_pvt *privates = NULL;
01897    ast_cli_unregister_multiple(jingle_cli, ARRAY_LEN(jingle_cli));
01898    /* First, take us out of the channel loop */
01899    ast_channel_unregister(&jingle_tech);
01900    ast_rtp_proto_unregister(&jingle_rtp);
01901 
01902    if (!ast_mutex_lock(&jinglelock)) {
01903       /* Hangup all interfaces if they have an owner */
01904       ASTOBJ_CONTAINER_TRAVERSE(&jingle_list, 1, {
01905          ASTOBJ_WRLOCK(iterator);
01906          privates = iterator->p;
01907          while(privates) {
01908             if (privates->owner)
01909                ast_softhangup(privates->owner, AST_SOFTHANGUP_APPUNLOAD);
01910             privates = privates->next;
01911          }
01912          iterator->p = NULL;
01913          ASTOBJ_UNLOCK(iterator);
01914       });
01915       ast_mutex_unlock(&jinglelock);
01916    } else {
01917       ast_log(LOG_WARNING, "Unable to lock the monitor\n");
01918       return -1;
01919    }
01920    ASTOBJ_CONTAINER_DESTROYALL(&jingle_list, jingle_member_destroy);
01921    ASTOBJ_CONTAINER_DESTROY(&jingle_list);
01922    return 0;
01923 }


Variable Documentation

struct ast_module_info __mod_info = { .name = AST_MODULE, .flags = AST_MODFLAG_DEFAULT , .description = "Jingle Channel Driver" , .key = "This paragraph is copyright (c) 2006 by Digium, Inc. \In order for your module to load, it must return this \key via a function called \"key\". Any code which \includes this paragraph must be licensed under the GNU \General Public License version 2 or later (at your \option). In addition to Digium's general reservations \of rights, Digium expressly reserves the right to \allow other parties to license this paragraph under \different terms. Any use of Digium, Inc. trademarks or \logos (including \"Asterisk\" or \"Digium\") without \express written permission of Digium, Inc. is prohibited.\n" , .buildopt_sum = AST_BUILDOPT_SUM, .load = load_module, .unload = unload_module, .reload = reload, } [static]

Definition at line 1929 of file chan_jingle.c.

struct in_addr __ourip [static]

Definition at line 216 of file chan_jingle.c.

const struct ast_module_info* ast_module_info = &__mod_info [static]

Definition at line 1929 of file chan_jingle.c.

struct sockaddr_in bindaddr = { 0, } [static]

The address we bind to

Definition at line 212 of file chan_jingle.c.

struct ast_jb_conf default_jbconf [static]

Global jitterbuffer configuration - by default, jb is disabled

Definition at line 75 of file chan_jingle.c.

const char desc[] = "Jingle Channel" [static]

Definition at line 162 of file chan_jingle.c.

char externip[16] [static]

Definition at line 233 of file chan_jingle.c.

int global_capability = AST_FORMAT_ULAW | AST_FORMAT_ALAW | AST_FORMAT_GSM | AST_FORMAT_H263 [static]

Definition at line 165 of file chan_jingle.c.

struct ast_jb_conf global_jbconf [static]

Definition at line 82 of file chan_jingle.c.

struct io_context* io [static]

The IO context

Definition at line 215 of file chan_jingle.c.

struct ast_cli_entry jingle_cli[] [static]

Initial value:

 {
   AST_CLI_DEFINE(jingle_do_reload, "Reload Jingle configuration"),
   AST_CLI_DEFINE(jingle_show_channels, "Show Jingle channels"),
}

Definition at line 227 of file chan_jingle.c.

struct jingle_container jingle_list [static]

struct ast_rtp_protocol jingle_rtp [static]

RTP driver interface.

Definition at line 220 of file chan_jingle.c.

struct ast_channel_tech jingle_tech [static]

PBX interface structure for channel registration.

Definition at line 192 of file chan_jingle.c.

ast_mutex_t jinglelock = ((ast_mutex_t) PTHREAD_MUTEX_INITIALIZER ) [static]

Protect the interface list (of jingle_pvt's)

Definition at line 167 of file chan_jingle.c.

Referenced by jingle_alloc(), jingle_show_channels(), and unload_module().

struct sched_context* sched [static]

The scheduling context

Definition at line 214 of file chan_jingle.c.

const char type[] = "Jingle" [static]

Definition at line 163 of file chan_jingle.c.


Generated on Wed Oct 28 11:45:56 2009 for Asterisk - the Open Source PBX by  doxygen 1.5.6