#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"
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 jingle * | find_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_pvt * | jingle_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_channel * | jingle_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_frame * | jingle_read (struct ast_channel *ast) |
static struct ast_channel * | jingle_request (const char *request_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_frame * | jingle_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 = "a9c98e5d177805051735cb5b0b16b0a0" , .load = load_module, .unload = unload_module, .reload = reload, } |
static struct in_addr | __ourip |
static struct ast_module_info * | ast_module_info = &__mod_info |
static struct sockaddr_in | bindaddr = { 0, } |
static const char | channel_type [] = "Jingle" |
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_context * | io |
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_RECURSIVE_MUTEX_INITIALIZER_NP ) |
static struct sched_context * | sched |
Definition in file chan_jingle.c.
#define FORMAT "%-30.30s %-30.30s %-15.15s %-5.5s %-5.5s \n" |
#define JINGLE_CONFIG "jingle.conf" |
enum jingle_connect_type |
Definition at line 90 of file chan_jingle.c.
00090 { 00091 AJI_CONNECT_HOST, 00092 AJI_CONNECT_PRFLX, 00093 AJI_CONNECT_RELAY, 00094 AJI_CONNECT_SRFLX, 00095 };
enum jingle_protocol |
Definition at line 85 of file chan_jingle.c.
00085 { 00086 AJI_PROTOCOL_UDP, 00087 AJI_PROTOCOL_SSLTCP, 00088 };
static void __reg_module | ( | void | ) | [static] |
Definition at line 1934 of file chan_jingle.c.
static void __unreg_module | ( | void | ) | [static] |
Definition at line 1934 of file chan_jingle.c.
static void add_codec_to_answer | ( | const struct jingle_pvt * | p, | |
int | codec, | |||
iks * | dcodecs | |||
) | [static] |
Definition at line 270 of file chan_jingle.c.
References ast_getformatname(), ast_rtp_lookup_code(), format, jingle::p, and jingle_pvt::rtp.
00271 { 00272 char *format = ast_getformatname(codec); 00273 00274 if (!strcasecmp("ulaw", format)) { 00275 iks *payload_eg711u, *payload_pcmu; 00276 payload_pcmu = iks_new("payload-type"); 00277 iks_insert_attrib(payload_pcmu, "id", "0"); 00278 iks_insert_attrib(payload_pcmu, "name", "PCMU"); 00279 payload_eg711u = iks_new("payload-type"); 00280 iks_insert_attrib(payload_eg711u, "id", "100"); 00281 iks_insert_attrib(payload_eg711u, "name", "EG711U"); 00282 iks_insert_node(dcodecs, payload_pcmu); 00283 iks_insert_node(dcodecs, payload_eg711u); 00284 } 00285 if (!strcasecmp("alaw", format)) { 00286 iks *payload_eg711a; 00287 iks *payload_pcma = iks_new("payload-type"); 00288 iks_insert_attrib(payload_pcma, "id", "8"); 00289 iks_insert_attrib(payload_pcma, "name", "PCMA"); 00290 payload_eg711a = iks_new("payload-type"); 00291 iks_insert_attrib(payload_eg711a, "id", "101"); 00292 iks_insert_attrib(payload_eg711a, "name", "EG711A"); 00293 iks_insert_node(dcodecs, payload_pcma); 00294 iks_insert_node(dcodecs, payload_eg711a); 00295 } 00296 if (!strcasecmp("ilbc", format)) { 00297 iks *payload_ilbc = iks_new("payload-type"); 00298 iks_insert_attrib(payload_ilbc, "id", "97"); 00299 iks_insert_attrib(payload_ilbc, "name", "iLBC"); 00300 iks_insert_node(dcodecs, payload_ilbc); 00301 } 00302 if (!strcasecmp("g723", format)) { 00303 iks *payload_g723 = iks_new("payload-type"); 00304 iks_insert_attrib(payload_g723, "id", "4"); 00305 iks_insert_attrib(payload_g723, "name", "G723"); 00306 iks_insert_node(dcodecs, payload_g723); 00307 } 00308 ast_rtp_lookup_code(p->rtp, 1, codec); 00309 }
static struct jingle* find_jingle | ( | char * | name, | |
char * | connection | |||
) | [static] |
Definition at line 244 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().
00245 { 00246 struct jingle *jingle = NULL; 00247 00248 jingle = ASTOBJ_CONTAINER_FIND(&jingle_list, name); 00249 if (!jingle && strchr(name, '@')) 00250 jingle = ASTOBJ_CONTAINER_FIND_FULL(&jingle_list, name, user,,, strcasecmp); 00251 00252 if (!jingle) { 00253 /* guest call */ 00254 ASTOBJ_CONTAINER_TRAVERSE(&jingle_list, 1, { 00255 ASTOBJ_RDLOCK(iterator); 00256 if (!strcasecmp(iterator->name, "guest")) { 00257 jingle = iterator; 00258 } 00259 ASTOBJ_UNLOCK(iterator); 00260 00261 if (jingle) 00262 break; 00263 }); 00264 00265 } 00266 return jingle; 00267 }
static int jingle_accept_call | ( | struct jingle * | client, | |
struct jingle_pvt * | p | |||
) | [static] |
Definition at line 311 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, aji_client::jid, JINGLE_ACCEPT, JINGLE_AUDIO_RTP_NS, JINGLE_NODE, JINGLE_NS, JINGLE_SID, aji_client::mid, aji_client::p, jingle::p, jingle::prefs, jingle_pvt::sid, and jingle::user.
Referenced by jingle_answer().
00312 { 00313 struct jingle_pvt *tmp = client->p; 00314 struct aji_client *c = client->connection; 00315 iks *iq, *jingle, *dcodecs, *payload_red, *payload_audio, *payload_cn; 00316 int x; 00317 int pref_codec = 0; 00318 int alreadysent = 0; 00319 00320 if (p->initiator) 00321 return 1; 00322 00323 iq = iks_new("iq"); 00324 jingle = iks_new(JINGLE_NODE); 00325 dcodecs = iks_new("description"); 00326 if (iq && jingle && dcodecs) { 00327 iks_insert_attrib(dcodecs, "xmlns", JINGLE_AUDIO_RTP_NS); 00328 00329 for (x = 0; x < 32; x++) { 00330 if (!(pref_codec = ast_codec_pref_index(&client->prefs, x))) 00331 break; 00332 if (!(client->capability & pref_codec)) 00333 continue; 00334 if (alreadysent & pref_codec) 00335 continue; 00336 add_codec_to_answer(p, pref_codec, dcodecs); 00337 alreadysent |= pref_codec; 00338 } 00339 payload_red = iks_new("payload-type"); 00340 iks_insert_attrib(payload_red, "id", "117"); 00341 iks_insert_attrib(payload_red, "name", "red"); 00342 payload_audio = iks_new("payload-type"); 00343 iks_insert_attrib(payload_audio, "id", "106"); 00344 iks_insert_attrib(payload_audio, "name", "audio/telephone-event"); 00345 payload_cn = iks_new("payload-type"); 00346 iks_insert_attrib(payload_cn, "id", "13"); 00347 iks_insert_attrib(payload_cn, "name", "CN"); 00348 00349 00350 iks_insert_attrib(iq, "type", "set"); 00351 iks_insert_attrib(iq, "to", (p->them) ? p->them : client->user); 00352 iks_insert_attrib(iq, "id", client->connection->mid); 00353 ast_aji_increment_mid(client->connection->mid); 00354 00355 iks_insert_attrib(jingle, "xmlns", JINGLE_NS); 00356 iks_insert_attrib(jingle, "action", JINGLE_ACCEPT); 00357 iks_insert_attrib(jingle, "initiator", p->initiator ? client->connection->jid->full : p->them); 00358 iks_insert_attrib(jingle, JINGLE_SID, tmp->sid); 00359 iks_insert_node(iq, jingle); 00360 iks_insert_node(jingle, dcodecs); 00361 iks_insert_node(dcodecs, payload_red); 00362 iks_insert_node(dcodecs, payload_audio); 00363 iks_insert_node(dcodecs, payload_cn); 00364 00365 ast_aji_send(c, iq); 00366 00367 iks_delete(payload_red); 00368 iks_delete(payload_audio); 00369 iks_delete(payload_cn); 00370 iks_delete(dcodecs); 00371 iks_delete(jingle); 00372 iks_delete(iq); 00373 } 00374 return 1; 00375 }
static int jingle_action | ( | struct jingle * | client, | |
struct jingle_pvt * | p, | |||
const char * | action | |||
) | [static] |
Definition at line 883 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().
00884 { 00885 iks *iq, *jingle = NULL; 00886 int res = -1; 00887 00888 iq = iks_new("iq"); 00889 jingle = iks_new("jingle"); 00890 00891 if (iq) { 00892 iks_insert_attrib(iq, "type", "set"); 00893 iks_insert_attrib(iq, "from", client->connection->jid->full); 00894 iks_insert_attrib(iq, "to", p->them); 00895 iks_insert_attrib(iq, "id", client->connection->mid); 00896 ast_aji_increment_mid(client->connection->mid); 00897 if (jingle) { 00898 iks_insert_attrib(jingle, "action", action); 00899 iks_insert_attrib(jingle, JINGLE_SID, p->sid); 00900 iks_insert_attrib(jingle, "initiator", p->initiator ? client->connection->jid->full : p->them); 00901 iks_insert_attrib(jingle, "xmlns", JINGLE_NS); 00902 00903 iks_insert_node(iq, jingle); 00904 00905 ast_aji_send(client->connection, iq); 00906 res = 0; 00907 } 00908 } 00909 00910 iks_delete(jingle); 00911 iks_delete(iq); 00912 00913 return res; 00914 }
static int jingle_add_candidate | ( | struct jingle * | client, | |
ikspak * | pak | |||
) | [static] |
Definition at line 1089 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, aji_client::jid, JINGLE_NODE, JINGLE_SID, jingle_update_stun(), jingle_pvt::laststun, jingle_pvt::next, jingle::p, jingle_pvt::parent, and jingle_pvt::theircandidates.
Referenced by jingle_parser().
01090 { 01091 struct jingle_pvt *p = NULL, *tmp = NULL; 01092 struct aji_client *c = client->connection; 01093 struct jingle_candidate *newcandidate = NULL; 01094 iks *traversenodes = NULL, *receipt = NULL; 01095 01096 for (tmp = client->p; tmp; tmp = tmp->next) { 01097 if (iks_find_with_attrib(pak->x, JINGLE_NODE, JINGLE_SID, tmp->sid)) { 01098 p = tmp; 01099 break; 01100 } 01101 } 01102 01103 if (!p) 01104 return -1; 01105 01106 traversenodes = pak->query; 01107 while(traversenodes) { 01108 if(!strcasecmp(iks_name(traversenodes), "jingle")) { 01109 traversenodes = iks_child(traversenodes); 01110 continue; 01111 } 01112 if(!strcasecmp(iks_name(traversenodes), "content")) { 01113 traversenodes = iks_child(traversenodes); 01114 continue; 01115 } 01116 if(!strcasecmp(iks_name(traversenodes), "transport")) { 01117 traversenodes = iks_child(traversenodes); 01118 continue; 01119 } 01120 01121 if(!strcasecmp(iks_name(traversenodes), "candidate")) { 01122 newcandidate = ast_calloc(1, sizeof(*newcandidate)); 01123 if (!newcandidate) 01124 return 0; 01125 ast_copy_string(newcandidate->ip, iks_find_attrib(traversenodes, "ip"), sizeof(newcandidate->ip)); 01126 newcandidate->port = atoi(iks_find_attrib(traversenodes, "port")); 01127 ast_copy_string(newcandidate->password, iks_find_attrib(traversenodes, "pwd"), sizeof(newcandidate->password)); 01128 if (!strcasecmp(iks_find_attrib(traversenodes, "protocol"), "udp")) 01129 newcandidate->protocol = AJI_PROTOCOL_UDP; 01130 else if (!strcasecmp(iks_find_attrib(traversenodes, "protocol"), "ssltcp")) 01131 newcandidate->protocol = AJI_PROTOCOL_SSLTCP; 01132 01133 if (!strcasecmp(iks_find_attrib(traversenodes, "type"), "host")) 01134 newcandidate->type = AJI_CONNECT_HOST; 01135 else if (!strcasecmp(iks_find_attrib(traversenodes, "type"), "prflx")) 01136 newcandidate->type = AJI_CONNECT_PRFLX; 01137 else if (!strcasecmp(iks_find_attrib(traversenodes, "type"), "relay")) 01138 newcandidate->type = AJI_CONNECT_RELAY; 01139 else if (!strcasecmp(iks_find_attrib(traversenodes, "type"), "srflx")) 01140 newcandidate->type = AJI_CONNECT_SRFLX; 01141 01142 newcandidate->network = atoi(iks_find_attrib(traversenodes, "network")); 01143 newcandidate->generation = atoi(iks_find_attrib(traversenodes, "generation")); 01144 newcandidate->next = NULL; 01145 01146 newcandidate->next = p->theircandidates; 01147 p->theircandidates = newcandidate; 01148 p->laststun = 0; 01149 jingle_update_stun(p->parent, p); 01150 newcandidate = NULL; 01151 } 01152 traversenodes = iks_next(traversenodes); 01153 } 01154 01155 receipt = iks_new("iq"); 01156 iks_insert_attrib(receipt, "type", "result"); 01157 iks_insert_attrib(receipt, "from", c->jid->full); 01158 iks_insert_attrib(receipt, "to", iks_find_attrib(pak->x, "from")); 01159 iks_insert_attrib(receipt, "id", iks_find_attrib(pak->x, "id")); 01160 ast_aji_send(c, receipt); 01161 01162 iks_delete(receipt); 01163 01164 return 1; 01165 }
static struct jingle_pvt * jingle_alloc | ( | struct jingle * | client, | |
const char * | from, | |||
const char * | sid | |||
) | [static] |
Definition at line 741 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, bindaddr, aji_client::buddies, jingle::buddy, aji_resource::cap, jingle::connection, io, aji_version::jingle, jinglelock, LOG_ERROR, LOG_WARNING, jingle::name, aji_resource::next, jingle::p, jingle::prefs, aji_resource::resource, and aji_buddy::resources.
Referenced by jingle_newcall(), and jingle_request().
00742 { 00743 struct jingle_pvt *tmp = NULL; 00744 struct aji_resource *resources = NULL; 00745 struct aji_buddy *buddy; 00746 char idroster[200]; 00747 00748 ast_debug(1, "The client is %s for alloc\n", client->name); 00749 if (!sid && !strchr(from, '/')) { /* I started call! */ 00750 if (!strcasecmp(client->name, "guest")) { 00751 buddy = ASTOBJ_CONTAINER_FIND(&client->connection->buddies, from); 00752 if (buddy) 00753 resources = buddy->resources; 00754 } else if (client->buddy) 00755 resources = client->buddy->resources; 00756 while (resources) { 00757 if (resources->cap->jingle) { 00758 break; 00759 } 00760 resources = resources->next; 00761 } 00762 if (resources) 00763 snprintf(idroster, sizeof(idroster), "%s/%s", from, resources->resource); 00764 else { 00765 ast_log(LOG_ERROR, "no jingle capable clients to talk to.\n"); 00766 return NULL; 00767 } 00768 } 00769 if (!(tmp = ast_calloc(1, sizeof(*tmp)))) { 00770 return NULL; 00771 } 00772 00773 memcpy(&tmp->prefs, &client->prefs, sizeof(tmp->prefs)); 00774 00775 if (sid) { 00776 ast_copy_string(tmp->sid, sid, sizeof(tmp->sid)); 00777 ast_copy_string(tmp->them, from, sizeof(tmp->them)); 00778 } else { 00779 snprintf(tmp->sid, sizeof(tmp->sid), "%08lx%08lx", ast_random(), ast_random()); 00780 ast_copy_string(tmp->them, idroster, sizeof(tmp->them)); 00781 tmp->initiator = 1; 00782 } 00783 tmp->rtp = ast_rtp_new_with_bindaddr(sched, io, 1, 0, bindaddr.sin_addr); 00784 tmp->parent = client; 00785 if (!tmp->rtp) { 00786 ast_log(LOG_WARNING, "Out of RTP sessions?\n"); 00787 ast_free(tmp); 00788 return NULL; 00789 } 00790 ast_copy_string(tmp->exten, "s", sizeof(tmp->exten)); 00791 ast_mutex_init(&tmp->lock); 00792 ast_mutex_lock(&jinglelock); 00793 tmp->next = client->p; 00794 client->p = tmp; 00795 ast_mutex_unlock(&jinglelock); 00796 return tmp; 00797 }
static int jingle_answer | ( | struct ast_channel * | ast | ) | [static] |
Definition at line 389 of file chan_jingle.c.
References ast_debug, ast_mutex_lock(), ast_mutex_unlock(), jingle_accept_call(), jingle_pvt::lock, jingle::p, jingle_pvt::parent, and ast_channel::tech_pvt.
00390 { 00391 struct jingle_pvt *p = ast->tech_pvt; 00392 struct jingle *client = p->parent; 00393 int res = 0; 00394 00395 ast_debug(1, "Answer!\n"); 00396 ast_mutex_lock(&p->lock); 00397 jingle_accept_call(client, p); 00398 ast_mutex_unlock(&p->lock); 00399 return res; 00400 }
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 1424 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.
01425 { 01426 struct jingle_pvt *p = ast->tech_pvt; 01427 01428 if ((ast->_state != AST_STATE_DOWN) && (ast->_state != AST_STATE_RESERVED)) { 01429 ast_log(LOG_WARNING, "jingle_call called on %s, neither down nor reserved\n", ast->name); 01430 return -1; 01431 } 01432 01433 ast_setstate(ast, AST_STATE_RING); 01434 p->jointcapability = p->capability; 01435 if (!p->ringrule) { 01436 ast_copy_string(p->ring, p->parent->connection->mid, sizeof(p->ring)); 01437 p->ringrule = iks_filter_add_rule(p->parent->connection->f, jingle_ringing_ack, p, 01438 IKS_RULE_ID, p->ring, IKS_RULE_DONE); 01439 } else 01440 ast_log(LOG_WARNING, "Whoa, already have a ring rule!\n"); 01441 01442 jingle_transmit_invite(p); 01443 jingle_create_candidates(p->parent, p, p->sid, p->them); 01444 01445 return 0; 01446 }
static int jingle_create_candidates | ( | struct jingle * | client, | |
struct jingle_pvt * | p, | |||
char * | sid, | |||
char * | from | |||
) | [static] |
Definition at line 583 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(), bindaddr, jingle_candidate::component, jingle::connection, externip, 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().
00584 { 00585 struct jingle_candidate *tmp; 00586 struct aji_client *c = client->connection; 00587 struct jingle_candidate *ours1 = NULL, *ours2 = NULL; 00588 struct sockaddr_in sin; 00589 struct sockaddr_in dest; 00590 struct in_addr us; 00591 struct in_addr externaddr; 00592 iks *iq, *jingle, *content, *transport, *candidate; 00593 char component[16], foundation[16], generation[16], network[16], pass[16], port[7], priority[16], user[16]; 00594 00595 00596 iq = iks_new("iq"); 00597 jingle = iks_new(JINGLE_NODE); 00598 content = iks_new("content"); 00599 transport = iks_new("transport"); 00600 candidate = iks_new("candidate"); 00601 if (!iq || !jingle || !content || !transport || !candidate) { 00602 ast_log(LOG_ERROR, "Memory allocation error\n"); 00603 goto safeout; 00604 } 00605 ours1 = ast_calloc(1, sizeof(*ours1)); 00606 ours2 = ast_calloc(1, sizeof(*ours2)); 00607 if (!ours1 || !ours2) 00608 goto safeout; 00609 00610 iks_insert_node(iq, jingle); 00611 iks_insert_node(jingle, content); 00612 iks_insert_node(content, transport); 00613 iks_insert_node(transport, candidate); 00614 00615 for (; p; p = p->next) { 00616 if (!strcasecmp(p->sid, sid)) 00617 break; 00618 } 00619 00620 if (!p) { 00621 ast_log(LOG_NOTICE, "No matching jingle session - SID %s!\n", sid); 00622 goto safeout; 00623 } 00624 00625 ast_rtp_get_us(p->rtp, &sin); 00626 ast_find_ourip(&us, bindaddr); 00627 00628 /* Setup our first jingle candidate */ 00629 ours1->component = 1; 00630 ours1->foundation = (unsigned int)bindaddr.sin_addr.s_addr | AJI_CONNECT_HOST | AJI_PROTOCOL_UDP; 00631 ours1->generation = 0; 00632 ast_copy_string(ours1->ip, ast_inet_ntoa(us), sizeof(ours1->ip)); 00633 ours1->network = 0; 00634 ours1->port = ntohs(sin.sin_port); 00635 ours1->priority = 1678246398; 00636 ours1->protocol = AJI_PROTOCOL_UDP; 00637 snprintf(pass, sizeof(pass), "%08lx%08lx", ast_random(), ast_random()); 00638 ast_copy_string(ours1->password, pass, sizeof(ours1->password)); 00639 ours1->type = AJI_CONNECT_HOST; 00640 snprintf(user, sizeof(user), "%08lx%08lx", ast_random(), ast_random()); 00641 ast_copy_string(ours1->ufrag, user, sizeof(ours1->ufrag)); 00642 p->ourcandidates = ours1; 00643 00644 if (!ast_strlen_zero(externip)) { 00645 /* XXX We should really stun for this one not just go with externip XXX */ 00646 if (inet_aton(externip, &externaddr)) 00647 ast_log(LOG_WARNING, "Invalid extern IP : %s\n", externip); 00648 00649 ours2->component = 1; 00650 ours2->foundation = (unsigned int)externaddr.s_addr | AJI_CONNECT_PRFLX | AJI_PROTOCOL_UDP; 00651 ours2->generation = 0; 00652 ast_copy_string(ours2->ip, externip, sizeof(ours2->ip)); 00653 ours2->network = 0; 00654 ours2->port = ntohs(sin.sin_port); 00655 ours2->priority = 1678246397; 00656 ours2->protocol = AJI_PROTOCOL_UDP; 00657 snprintf(pass, sizeof(pass), "%08lx%08lx", ast_random(), ast_random()); 00658 ast_copy_string(ours2->password, pass, sizeof(ours2->password)); 00659 ours2->type = AJI_CONNECT_PRFLX; 00660 00661 snprintf(user, sizeof(user), "%08lx%08lx", ast_random(), ast_random()); 00662 ast_copy_string(ours2->ufrag, user, sizeof(ours2->ufrag)); 00663 ours1->next = ours2; 00664 ours2 = NULL; 00665 } 00666 ours1 = NULL; 00667 dest.sin_addr = __ourip; 00668 dest.sin_port = sin.sin_port; 00669 00670 00671 for (tmp = p->ourcandidates; tmp; tmp = tmp->next) { 00672 snprintf(component, sizeof(component), "%u", tmp->component); 00673 snprintf(foundation, sizeof(foundation), "%u", tmp->foundation); 00674 snprintf(generation, sizeof(generation), "%u", tmp->generation); 00675 snprintf(network, sizeof(network), "%u", tmp->network); 00676 snprintf(port, sizeof(port), "%u", tmp->port); 00677 snprintf(priority, sizeof(priority), "%u", tmp->priority); 00678 00679 iks_insert_attrib(iq, "from", c->jid->full); 00680 iks_insert_attrib(iq, "to", from); 00681 iks_insert_attrib(iq, "type", "set"); 00682 iks_insert_attrib(iq, "id", c->mid); 00683 ast_aji_increment_mid(c->mid); 00684 iks_insert_attrib(jingle, "action", JINGLE_NEGOTIATE); 00685 iks_insert_attrib(jingle, JINGLE_SID, sid); 00686 iks_insert_attrib(jingle, "initiator", (p->initiator) ? c->jid->full : from); 00687 iks_insert_attrib(jingle, "xmlns", JINGLE_NS); 00688 iks_insert_attrib(content, "creator", p->initiator ? "initiator" : "responder"); 00689 iks_insert_attrib(content, "name", "asterisk-audio-content"); 00690 iks_insert_attrib(transport, "xmlns", JINGLE_ICE_UDP_NS); 00691 iks_insert_attrib(candidate, "component", component); 00692 iks_insert_attrib(candidate, "foundation", foundation); 00693 iks_insert_attrib(candidate, "generation", generation); 00694 iks_insert_attrib(candidate, "ip", tmp->ip); 00695 iks_insert_attrib(candidate, "network", network); 00696 iks_insert_attrib(candidate, "port", port); 00697 iks_insert_attrib(candidate, "priority", priority); 00698 switch (tmp->protocol) { 00699 case AJI_PROTOCOL_UDP: 00700 iks_insert_attrib(candidate, "protocol", "udp"); 00701 break; 00702 case AJI_PROTOCOL_SSLTCP: 00703 iks_insert_attrib(candidate, "protocol", "ssltcp"); 00704 break; 00705 } 00706 iks_insert_attrib(candidate, "pwd", tmp->password); 00707 switch (tmp->type) { 00708 case AJI_CONNECT_HOST: 00709 iks_insert_attrib(candidate, "type", "host"); 00710 break; 00711 case AJI_CONNECT_PRFLX: 00712 iks_insert_attrib(candidate, "type", "prflx"); 00713 break; 00714 case AJI_CONNECT_RELAY: 00715 iks_insert_attrib(candidate, "type", "relay"); 00716 break; 00717 case AJI_CONNECT_SRFLX: 00718 iks_insert_attrib(candidate, "type", "srflx"); 00719 break; 00720 } 00721 iks_insert_attrib(candidate, "ufrag", tmp->ufrag); 00722 00723 ast_aji_send(c, iq); 00724 } 00725 p->laststun = 0; 00726 00727 safeout: 00728 if (ours1) 00729 ast_free(ours1); 00730 if (ours2) 00731 ast_free(ours2); 00732 iks_delete(iq); 00733 iks_delete(jingle); 00734 iks_delete(content); 00735 iks_delete(transport); 00736 iks_delete(candidate); 00737 00738 return 1; 00739 }
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 1666 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, jingle::name, jingle_candidate::next, prefs, jingle::prefs, jingle::user, and var.
01669 { 01670 struct aji_client *client; 01671 01672 if (!member) 01673 ast_log(LOG_WARNING, "Out of memory.\n"); 01674 01675 ast_copy_string(member->name, label, sizeof(member->name)); 01676 ast_copy_string(member->user, label, sizeof(member->user)); 01677 ast_copy_string(member->context, context, sizeof(member->context)); 01678 member->allowguest = allowguest; 01679 member->prefs = prefs; 01680 while (var) { 01681 #if 0 01682 struct jingle_candidate *candidate = NULL; 01683 #endif 01684 if (!strcasecmp(var->name, "username")) 01685 ast_copy_string(member->user, var->value, sizeof(member->user)); 01686 else if (!strcasecmp(var->name, "disallow")) 01687 ast_parse_allow_disallow(&member->prefs, &member->capability, var->value, 0); 01688 else if (!strcasecmp(var->name, "allow")) 01689 ast_parse_allow_disallow(&member->prefs, &member->capability, var->value, 1); 01690 else if (!strcasecmp(var->name, "context")) 01691 ast_copy_string(member->context, var->value, sizeof(member->context)); 01692 #if 0 01693 else if (!strcasecmp(var->name, "candidate")) { 01694 candidate = jingle_create_candidate(var->value); 01695 if (candidate) { 01696 candidate->next = member->ourcandidates; 01697 member->ourcandidates = candidate; 01698 } 01699 } 01700 #endif 01701 else if (!strcasecmp(var->name, "connection")) { 01702 if ((client = ast_aji_get_client(var->value))) { 01703 member->connection = client; 01704 iks_filter_add_rule(client->f, jingle_parser, member, 01705 IKS_RULE_TYPE, IKS_PAK_IQ, 01706 IKS_RULE_FROM_PARTIAL, member->user, 01707 IKS_RULE_NS, JINGLE_NS, 01708 IKS_RULE_DONE); 01709 } else { 01710 ast_log(LOG_ERROR, "connection referenced not found!\n"); 01711 return 0; 01712 } 01713 } 01714 var = var->next; 01715 } 01716 if (member->connection && member->user) 01717 member->buddy = ASTOBJ_CONTAINER_FIND(&member->connection->buddies, member->user); 01718 else { 01719 ast_log(LOG_ERROR, "No Connection or Username!\n"); 01720 } 01721 return 1; 01722 }
static int jingle_digit | ( | struct ast_channel * | ast, | |
char | digit, | |||
unsigned int | duration | |||
) | [static] |
Definition at line 1284 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::p, jingle_pvt::parent, jingle_pvt::sid, ast_channel::tech_pvt, and jingle_pvt::them.
Referenced by jingle_digit_begin(), and jingle_digit_end().
01285 { 01286 struct jingle_pvt *p = ast->tech_pvt; 01287 struct jingle *client = p->parent; 01288 iks *iq, *jingle, *dtmf; 01289 char buffer[2] = {digit, '\0'}; 01290 iq = iks_new("iq"); 01291 jingle = iks_new("jingle"); 01292 dtmf = iks_new("dtmf"); 01293 if(!iq || !jingle || !dtmf) { 01294 iks_delete(iq); 01295 iks_delete(jingle); 01296 iks_delete(dtmf); 01297 ast_log(LOG_ERROR, "Did not send dtmf do to memory issue\n"); 01298 return -1; 01299 } 01300 01301 iks_insert_attrib(iq, "type", "set"); 01302 iks_insert_attrib(iq, "to", p->them); 01303 iks_insert_attrib(iq, "from", client->connection->jid->full); 01304 iks_insert_attrib(iq, "id", client->connection->mid); 01305 ast_aji_increment_mid(client->connection->mid); 01306 iks_insert_attrib(jingle, "xmlns", JINGLE_NS); 01307 iks_insert_attrib(jingle, "action", "session-info"); 01308 iks_insert_attrib(jingle, "initiator", p->initiator ? client->connection->jid->full : p->them); 01309 iks_insert_attrib(jingle, "sid", p->sid); 01310 iks_insert_attrib(dtmf, "xmlns", JINGLE_DTMF_NS); 01311 iks_insert_attrib(dtmf, "code", buffer); 01312 iks_insert_node(iq, jingle); 01313 iks_insert_node(jingle, dtmf); 01314 01315 ast_mutex_lock(&p->lock); 01316 if (ast->dtmff.frametype == AST_FRAME_DTMF_BEGIN || duration == 0) { 01317 iks_insert_attrib(dtmf, "action", "button-down"); 01318 } else if (ast->dtmff.frametype == AST_FRAME_DTMF_END || duration != 0) { 01319 iks_insert_attrib(dtmf, "action", "button-up"); 01320 } 01321 ast_aji_send(client->connection, iq); 01322 01323 iks_delete(iq); 01324 iks_delete(jingle); 01325 iks_delete(dtmf); 01326 ast_mutex_unlock(&p->lock); 01327 return 0; 01328 }
static int jingle_digit_begin | ( | struct ast_channel * | ast, | |
char | digit | |||
) | [static] |
Definition at line 1330 of file chan_jingle.c.
References chan, and jingle_digit().
01331 { 01332 return jingle_digit(chan, digit, 0); 01333 }
static int jingle_digit_end | ( | struct ast_channel * | ast, | |
char | digit, | |||
unsigned int | duration | |||
) | [static] |
Definition at line 1335 of file chan_jingle.c.
References jingle_digit().
01336 { 01337 return jingle_digit(ast, digit, duration); 01338 }
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 1577 of file chan_jingle.c.
References CLI_GENERATE, CLI_INIT, CLI_SUCCESS, ast_cli_entry::command, and ast_cli_entry::usage.
01578 { 01579 switch (cmd) { 01580 case CLI_INIT: 01581 e->command = "jingle reload"; 01582 e->usage = 01583 "Usage: jingle reload\n" 01584 " Reload jingle channel driver.\n"; 01585 return NULL; 01586 case CLI_GENERATE: 01587 return NULL; 01588 } 01589 01590 return CLI_SUCCESS; 01591 }
static int jingle_fixup | ( | struct ast_channel * | oldchan, | |
struct ast_channel * | newchan | |||
) | [static] |
Definition at line 1250 of file chan_jingle.c.
References ast_mutex_lock(), ast_mutex_unlock(), jingle_pvt::lock, jingle_pvt::owner, and ast_channel::tech_pvt.
01251 { 01252 struct jingle_pvt *p = newchan->tech_pvt; 01253 ast_mutex_lock(&p->lock); 01254 01255 if ((p->owner != oldchan)) { 01256 ast_mutex_unlock(&p->lock); 01257 return -1; 01258 } 01259 if (p->owner == oldchan) 01260 p->owner = newchan; 01261 ast_mutex_unlock(&p->lock); 01262 return 0; 01263 }
static void jingle_free_candidates | ( | struct jingle_candidate * | candidate | ) | [static] |
Definition at line 916 of file chan_jingle.c.
References ast_free, last, and jingle_candidate::next.
Referenced by jingle_free_pvt().
00917 { 00918 struct jingle_candidate *last; 00919 while (candidate) { 00920 last = candidate; 00921 candidate = candidate->next; 00922 ast_free(last); 00923 } 00924 }
static void jingle_free_pvt | ( | struct jingle * | client, | |
struct jingle_pvt * | p | |||
) | [static] |
Definition at line 926 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().
00927 { 00928 struct jingle_pvt *cur, *prev = NULL; 00929 cur = client->p; 00930 while (cur) { 00931 if (cur == p) { 00932 if (prev) 00933 prev->next = p->next; 00934 else 00935 client->p = p->next; 00936 break; 00937 } 00938 prev = cur; 00939 cur = cur->next; 00940 } 00941 if (p->ringrule) 00942 iks_filter_remove_rule(p->parent->connection->f, p->ringrule); 00943 if (p->owner) 00944 ast_log(LOG_WARNING, "Uh oh, there's an owner, this is going to be messy.\n"); 00945 if (p->rtp) 00946 ast_rtp_destroy(p->rtp); 00947 if (p->vrtp) 00948 ast_rtp_destroy(p->vrtp); 00949 jingle_free_candidates(p->theircandidates); 00950 ast_free(p); 00951 }
static int jingle_get_codec | ( | struct ast_channel * | chan | ) | [static] |
Definition at line 420 of file chan_jingle.c.
References chan, jingle_pvt::peercapability, and ast_channel::tech_pvt.
00421 { 00422 struct jingle_pvt *p = chan->tech_pvt; 00423 return p->peercapability; 00424 }
static enum ast_rtp_get_result jingle_get_rtp_peer | ( | struct ast_channel * | chan, | |
struct ast_rtp ** | rtp | |||
) | [static] |
Definition at line 402 of file chan_jingle.c.
References ast_mutex_lock(), ast_mutex_unlock(), AST_RTP_GET_FAILED, AST_RTP_TRY_PARTIAL, chan, jingle_pvt::lock, jingle_pvt::rtp, and ast_channel::tech_pvt.
00403 { 00404 struct jingle_pvt *p = chan->tech_pvt; 00405 enum ast_rtp_get_result res = AST_RTP_GET_FAILED; 00406 00407 if (!p) 00408 return res; 00409 00410 ast_mutex_lock(&p->lock); 00411 if (p->rtp) { 00412 *rtp = p->rtp; 00413 res = AST_RTP_TRY_PARTIAL; 00414 } 00415 ast_mutex_unlock(&p->lock); 00416 00417 return res; 00418 }
static int jingle_handle_dtmf | ( | struct jingle * | client, | |
ikspak * | pak | |||
) | [static] |
Definition at line 498 of file chan_jingle.c.
References AST_FRAME_DTMF, AST_FRAME_DTMF_BEGIN, AST_FRAME_DTMF_END, ast_log(), ast_queue_frame(), ast_verbose, f, JINGLE_NODE, jingle_response(), JINGLE_SID, LOG_NOTICE, jingle_pvt::next, jingle_pvt::owner, jingle::p, and jingle_pvt::sid.
Referenced by jingle_parser().
00499 { 00500 struct jingle_pvt *tmp; 00501 iks *dtmfnode = NULL, *dtmfchild = NULL; 00502 char *dtmf; 00503 /* Make sure our new call doesn't exist yet */ 00504 for (tmp = client->p; tmp; tmp = tmp->next) { 00505 if (iks_find_with_attrib(pak->x, JINGLE_NODE, JINGLE_SID, tmp->sid)) 00506 break; 00507 } 00508 00509 if (tmp) { 00510 if(iks_find_with_attrib(pak->x, "dtmf-method", "method", "rtp")) { 00511 jingle_response(client,pak, 00512 "feature-not-implemented xmlns='urn:ietf:params:xml:ns:xmpp-stanzas'", 00513 "unsupported-dtmf-method xmlns='http://www.xmpp.org/extensions/xep-0181.html#ns-errors'"); 00514 return -1; 00515 } 00516 if ((dtmfnode = iks_find(pak->x, "dtmf"))) { 00517 if((dtmf = iks_find_attrib(dtmfnode, "code"))) { 00518 if(iks_find_with_attrib(pak->x, "dtmf", "action", "button-up")) { 00519 struct ast_frame f = {AST_FRAME_DTMF_BEGIN, }; 00520 f.subclass = dtmf[0]; 00521 ast_queue_frame(tmp->owner, &f); 00522 ast_verbose("JINGLE! DTMF-relay event received: %c\n", f.subclass); 00523 } else if(iks_find_with_attrib(pak->x, "dtmf", "action", "button-down")) { 00524 struct ast_frame f = {AST_FRAME_DTMF_END, }; 00525 f.subclass = dtmf[0]; 00526 ast_queue_frame(tmp->owner, &f); 00527 ast_verbose("JINGLE! DTMF-relay event received: %c\n", f.subclass); 00528 } else if(iks_find_attrib(pak->x, "dtmf")) { /* 250 millasecond default */ 00529 struct ast_frame f = {AST_FRAME_DTMF, }; 00530 f.subclass = dtmf[0]; 00531 ast_queue_frame(tmp->owner, &f); 00532 ast_verbose("JINGLE! DTMF-relay event received: %c\n", f.subclass); 00533 } 00534 } 00535 } else if ((dtmfnode = iks_find_with_attrib(pak->x, JINGLE_NODE, "action", "session-info"))) { 00536 if((dtmfchild = iks_find(dtmfnode, "dtmf"))) { 00537 if((dtmf = iks_find_attrib(dtmfchild, "code"))) { 00538 if(iks_find_with_attrib(dtmfnode, "dtmf", "action", "button-up")) { 00539 struct ast_frame f = {AST_FRAME_DTMF_END, }; 00540 f.subclass = dtmf[0]; 00541 ast_queue_frame(tmp->owner, &f); 00542 ast_verbose("JINGLE! DTMF-relay event received: %c\n", f.subclass); 00543 } else if(iks_find_with_attrib(dtmfnode, "dtmf", "action", "button-down")) { 00544 struct ast_frame f = {AST_FRAME_DTMF_BEGIN, }; 00545 f.subclass = dtmf[0]; 00546 ast_queue_frame(tmp->owner, &f); 00547 ast_verbose("JINGLE! DTMF-relay event received: %c\n", f.subclass); 00548 } 00549 } 00550 } 00551 } 00552 jingle_response(client, pak, NULL, NULL); 00553 return 1; 00554 } else 00555 ast_log(LOG_NOTICE, "Whoa, didn't find call!\n"); 00556 00557 jingle_response(client, pak, NULL, NULL); 00558 return 1; 00559 }
static int jingle_hangup | ( | struct ast_channel * | ast | ) | [static] |
Hangup a call through the jingle proxy channel.
Definition at line 1449 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::p, jingle_pvt::parent, and ast_channel::tech_pvt.
01450 { 01451 struct jingle_pvt *p = ast->tech_pvt; 01452 struct jingle *client; 01453 01454 ast_mutex_lock(&p->lock); 01455 client = p->parent; 01456 p->owner = NULL; 01457 ast->tech_pvt = NULL; 01458 if (!p->alreadygone) 01459 jingle_action(client, p, JINGLE_TERMINATE); 01460 ast_mutex_unlock(&p->lock); 01461 01462 jingle_free_pvt(client, p); 01463 01464 return 0; 01465 }
static int jingle_hangup_farend | ( | struct jingle * | client, | |
ikspak * | pak | |||
) | [static] |
Definition at line 562 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().
00563 { 00564 struct jingle_pvt *tmp; 00565 00566 ast_debug(1, "The client is %s\n", client->name); 00567 /* Make sure our new call doesn't exist yet */ 00568 for (tmp = client->p; tmp; tmp = tmp->next) { 00569 if (iks_find_with_attrib(pak->x, JINGLE_NODE, JINGLE_SID, tmp->sid)) 00570 break; 00571 } 00572 00573 if (tmp) { 00574 tmp->alreadygone = 1; 00575 if (tmp->owner) 00576 ast_queue_hangup(tmp->owner); 00577 } else 00578 ast_log(LOG_NOTICE, "Whoa, didn't find call!\n"); 00579 jingle_response(client, pak, NULL, NULL); 00580 return 1; 00581 }
static int jingle_indicate | ( | struct ast_channel * | ast, | |
int | condition, | |||
const void * | data, | |||
size_t | datalen | |||
) | [static] |
Definition at line 1265 of file chan_jingle.c.
References AST_CONTROL_HOLD, AST_CONTROL_UNHOLD, ast_log(), ast_moh_start(), ast_moh_stop(), and LOG_NOTICE.
01266 { 01267 int res = 0; 01268 01269 switch (condition) { 01270 case AST_CONTROL_HOLD: 01271 ast_moh_start(ast, data, NULL); 01272 break; 01273 case AST_CONTROL_UNHOLD: 01274 ast_moh_stop(ast); 01275 break; 01276 default: 01277 ast_log(LOG_NOTICE, "Don't know how to indicate condition '%d'\n", condition); 01278 res = -1; 01279 } 01280 01281 return res; 01282 }
static int jingle_is_answered | ( | struct jingle * | client, | |
ikspak * | pak | |||
) | [static] |
Definition at line 478 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().
00479 { 00480 struct jingle_pvt *tmp; 00481 00482 ast_debug(1, "The client is %s\n", client->name); 00483 /* Make sure our new call doesn't exist yet */ 00484 for (tmp = client->p; tmp; tmp = tmp->next) { 00485 if (iks_find_with_attrib(pak->x, JINGLE_NODE, JINGLE_SID, tmp->sid)) 00486 break; 00487 } 00488 00489 if (tmp) { 00490 if (tmp->owner) 00491 ast_queue_control(tmp->owner, AST_CONTROL_ANSWER); 00492 } else 00493 ast_log(LOG_NOTICE, "Whoa, didn't find call!\n"); 00494 jingle_response(client, pak, NULL, NULL); 00495 return 1; 00496 }
static int jingle_load_config | ( | void | ) | [static] |
Definition at line 1724 of file chan_jingle.c.
References ahp, 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(), bindaddr, clients, config_flags, context, default_jbconf, externip, global_capability, global_jbconf, hp, JINGLE_CONFIG, LOG_WARNING, prefs, and var.
Referenced by load_module().
01725 { 01726 char *cat = NULL; 01727 struct ast_config *cfg = NULL; 01728 char context[100]; 01729 int allowguest = 1; 01730 struct ast_variable *var; 01731 struct jingle *member; 01732 struct hostent *hp; 01733 struct ast_hostent ahp; 01734 struct ast_codec_pref prefs; 01735 struct aji_client_container *clients; 01736 struct jingle_candidate *global_candidates = NULL; 01737 struct ast_flags config_flags = { 0 }; 01738 01739 cfg = ast_config_load(JINGLE_CONFIG, config_flags); 01740 if (!cfg) 01741 return 0; 01742 01743 /* Copy the default jb config over global_jbconf */ 01744 memcpy(&global_jbconf, &default_jbconf, sizeof(struct ast_jb_conf)); 01745 01746 cat = ast_category_browse(cfg, NULL); 01747 for (var = ast_variable_browse(cfg, "general"); var; var = var->next) { 01748 /* handle jb conf */ 01749 if (!ast_jb_read_conf(&global_jbconf, var->name, var->value)) 01750 continue; 01751 01752 if (!strcasecmp(var->name, "allowguest")) 01753 allowguest = 01754 (ast_true(ast_variable_retrieve(cfg, "general", "allowguest"))) ? 1 : 0; 01755 else if (!strcasecmp(var->name, "disallow")) 01756 ast_parse_allow_disallow(&prefs, &global_capability, var->value, 0); 01757 else if (!strcasecmp(var->name, "allow")) 01758 ast_parse_allow_disallow(&prefs, &global_capability, var->value, 1); 01759 else if (!strcasecmp(var->name, "context")) 01760 ast_copy_string(context, var->value, sizeof(context)); 01761 else if (!strcasecmp(var->name, "externip")) 01762 ast_copy_string(externip, var->value, sizeof(externip)); 01763 else if (!strcasecmp(var->name, "bindaddr")) { 01764 if (!(hp = ast_gethostbyname(var->value, &ahp))) { 01765 ast_log(LOG_WARNING, "Invalid address: %s\n", var->value); 01766 } else { 01767 memcpy(&bindaddr.sin_addr, hp->h_addr, sizeof(bindaddr.sin_addr)); 01768 } 01769 } 01770 /* Idea to allow for custom candidates */ 01771 /* 01772 else if (!strcasecmp(var->name, "candidate")) { 01773 candidate = jingle_create_candidate(var->value); 01774 if (candidate) { 01775 candidate->next = global_candidates; 01776 global_candidates = candidate; 01777 } 01778 } 01779 */ 01780 } 01781 while (cat) { 01782 if (strcasecmp(cat, "general")) { 01783 var = ast_variable_browse(cfg, cat); 01784 member = ast_calloc(1, sizeof(*member)); 01785 ASTOBJ_INIT(member); 01786 ASTOBJ_WRLOCK(member); 01787 if (!strcasecmp(cat, "guest")) { 01788 ast_copy_string(member->name, "guest", sizeof(member->name)); 01789 ast_copy_string(member->user, "guest", sizeof(member->user)); 01790 ast_copy_string(member->context, context, sizeof(member->context)); 01791 member->allowguest = allowguest; 01792 member->prefs = prefs; 01793 while (var) { 01794 if (!strcasecmp(var->name, "disallow")) 01795 ast_parse_allow_disallow(&member->prefs, &member->capability, 01796 var->value, 0); 01797 else if (!strcasecmp(var->name, "allow")) 01798 ast_parse_allow_disallow(&member->prefs, &member->capability, 01799 var->value, 1); 01800 else if (!strcasecmp(var->name, "context")) 01801 ast_copy_string(member->context, var->value, 01802 sizeof(member->context)); 01803 else if (!strcasecmp(var->name, "parkinglot")) 01804 ast_copy_string(member->parkinglot, var->value, 01805 sizeof(member->parkinglot)); 01806 /* Idea to allow for custom candidates */ 01807 /* 01808 else if (!strcasecmp(var->name, "candidate")) { 01809 candidate = jingle_create_candidate(var->value); 01810 if (candidate) { 01811 candidate->next = member->ourcandidates; 01812 member->ourcandidates = candidate; 01813 } 01814 } 01815 */ 01816 var = var->next; 01817 } 01818 ASTOBJ_UNLOCK(member); 01819 clients = ast_aji_get_clients(); 01820 if (clients) { 01821 ASTOBJ_CONTAINER_TRAVERSE(clients, 1, { 01822 ASTOBJ_WRLOCK(iterator); 01823 ASTOBJ_WRLOCK(member); 01824 member->connection = NULL; 01825 iks_filter_add_rule(iterator->f, jingle_parser, member, IKS_RULE_TYPE, IKS_PAK_IQ, IKS_RULE_NS, JINGLE_NS, IKS_RULE_DONE); 01826 iks_filter_add_rule(iterator->f, jingle_parser, member, IKS_RULE_TYPE, IKS_PAK_IQ, IKS_RULE_NS, JINGLE_DTMF_NS, IKS_RULE_DONE); 01827 ASTOBJ_UNLOCK(member); 01828 ASTOBJ_UNLOCK(iterator); 01829 }); 01830 ASTOBJ_CONTAINER_LINK(&jingle_list, member); 01831 } else { 01832 ASTOBJ_UNLOCK(member); 01833 ASTOBJ_UNREF(member, jingle_member_destroy); 01834 } 01835 } else { 01836 ASTOBJ_UNLOCK(member); 01837 if (jingle_create_member(cat, var, allowguest, prefs, context, member)) 01838 ASTOBJ_CONTAINER_LINK(&jingle_list, member); 01839 ASTOBJ_UNREF(member, jingle_member_destroy); 01840 } 01841 } 01842 cat = ast_category_browse(cfg, cat); 01843 } 01844 jingle_free_candidates(global_candidates); 01845 return 1; 01846 }
static void jingle_member_destroy | ( | struct jingle * | obj | ) | [static] |
Definition at line 239 of file chan_jingle.c.
References ast_free.
Referenced by jingle_parser(), and unload_module().
00240 { 00241 ast_free(obj); 00242 }
static struct ast_channel* jingle_new | ( | struct jingle * | client, | |
struct jingle_pvt * | i, | |||
int | state, | |||
const char * | title | |||
) | [static] |
Start new jingle channel.
Definition at line 800 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_capability, global_jbconf, ast_channel::hangupcause, jingle_tech, 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().
00801 { 00802 struct ast_channel *tmp; 00803 int fmt; 00804 int what; 00805 const char *str; 00806 00807 if (title) 00808 str = title; 00809 else 00810 str = i->them; 00811 tmp = ast_channel_alloc(1, state, i->cid_num, i->cid_name, "", "", "", 0, "Jingle/%s-%04lx", str, ast_random() & 0xffff); 00812 if (!tmp) { 00813 ast_log(LOG_WARNING, "Unable to allocate Jingle channel structure!\n"); 00814 return NULL; 00815 } 00816 tmp->tech = &jingle_tech; 00817 00818 /* Select our native format based on codec preference until we receive 00819 something from another device to the contrary. */ 00820 if (i->jointcapability) 00821 what = i->jointcapability; 00822 else if (i->capability) 00823 what = i->capability; 00824 else 00825 what = global_capability; 00826 00827 /* Set Frame packetization */ 00828 if (i->rtp) 00829 ast_rtp_codec_setpref(i->rtp, &i->prefs); 00830 00831 tmp->nativeformats = ast_codec_choose(&i->prefs, what, 1) | (i->jointcapability & AST_FORMAT_VIDEO_MASK); 00832 fmt = ast_best_codec(tmp->nativeformats); 00833 00834 if (i->rtp) { 00835 ast_channel_set_fd(tmp, 0, ast_rtp_fd(i->rtp)); 00836 ast_channel_set_fd(tmp, 1, ast_rtcp_fd(i->rtp)); 00837 } 00838 if (i->vrtp) { 00839 ast_channel_set_fd(tmp, 2, ast_rtp_fd(i->vrtp)); 00840 ast_channel_set_fd(tmp, 3, ast_rtcp_fd(i->vrtp)); 00841 } 00842 if (state == AST_STATE_RING) 00843 tmp->rings = 1; 00844 tmp->adsicpe = AST_ADSI_UNAVAILABLE; 00845 tmp->writeformat = fmt; 00846 tmp->rawwriteformat = fmt; 00847 tmp->readformat = fmt; 00848 tmp->rawreadformat = fmt; 00849 tmp->tech_pvt = i; 00850 00851 tmp->callgroup = client->callgroup; 00852 tmp->pickupgroup = client->pickupgroup; 00853 tmp->cid.cid_pres = client->callingpres; 00854 if (!ast_strlen_zero(client->accountcode)) 00855 ast_string_field_set(tmp, accountcode, client->accountcode); 00856 if (client->amaflags) 00857 tmp->amaflags = client->amaflags; 00858 if (!ast_strlen_zero(client->language)) 00859 ast_string_field_set(tmp, language, client->language); 00860 if (!ast_strlen_zero(client->musicclass)) 00861 ast_string_field_set(tmp, musicclass, client->musicclass); 00862 i->owner = tmp; 00863 ast_copy_string(tmp->context, client->context, sizeof(tmp->context)); 00864 ast_copy_string(tmp->exten, i->exten, sizeof(tmp->exten)); 00865 /* Don't use ast_set_callerid() here because it will 00866 * generate an unnecessary NewCallerID event */ 00867 tmp->cid.cid_ani = ast_strdup(i->cid_num); 00868 if (!ast_strlen_zero(i->exten) && strcmp(i->exten, "s")) 00869 tmp->cid.cid_dnid = ast_strdup(i->exten); 00870 tmp->priority = 1; 00871 if (i->rtp) 00872 ast_jb_configure(tmp, &global_jbconf); 00873 if (state != AST_STATE_DOWN && ast_pbx_start(tmp)) { 00874 ast_log(LOG_WARNING, "Unable to start PBX on %s\n", tmp->name); 00875 tmp->hangupcause = AST_CAUSE_SWITCH_CONGESTION; 00876 ast_hangup(tmp); 00877 tmp = NULL; 00878 } 00879 00880 return tmp; 00881 }
static int jingle_newcall | ( | struct jingle * | client, | |
ikspak * | pak | |||
) | [static] |
Definition at line 954 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().
00955 { 00956 struct jingle_pvt *p, *tmp = client->p; 00957 struct ast_channel *chan; 00958 int res; 00959 iks *codec, *content, *description; 00960 char *from = NULL; 00961 00962 /* Make sure our new call doesn't exist yet */ 00963 from = iks_find_attrib(pak->x,"to"); 00964 if(!from) 00965 from = client->connection->jid->full; 00966 00967 while (tmp) { 00968 if (iks_find_with_attrib(pak->x, JINGLE_NODE, JINGLE_SID, tmp->sid)) { 00969 ast_log(LOG_NOTICE, "Ignoring duplicate call setup on SID %s\n", tmp->sid); 00970 jingle_response(client, pak, "out-of-order", NULL); 00971 return -1; 00972 } 00973 tmp = tmp->next; 00974 } 00975 00976 if (!strcasecmp(client->name, "guest")){ 00977 /* the guest account is not tied to any configured XMPP client, 00978 let's set it now */ 00979 client->connection = ast_aji_get_client(from); 00980 if (!client->connection) { 00981 ast_log(LOG_ERROR, "No XMPP client to talk to, us (partial JID) : %s\n", from); 00982 return -1; 00983 } 00984 } 00985 00986 p = jingle_alloc(client, pak->from->partial, iks_find_attrib(pak->query, JINGLE_SID)); 00987 if (!p) { 00988 ast_log(LOG_WARNING, "Unable to allocate jingle structure!\n"); 00989 return -1; 00990 } 00991 chan = jingle_new(client, p, AST_STATE_DOWN, pak->from->user); 00992 if (!chan) { 00993 jingle_free_pvt(client, p); 00994 return -1; 00995 } 00996 ast_mutex_lock(&p->lock); 00997 ast_copy_string(p->them, pak->from->full, sizeof(p->them)); 00998 if (iks_find_attrib(pak->query, JINGLE_SID)) { 00999 ast_copy_string(p->sid, iks_find_attrib(pak->query, JINGLE_SID), 01000 sizeof(p->sid)); 01001 } 01002 01003 /* content points to the first <content/> tag */ 01004 content = iks_child(iks_child(pak->x)); 01005 while (content) { 01006 description = iks_find_with_attrib(content, "description", "xmlns", JINGLE_AUDIO_RTP_NS); 01007 if (description) { 01008 /* audio content found */ 01009 codec = iks_child(iks_child(content)); 01010 ast_copy_string(p->audio_content_name, iks_find_attrib(content, "name"), sizeof(p->audio_content_name)); 01011 01012 while (codec) { 01013 ast_rtp_set_m_type(p->rtp, atoi(iks_find_attrib(codec, "id"))); 01014 ast_rtp_set_rtpmap_type(p->rtp, atoi(iks_find_attrib(codec, "id")), "audio", iks_find_attrib(codec, "name"), 0); 01015 codec = iks_next(codec); 01016 } 01017 } 01018 01019 description = NULL; 01020 codec = NULL; 01021 01022 description = iks_find_with_attrib(content, "description", "xmlns", JINGLE_VIDEO_RTP_NS); 01023 if (description) { 01024 /* video content found */ 01025 codec = iks_child(iks_child(content)); 01026 ast_copy_string(p->video_content_name, iks_find_attrib(content, "name"), sizeof(p->video_content_name)); 01027 01028 while (codec) { 01029 ast_rtp_set_m_type(p->rtp, atoi(iks_find_attrib(codec, "id"))); 01030 ast_rtp_set_rtpmap_type(p->rtp, atoi(iks_find_attrib(codec, "id")), "audio", iks_find_attrib(codec, "name"), 0); 01031 codec = iks_next(codec); 01032 } 01033 } 01034 01035 content = iks_next(content); 01036 } 01037 01038 ast_mutex_unlock(&p->lock); 01039 ast_setstate(chan, AST_STATE_RING); 01040 res = ast_pbx_start(chan); 01041 01042 switch (res) { 01043 case AST_PBX_FAILED: 01044 ast_log(LOG_WARNING, "Failed to start PBX :(\n"); 01045 jingle_response(client, pak, "service-unavailable", NULL); 01046 break; 01047 case AST_PBX_CALL_LIMIT: 01048 ast_log(LOG_WARNING, "Failed to start PBX (call limit reached) \n"); 01049 jingle_response(client, pak, "service-unavailable", NULL); 01050 break; 01051 case AST_PBX_SUCCESS: 01052 jingle_response(client, pak, NULL, NULL); 01053 jingle_create_candidates(client, p, 01054 iks_find_attrib(pak->query, JINGLE_SID), 01055 iks_find_attrib(pak->x, "from")); 01056 /* nothing to do */ 01057 break; 01058 } 01059 01060 return 1; 01061 }
static int jingle_parser | ( | void * | data, | |
ikspak * | pak | |||
) | [static] |
Definition at line 1593 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().
01594 { 01595 struct jingle *client = ASTOBJ_REF((struct jingle *) data); 01596 ast_log(LOG_NOTICE, "Filter matched\n"); 01597 01598 if (iks_find_with_attrib(pak->x, JINGLE_NODE, "action", JINGLE_INITIATE)) { 01599 /* New call */ 01600 jingle_newcall(client, pak); 01601 } else if (iks_find_with_attrib(pak->x, JINGLE_NODE, "action", JINGLE_NEGOTIATE)) { 01602 ast_debug(3, "About to add candidate!\n"); 01603 jingle_add_candidate(client, pak); 01604 ast_debug(3, "Candidate Added!\n"); 01605 } else if (iks_find_with_attrib(pak->x, JINGLE_NODE, "action", JINGLE_ACCEPT)) { 01606 jingle_is_answered(client, pak); 01607 } else if (iks_find_with_attrib(pak->x, JINGLE_NODE, "action", JINGLE_INFO)) { 01608 jingle_handle_dtmf(client, pak); 01609 } else if (iks_find_with_attrib(pak->x, JINGLE_NODE, "action", JINGLE_TERMINATE)) { 01610 jingle_hangup_farend(client, pak); 01611 } else if (iks_find_with_attrib(pak->x, JINGLE_NODE, "action", "reject")) { 01612 jingle_hangup_farend(client, pak); 01613 } 01614 ASTOBJ_UNREF(client, jingle_member_destroy); 01615 return IKS_FILTER_EAT; 01616 }
static struct ast_frame * jingle_read | ( | struct ast_channel * | ast | ) | [static] |
Definition at line 1195 of file chan_jingle.c.
References ast_mutex_lock(), ast_mutex_unlock(), jingle_rtp_read(), jingle_pvt::lock, and ast_channel::tech_pvt.
01196 { 01197 struct ast_frame *fr; 01198 struct jingle_pvt *p = ast->tech_pvt; 01199 01200 ast_mutex_lock(&p->lock); 01201 fr = jingle_rtp_read(ast, p); 01202 ast_mutex_unlock(&p->lock); 01203 return fr; 01204 }
static struct ast_channel * jingle_request | ( | const char * | type, | |
int | format, | |||
void * | data, | |||
int * | cause | |||
) | [static] |
Part of PBX interface.
Definition at line 1468 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().
01469 { 01470 struct jingle_pvt *p = NULL; 01471 struct jingle *client = NULL; 01472 char *sender = NULL, *to = NULL, *s = NULL; 01473 struct ast_channel *chan = NULL; 01474 01475 if (data) { 01476 s = ast_strdupa(data); 01477 if (s) { 01478 sender = strsep(&s, "/"); 01479 if (sender && (sender[0] != '\0')) 01480 to = strsep(&s, "/"); 01481 if (!to) { 01482 ast_log(LOG_ERROR, "Bad arguments in Jingle Dialstring: %s\n", (char*) data); 01483 return NULL; 01484 } 01485 } 01486 } 01487 01488 client = find_jingle(to, sender); 01489 if (!client) { 01490 ast_log(LOG_WARNING, "Could not find recipient.\n"); 01491 return NULL; 01492 } 01493 if (!strcasecmp(client->name, "guest")){ 01494 /* the guest account is not tied to any configured XMPP client, 01495 let's set it now */ 01496 client->connection = ast_aji_get_client(sender); 01497 if (!client->connection) { 01498 ast_log(LOG_ERROR, "No XMPP client to talk to, us (partial JID) : %s\n", sender); 01499 return NULL; 01500 } 01501 } 01502 01503 ASTOBJ_WRLOCK(client); 01504 p = jingle_alloc(client, to, NULL); 01505 if (p) 01506 chan = jingle_new(client, p, AST_STATE_DOWN, to); 01507 ASTOBJ_UNLOCK(client); 01508 01509 return chan; 01510 }
static int jingle_response | ( | struct jingle * | client, | |
ikspak * | pak, | |||
const char * | reasonstr, | |||
const char * | reasonstr2 | |||
) | [static] |
Definition at line 446 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().
00447 { 00448 iks *response = NULL, *error = NULL, *reason = NULL; 00449 int res = -1; 00450 00451 response = iks_new("iq"); 00452 if (response) { 00453 iks_insert_attrib(response, "type", "result"); 00454 iks_insert_attrib(response, "from", client->connection->jid->full); 00455 iks_insert_attrib(response, "to", iks_find_attrib(pak->x, "from")); 00456 iks_insert_attrib(response, "id", iks_find_attrib(pak->x, "id")); 00457 if (reasonstr) { 00458 error = iks_new("error"); 00459 if (error) { 00460 iks_insert_attrib(error, "type", "cancel"); 00461 reason = iks_new(reasonstr); 00462 if (reason) 00463 iks_insert_node(error, reason); 00464 iks_insert_node(response, error); 00465 } 00466 } 00467 ast_aji_send(client->connection, response); 00468 res = 0; 00469 } 00470 00471 iks_delete(reason); 00472 iks_delete(error); 00473 iks_delete(response); 00474 00475 return res; 00476 }
static int jingle_ringing_ack | ( | void * | data, | |
ikspak * | pak | |||
) | [static] |
Definition at line 377 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().
00378 { 00379 struct jingle_pvt *p = data; 00380 00381 if (p->ringrule) 00382 iks_filter_remove_rule(p->parent->connection->f, p->ringrule); 00383 p->ringrule = NULL; 00384 if (p->owner) 00385 ast_queue_control(p->owner, AST_CONTROL_RINGING); 00386 return IKS_FILTER_EAT; 00387 }
static struct ast_frame* jingle_rtp_read | ( | struct ast_channel * | ast, | |
struct jingle_pvt * | p | |||
) | [static] |
Definition at line 1167 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, jingle_update_stun(), ast_channel::nativeformats, jingle_pvt::owner, jingle_pvt::parent, ast_channel::readformat, jingle_pvt::rtp, and ast_channel::writeformat.
Referenced by jingle_read().
01168 { 01169 struct ast_frame *f; 01170 01171 if (!p->rtp) 01172 return &ast_null_frame; 01173 f = ast_rtp_read(p->rtp); 01174 jingle_update_stun(p->parent, p); 01175 if (p->owner) { 01176 /* We already hold the channel lock */ 01177 if (f->frametype == AST_FRAME_VOICE) { 01178 if (f->subclass != (p->owner->nativeformats & AST_FORMAT_AUDIO_MASK)) { 01179 ast_debug(1, "Oooh, format changed to %d\n", f->subclass); 01180 p->owner->nativeformats = 01181 (p->owner->nativeformats & AST_FORMAT_VIDEO_MASK) | f->subclass; 01182 ast_set_read_format(p->owner, p->owner->readformat); 01183 ast_set_write_format(p->owner, p->owner->writeformat); 01184 } 01185 /* if ((ast_test_flag(p, SIP_DTMF) == SIP_DTMF_INBAND) && p->vad) { 01186 f = ast_dsp_process(p->owner, p->vad, f); 01187 if (f && (f->frametype == AST_FRAME_DTMF)) 01188 ast_debug(1, "* Detected inband DTMF '%c'\n", f->subclass); 01189 } */ 01190 } 01191 } 01192 return f; 01193 }
static int jingle_sendhtml | ( | struct ast_channel * | ast, | |
int | subclass, | |||
const char * | data, | |||
int | datalen | |||
) | [static] |
Definition at line 1340 of file chan_jingle.c.
References ast_log(), and LOG_NOTICE.
01341 { 01342 ast_log(LOG_NOTICE, "XXX Implement jingle sendhtml XXX\n"); 01343 01344 return -1; 01345 }
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 426 of file chan_jingle.c.
References ast_mutex_lock(), ast_mutex_unlock(), chan, jingle_pvt::lock, and ast_channel::tech_pvt.
00427 { 00428 struct jingle_pvt *p; 00429 00430 p = chan->tech_pvt; 00431 if (!p) 00432 return -1; 00433 ast_mutex_lock(&p->lock); 00434 00435 /* if (rtp) 00436 ast_rtp_get_peer(rtp, &p->redirip); 00437 else 00438 memset(&p->redirip, 0, sizeof(p->redirip)); 00439 p->redircodecs = codecs; */ 00440 00441 /* Reset lastrtprx timer */ 00442 ast_mutex_unlock(&p->lock); 00443 return 0; 00444 }
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 1513 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.
01514 { 01515 #define FORMAT "%-30.30s %-30.30s %-15.15s %-5.5s %-5.5s \n" 01516 struct jingle_pvt *p; 01517 struct ast_channel *chan; 01518 int numchans = 0; 01519 char them[AJI_MAX_JIDLEN]; 01520 char *jid = NULL; 01521 char *resource = NULL; 01522 01523 switch (cmd) { 01524 case CLI_INIT: 01525 e->command = "jingle show channels"; 01526 e->usage = 01527 "Usage: jingle show channels\n" 01528 " Shows current state of the Jingle channels.\n"; 01529 return NULL; 01530 case CLI_GENERATE: 01531 return NULL; 01532 } 01533 01534 if (a->argc != 3) 01535 return CLI_SHOWUSAGE; 01536 01537 ast_mutex_lock(&jinglelock); 01538 ast_cli(a->fd, FORMAT, "Channel", "Jabber ID", "Resource", "Read", "Write"); 01539 ASTOBJ_CONTAINER_TRAVERSE(&jingle_list, 1, { 01540 ASTOBJ_WRLOCK(iterator); 01541 p = iterator->p; 01542 while(p) { 01543 chan = p->owner; 01544 ast_copy_string(them, p->them, sizeof(them)); 01545 jid = them; 01546 resource = strchr(them, '/'); 01547 if (!resource) 01548 resource = "None"; 01549 else { 01550 *resource = '\0'; 01551 resource ++; 01552 } 01553 if (chan) 01554 ast_cli(a->fd, FORMAT, 01555 chan->name, 01556 jid, 01557 resource, 01558 ast_getformatname(chan->readformat), 01559 ast_getformatname(chan->writeformat) 01560 ); 01561 else 01562 ast_log(LOG_WARNING, "No available channel\n"); 01563 numchans ++; 01564 p = p->next; 01565 } 01566 ASTOBJ_UNLOCK(iterator); 01567 }); 01568 01569 ast_mutex_unlock(&jinglelock); 01570 01571 ast_cli(a->fd, "%d active jingle channel%s\n", numchans, (numchans != 1) ? "s" : ""); 01572 return CLI_SUCCESS; 01573 #undef FORMAT 01574 }
static int jingle_transmit_invite | ( | struct jingle_pvt * | p | ) | [static] |
Definition at line 1346 of file chan_jingle.c.
References ast_aji_increment_mid(), ast_aji_send(), ast_copy_string(), 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, and aji_client::p.
Referenced by jingle_call().
01347 { 01348 struct jingle *aux = NULL; 01349 struct aji_client *client = NULL; 01350 iks *iq, *jingle, *content, *description, *transport; 01351 iks *payload_eg711u, *payload_pcmu; 01352 01353 aux = p->parent; 01354 client = aux->connection; 01355 iq = iks_new("iq"); 01356 jingle = iks_new(JINGLE_NODE); 01357 content = iks_new("content"); 01358 description = iks_new("description"); 01359 transport = iks_new("transport"); 01360 payload_pcmu = iks_new("payload-type"); 01361 payload_eg711u = iks_new("payload-type"); 01362 01363 ast_copy_string(p->audio_content_name, "asterisk-audio-content", sizeof(p->audio_content_name)); 01364 01365 iks_insert_attrib(iq, "type", "set"); 01366 iks_insert_attrib(iq, "to", p->them); 01367 iks_insert_attrib(iq, "from", client->jid->full); 01368 iks_insert_attrib(iq, "id", client->mid); 01369 ast_aji_increment_mid(client->mid); 01370 iks_insert_attrib(jingle, "action", JINGLE_INITIATE); 01371 iks_insert_attrib(jingle, JINGLE_SID, p->sid); 01372 iks_insert_attrib(jingle, "initiator", client->jid->full); 01373 iks_insert_attrib(jingle, "xmlns", JINGLE_NS); 01374 01375 /* For now, we only send one audio based content */ 01376 iks_insert_attrib(content, "creator", "initiator"); 01377 iks_insert_attrib(content, "name", p->audio_content_name); 01378 iks_insert_attrib(content, "profile", "RTP/AVP"); 01379 iks_insert_attrib(description, "xmlns", JINGLE_AUDIO_RTP_NS); 01380 iks_insert_attrib(transport, "xmlns", JINGLE_ICE_UDP_NS); 01381 iks_insert_attrib(payload_pcmu, "id", "0"); 01382 iks_insert_attrib(payload_pcmu, "name", "PCMU"); 01383 iks_insert_attrib(payload_eg711u, "id", "100"); 01384 iks_insert_attrib(payload_eg711u, "name", "EG711U"); 01385 iks_insert_node(description, payload_pcmu); 01386 iks_insert_node(description, payload_eg711u); 01387 iks_insert_node(content, description); 01388 iks_insert_node(content, transport); 01389 iks_insert_node(jingle, content); 01390 iks_insert_node(iq, jingle); 01391 01392 ast_aji_send(client, iq); 01393 01394 iks_delete(iq); 01395 iks_delete(jingle); 01396 iks_delete(content); 01397 iks_delete(description); 01398 iks_delete(transport); 01399 iks_delete(payload_eg711u); 01400 iks_delete(payload_pcmu); 01401 return 0; 01402 }
static int jingle_update_stun | ( | struct jingle * | client, | |
struct jingle_pvt * | p | |||
) | [static] |
Definition at line 1063 of file chan_jingle.c.
References ahp, 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().
01064 { 01065 struct jingle_candidate *tmp; 01066 struct hostent *hp; 01067 struct ast_hostent ahp; 01068 struct sockaddr_in sin; 01069 01070 if (time(NULL) == p->laststun) 01071 return 0; 01072 01073 tmp = p->theircandidates; 01074 p->laststun = time(NULL); 01075 while (tmp) { 01076 char username[256]; 01077 hp = ast_gethostbyname(tmp->ip, &ahp); 01078 sin.sin_family = AF_INET; 01079 memcpy(&sin.sin_addr, hp->h_addr, sizeof(sin.sin_addr)); 01080 sin.sin_port = htons(tmp->port); 01081 snprintf(username, sizeof(username), "%s:%s", tmp->ufrag, p->ourcandidates->ufrag); 01082 01083 ast_rtp_stun_request(p->rtp, &sin, username); 01084 tmp = tmp->next; 01085 } 01086 return 1; 01087 }
static int jingle_write | ( | struct ast_channel * | ast, | |
struct ast_frame * | f | |||
) | [static] |
Send frame to media channel (rtp).
Definition at line 1207 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.
01208 { 01209 struct jingle_pvt *p = ast->tech_pvt; 01210 int res = 0; 01211 01212 switch (frame->frametype) { 01213 case AST_FRAME_VOICE: 01214 if (!(frame->subclass & ast->nativeformats)) { 01215 ast_log(LOG_WARNING, 01216 "Asked to transmit frame type %d, while native formats is %d (read/write = %d/%d)\n", 01217 frame->subclass, ast->nativeformats, ast->readformat, 01218 ast->writeformat); 01219 return 0; 01220 } 01221 if (p) { 01222 ast_mutex_lock(&p->lock); 01223 if (p->rtp) { 01224 res = ast_rtp_write(p->rtp, frame); 01225 } 01226 ast_mutex_unlock(&p->lock); 01227 } 01228 break; 01229 case AST_FRAME_VIDEO: 01230 if (p) { 01231 ast_mutex_lock(&p->lock); 01232 if (p->vrtp) { 01233 res = ast_rtp_write(p->vrtp, frame); 01234 } 01235 ast_mutex_unlock(&p->lock); 01236 } 01237 break; 01238 case AST_FRAME_IMAGE: 01239 return 0; 01240 break; 01241 default: 01242 ast_log(LOG_WARNING, "Can't send %d type frames with Jingle write\n", 01243 frame->frametype); 01244 return 0; 01245 } 01246 01247 return res; 01248 }
static int load_module | ( | void | ) | [static] |
Load module into PBX, register channel.
Definition at line 1849 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, bindaddr, channel_type, free, io, io_context_create(), jingle_cli, JINGLE_CONFIG, jingle_list, jingle_load_config(), jingle_rtp, jingle_tech, LOG_ERROR, LOG_WARNING, and sched_context_create().
01850 { 01851 char *jabber_loaded = ast_module_helper("", "res_jabber.so", 0, 0, 0, 0); 01852 free(jabber_loaded); 01853 if (!jabber_loaded) { 01854 /* Dependency module has a different name, if embedded */ 01855 jabber_loaded = ast_module_helper("", "res_jabber", 0, 0, 0, 0); 01856 free(jabber_loaded); 01857 if (!jabber_loaded) { 01858 ast_log(LOG_ERROR, "chan_jingle.so depends upon res_jabber.so\n"); 01859 return AST_MODULE_LOAD_DECLINE; 01860 } 01861 } 01862 01863 ASTOBJ_CONTAINER_INIT(&jingle_list); 01864 if (!jingle_load_config()) { 01865 ast_log(LOG_ERROR, "Unable to read config file %s. Not loading module.\n", JINGLE_CONFIG); 01866 return AST_MODULE_LOAD_DECLINE; 01867 } 01868 01869 sched = sched_context_create(); 01870 if (!sched) 01871 ast_log(LOG_WARNING, "Unable to create schedule context\n"); 01872 01873 io = io_context_create(); 01874 if (!io) 01875 ast_log(LOG_WARNING, "Unable to create I/O context\n"); 01876 01877 if (ast_find_ourip(&__ourip, bindaddr)) { 01878 ast_log(LOG_WARNING, "Unable to get own IP address, Jingle disabled\n"); 01879 return 0; 01880 } 01881 01882 ast_rtp_proto_register(&jingle_rtp); 01883 ast_cli_register_multiple(jingle_cli, ARRAY_LEN(jingle_cli)); 01884 /* Make sure we can register our channel type */ 01885 if (ast_channel_register(&jingle_tech)) { 01886 ast_log(LOG_ERROR, "Unable to register channel class %s\n", channel_type); 01887 return -1; 01888 } 01889 return 0; 01890 }
static int reload | ( | void | ) | [static] |
static int unload_module | ( | void | ) | [static] |
Unload the jingle channel from Asterisk.
Definition at line 1899 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_cli, jingle_list, jingle_member_destroy(), jingle_rtp, jingle_tech, jinglelock, LOG_WARNING, jingle_pvt::next, and jingle_pvt::owner.
01900 { 01901 struct jingle_pvt *privates = NULL; 01902 ast_cli_unregister_multiple(jingle_cli, ARRAY_LEN(jingle_cli)); 01903 /* First, take us out of the channel loop */ 01904 ast_channel_unregister(&jingle_tech); 01905 ast_rtp_proto_unregister(&jingle_rtp); 01906 01907 if (!ast_mutex_lock(&jinglelock)) { 01908 /* Hangup all interfaces if they have an owner */ 01909 ASTOBJ_CONTAINER_TRAVERSE(&jingle_list, 1, { 01910 ASTOBJ_WRLOCK(iterator); 01911 privates = iterator->p; 01912 while(privates) { 01913 if (privates->owner) 01914 ast_softhangup(privates->owner, AST_SOFTHANGUP_APPUNLOAD); 01915 privates = privates->next; 01916 } 01917 iterator->p = NULL; 01918 ASTOBJ_UNLOCK(iterator); 01919 }); 01920 ast_mutex_unlock(&jinglelock); 01921 } else { 01922 ast_log(LOG_WARNING, "Unable to lock the monitor\n"); 01923 return -1; 01924 } 01925 ASTOBJ_CONTAINER_DESTROYALL(&jingle_list, jingle_member_destroy); 01926 ASTOBJ_CONTAINER_DESTROY(&jingle_list); 01927 return 0; 01928 }
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 = "a9c98e5d177805051735cb5b0b16b0a0" , .load = load_module, .unload = unload_module, .reload = reload, } [static] |
Definition at line 1934 of file chan_jingle.c.
struct in_addr __ourip [static] |
Definition at line 218 of file chan_jingle.c.
struct ast_module_info* ast_module_info = &__mod_info [static] |
Definition at line 1934 of file chan_jingle.c.
struct sockaddr_in bindaddr = { 0, } [static] |
The address we bind to
Definition at line 214 of file chan_jingle.c.
const char channel_type[] = "Jingle" [static] |
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 164 of file chan_jingle.c.
char externip[16] [static] |
Definition at line 235 of file chan_jingle.c.
int global_capability = AST_FORMAT_ULAW | AST_FORMAT_ALAW | AST_FORMAT_GSM | AST_FORMAT_H263 [static] |
Definition at line 167 of file chan_jingle.c.
struct ast_jb_conf global_jbconf [static] |
Definition at line 83 of file chan_jingle.c.
struct io_context* io [static] |
The IO context
Definition at line 217 of file chan_jingle.c.
struct ast_cli_entry jingle_cli[] [static] |
Initial value:
{ { .handler = jingle_do_reload , .summary = "Reload Jingle configuration" ,__VA_ARGS__ }, { .handler = jingle_show_channels , .summary = "Show Jingle channels" ,__VA_ARGS__ }, }
Definition at line 229 of file chan_jingle.c.
Referenced by load_module(), and unload_module().
struct jingle_container jingle_list [static] |
Definition at line 237 of file chan_jingle.c.
Referenced by find_jingle(), jingle_show_channels(), load_module(), and unload_module().
struct ast_rtp_protocol jingle_rtp [static] |
RTP driver interface.
Definition at line 222 of file chan_jingle.c.
Referenced by load_module(), and unload_module().
struct ast_channel_tech jingle_tech [static] |
PBX interface structure for channel registration.
Definition at line 194 of file chan_jingle.c.
Referenced by jingle_new(), load_module(), and unload_module().
ast_mutex_t jinglelock = ((ast_mutex_t) PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP ) [static] |
Protect the interface list (of jingle_pvt's)
Definition at line 169 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 216 of file chan_jingle.c.