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