00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044 #ifdef __cplusplus
00045 extern "C" {
00046 #endif
00047
00048 #include "asterisk.h"
00049
00050 ASTERISK_FILE_VERSION(__FILE__, "$Revision: 353685 $")
00051
00052 #ifdef __cplusplus
00053 }
00054 #endif
00055
00056 #include <sys/types.h>
00057 #include <sys/socket.h>
00058 #include <sys/signal.h>
00059 #include <sys/param.h>
00060 #include <arpa/inet.h>
00061 #include <net/if.h>
00062 #include <netinet/in.h>
00063 #include <netinet/in_systm.h>
00064 #include <netinet/ip.h>
00065 #include <netdb.h>
00066 #include <fcntl.h>
00067
00068 #ifdef __cplusplus
00069 extern "C" {
00070 #endif
00071
00072 #include "asterisk/lock.h"
00073 #include "asterisk/channel.h"
00074 #include "asterisk/config.h"
00075 #include "asterisk/module.h"
00076 #include "asterisk/musiconhold.h"
00077 #include "asterisk/pbx.h"
00078 #include "asterisk/utils.h"
00079 #include "asterisk/sched.h"
00080 #include "asterisk/io.h"
00081 #include "asterisk/rtp_engine.h"
00082 #include "asterisk/acl.h"
00083 #include "asterisk/callerid.h"
00084 #include "asterisk/cli.h"
00085 #include "asterisk/dsp.h"
00086 #include "asterisk/causes.h"
00087 #include "asterisk/stringfields.h"
00088 #include "asterisk/abstract_jb.h"
00089 #include "asterisk/astobj.h"
00090 #include "asterisk/format.h"
00091 #include "asterisk/format_cap.h"
00092
00093 #ifdef __cplusplus
00094 }
00095 #endif
00096
00097 #undef open
00098 #undef close
00099 #include "h323/chan_h323.h"
00100
00101 receive_digit_cb on_receive_digit;
00102 on_rtp_cb on_external_rtp_create;
00103 start_rtp_cb on_start_rtp_channel;
00104 setup_incoming_cb on_incoming_call;
00105 setup_outbound_cb on_outgoing_call;
00106 chan_ringing_cb on_chan_ringing;
00107 con_established_cb on_connection_established;
00108 clear_con_cb on_connection_cleared;
00109 answer_call_cb on_answer_call;
00110 progress_cb on_progress;
00111 rfc2833_cb on_set_rfc2833_payload;
00112 hangup_cb on_hangup;
00113 setcapabilities_cb on_setcapabilities;
00114 setpeercapabilities_cb on_setpeercapabilities;
00115 onhold_cb on_hold;
00116
00117 int h323debug;
00118
00119
00120
00121 static struct ast_jb_conf default_jbconf =
00122 {
00123 .flags = 0,
00124 .max_size = 200,
00125 .resync_threshold = 1000,
00126 .impl = "fixed",
00127 .target_extra = 40,
00128 };
00129 static struct ast_jb_conf global_jbconf;
00130
00131
00132 static const char tdesc[] = "The NuFone Network's Open H.323 Channel Driver";
00133 static const char config[] = "h323.conf";
00134 static char default_context[AST_MAX_CONTEXT] = "default";
00135 static struct sockaddr_in bindaddr;
00136
00137 #define GLOBAL_CAPABILITY (ast_format_id_to_old_bitfield(AST_FORMAT_G723_1) | \
00138 ast_format_id_to_old_bitfield(AST_FORMAT_GSM) | \
00139 ast_format_id_to_old_bitfield(AST_FORMAT_ULAW) | \
00140 ast_format_id_to_old_bitfield(AST_FORMAT_ALAW) | \
00141 ast_format_id_to_old_bitfield(AST_FORMAT_G729A) | \
00142 ast_format_id_to_old_bitfield(AST_FORMAT_G726_AAL2) | \
00143 ast_format_id_to_old_bitfield(AST_FORMAT_H261)) \
00144
00145
00146 static int h323_signalling_port = 1720;
00147 static char gatekeeper[100];
00148 static int gatekeeper_disable = 1;
00149 static int gatekeeper_discover = 0;
00150 static int gkroute = 0;
00151
00152 static int userbyalias = 1;
00153 static int acceptAnonymous = 1;
00154 static unsigned int tos = 0;
00155 static unsigned int cos = 0;
00156 static char secret[50];
00157 static unsigned int unique = 0;
00158
00159 static call_options_t global_options;
00160
00161
00162 static struct oh323_pvt {
00163 ast_mutex_t lock;
00164 call_options_t options;
00165 int alreadygone;
00166 int needdestroy;
00167 call_details_t cd;
00168 struct ast_channel *owner;
00169 struct sockaddr_in sa;
00170 struct sockaddr_in redirip;
00171 int nonCodecCapability;
00172 int outgoing;
00173 char exten[AST_MAX_EXTENSION];
00174 char context[AST_MAX_CONTEXT];
00175 char accountcode[256];
00176 char rdnis[80];
00177 int amaflags;
00178 struct ast_rtp_instance *rtp;
00179 struct ast_dsp *vad;
00180 int nativeformats;
00181 int needhangup;
00182 int hangupcause;
00183 int newstate;
00184 int newcontrol;
00185 int newdigit;
00186 int newduration;
00187 h323_format pref_codec;
00188 h323_format peercapability;
00189 h323_format jointcapability;
00190 struct ast_codec_pref peer_prefs;
00191 int dtmf_pt[2];
00192 int curDTMF;
00193 int DTMFsched;
00194 int update_rtp_info;
00195 int recvonly;
00196 int txDtmfDigit;
00197 int noInbandDtmf;
00198 int connection_established;
00199 int got_progress;
00200 struct oh323_pvt *next;
00201 } *iflist = NULL;
00202
00203
00204 static struct h323_user_list {
00205 ASTOBJ_CONTAINER_COMPONENTS(struct oh323_user);
00206 } userl;
00207
00208
00209 static struct h323_peer_list {
00210 ASTOBJ_CONTAINER_COMPONENTS(struct oh323_peer);
00211 } peerl;
00212
00213
00214 static struct h323_alias_list {
00215 ASTOBJ_CONTAINER_COMPONENTS(struct oh323_alias);
00216 } aliasl;
00217
00218
00219 static struct ast_sched_context *sched;
00220 static struct io_context *io;
00221
00222 AST_MUTEX_DEFINE_STATIC(iflock);
00223
00224
00225
00226 AST_MUTEX_DEFINE_STATIC(monlock);
00227
00228
00229 AST_MUTEX_DEFINE_STATIC(caplock);
00230
00231
00232 AST_MUTEX_DEFINE_STATIC(h323_reload_lock);
00233 static int h323_reloading = 0;
00234
00235
00236
00237 static pthread_t monitor_thread = AST_PTHREADT_NULL;
00238 static int restart_monitor(void);
00239 static int h323_do_reload(void);
00240
00241 static void delete_users(void);
00242 static void delete_aliases(void);
00243 static void prune_peers(void);
00244
00245 static struct ast_channel *oh323_request(const char *type, struct ast_format_cap *cap, const struct ast_channel *requestor, const char *dest, int *cause);
00246 static int oh323_digit_begin(struct ast_channel *c, char digit);
00247 static int oh323_digit_end(struct ast_channel *c, char digit, unsigned int duration);
00248 static int oh323_call(struct ast_channel *c, const char *dest, int timeout);
00249 static int oh323_hangup(struct ast_channel *c);
00250 static int oh323_answer(struct ast_channel *c);
00251 static struct ast_frame *oh323_read(struct ast_channel *c);
00252 static int oh323_write(struct ast_channel *c, struct ast_frame *frame);
00253 static int oh323_indicate(struct ast_channel *c, int condition, const void *data, size_t datalen);
00254 static int oh323_fixup(struct ast_channel *oldchan, struct ast_channel *newchan);
00255
00256 static struct ast_channel_tech oh323_tech = {
00257 .type = "H323",
00258 .description = tdesc,
00259 .properties = AST_CHAN_TP_WANTSJITTER | AST_CHAN_TP_CREATESJITTER,
00260 .requester = oh323_request,
00261 .send_digit_begin = oh323_digit_begin,
00262 .send_digit_end = oh323_digit_end,
00263 .call = oh323_call,
00264 .hangup = oh323_hangup,
00265 .answer = oh323_answer,
00266 .read = oh323_read,
00267 .write = oh323_write,
00268 .indicate = oh323_indicate,
00269 .fixup = oh323_fixup,
00270 .bridge = ast_rtp_instance_bridge,
00271 };
00272
00273 static const char* redirectingreason2str(int redirectingreason)
00274 {
00275 switch (redirectingreason) {
00276 case 0:
00277 return "UNKNOWN";
00278 case 1:
00279 return "BUSY";
00280 case 2:
00281 return "NO_REPLY";
00282 case 0xF:
00283 return "UNCONDITIONAL";
00284 default:
00285 return "NOREDIRECT";
00286 }
00287 }
00288
00289 static void oh323_destroy_alias(struct oh323_alias *alias)
00290 {
00291 if (h323debug)
00292 ast_debug(1, "Destroying alias '%s'\n", alias->name);
00293 ast_free(alias);
00294 }
00295
00296 static void oh323_destroy_user(struct oh323_user *user)
00297 {
00298 if (h323debug)
00299 ast_debug(1, "Destroying user '%s'\n", user->name);
00300 ast_free_ha(user->ha);
00301 ast_free(user);
00302 }
00303
00304 static void oh323_destroy_peer(struct oh323_peer *peer)
00305 {
00306 if (h323debug)
00307 ast_debug(1, "Destroying peer '%s'\n", peer->name);
00308 ast_free_ha(peer->ha);
00309 ast_free(peer);
00310 }
00311
00312 static int oh323_simulate_dtmf_end(const void *data)
00313 {
00314 struct oh323_pvt *pvt = (struct oh323_pvt *)data;
00315
00316 if (pvt) {
00317 ast_mutex_lock(&pvt->lock);
00318
00319 while (pvt->owner && ast_channel_trylock(pvt->owner)) {
00320 DEADLOCK_AVOIDANCE(&pvt->lock);
00321 }
00322
00323 if (pvt->owner) {
00324 struct ast_frame f = {
00325 .frametype = AST_FRAME_DTMF_END,
00326 .subclass.integer = pvt->curDTMF,
00327 .samples = 0,
00328 .src = "SIMULATE_DTMF_END",
00329 };
00330 ast_queue_frame(pvt->owner, &f);
00331 ast_channel_unlock(pvt->owner);
00332 }
00333
00334 pvt->DTMFsched = -1;
00335 ast_mutex_unlock(&pvt->lock);
00336 }
00337
00338 return 0;
00339 }
00340
00341
00342 static void __oh323_update_info(struct ast_channel *c, struct oh323_pvt *pvt)
00343 {
00344 h323_format chan_nativeformats_bits = ast_format_cap_to_old_bitfield(c->nativeformats);
00345 if (chan_nativeformats_bits != pvt->nativeformats) {
00346 if (h323debug)
00347 ast_debug(1, "Preparing %s for new native format\n", ast_channel_name(c));
00348 ast_format_cap_from_old_bitfield(c->nativeformats, pvt->nativeformats);
00349 ast_set_read_format(c, &c->readformat);
00350 ast_set_write_format(c, &c->writeformat);
00351 }
00352 if (pvt->needhangup) {
00353 if (h323debug)
00354 ast_debug(1, "Process pending hangup for %s\n", ast_channel_name(c));
00355 c->_softhangup |= AST_SOFTHANGUP_DEV;
00356 c->hangupcause = pvt->hangupcause;
00357 ast_queue_hangup_with_cause(c, pvt->hangupcause);
00358 pvt->needhangup = 0;
00359 pvt->newstate = pvt->newcontrol = pvt->newdigit = pvt->DTMFsched = -1;
00360 }
00361 if (pvt->newstate >= 0) {
00362 ast_setstate(c, pvt->newstate);
00363 pvt->newstate = -1;
00364 }
00365 if (pvt->newcontrol >= 0) {
00366 ast_queue_control(c, pvt->newcontrol);
00367 pvt->newcontrol = -1;
00368 }
00369 if (pvt->newdigit >= 0) {
00370 struct ast_frame f = {
00371 .frametype = AST_FRAME_DTMF_END,
00372 .subclass.integer = pvt->newdigit,
00373 .samples = pvt->newduration * 8,
00374 .len = pvt->newduration,
00375 .src = "UPDATE_INFO",
00376 };
00377 if (pvt->newdigit == ' ') {
00378 f.subclass.integer = pvt->curDTMF;
00379 if (pvt->DTMFsched >= 0) {
00380 AST_SCHED_DEL(sched, pvt->DTMFsched);
00381 }
00382 } else {
00383 if (pvt->newduration) {
00384 f.frametype = AST_FRAME_DTMF_BEGIN;
00385 AST_SCHED_DEL(sched, pvt->DTMFsched);
00386 pvt->DTMFsched = ast_sched_add(sched, pvt->newduration, oh323_simulate_dtmf_end, pvt);
00387 if (h323debug)
00388 ast_log(LOG_DTMF, "Scheduled DTMF END simulation for %d ms, id=%d\n", pvt->newduration, pvt->DTMFsched);
00389 }
00390 pvt->curDTMF = pvt->newdigit;
00391 }
00392 ast_queue_frame(c, &f);
00393 pvt->newdigit = -1;
00394 }
00395 if (pvt->update_rtp_info > 0) {
00396 if (pvt->rtp) {
00397 ast_jb_configure(c, &global_jbconf);
00398 ast_channel_set_fd(c, 0, ast_rtp_instance_fd(pvt->rtp, 0));
00399 ast_channel_set_fd(c, 1, ast_rtp_instance_fd(pvt->rtp, 1));
00400 ast_queue_frame(pvt->owner, &ast_null_frame);
00401 }
00402 pvt->update_rtp_info = -1;
00403 }
00404 }
00405
00406
00407 static void oh323_update_info(struct ast_channel *c)
00408 {
00409 struct oh323_pvt *pvt = c->tech_pvt;
00410
00411 if (pvt) {
00412 ast_mutex_lock(&pvt->lock);
00413 __oh323_update_info(c, pvt);
00414 ast_mutex_unlock(&pvt->lock);
00415 }
00416 }
00417
00418 static void cleanup_call_details(call_details_t *cd)
00419 {
00420 if (cd->call_token) {
00421 ast_free(cd->call_token);
00422 cd->call_token = NULL;
00423 }
00424 if (cd->call_source_aliases) {
00425 ast_free(cd->call_source_aliases);
00426 cd->call_source_aliases = NULL;
00427 }
00428 if (cd->call_dest_alias) {
00429 ast_free(cd->call_dest_alias);
00430 cd->call_dest_alias = NULL;
00431 }
00432 if (cd->call_source_name) {
00433 ast_free(cd->call_source_name);
00434 cd->call_source_name = NULL;
00435 }
00436 if (cd->call_source_e164) {
00437 ast_free(cd->call_source_e164);
00438 cd->call_source_e164 = NULL;
00439 }
00440 if (cd->call_dest_e164) {
00441 ast_free(cd->call_dest_e164);
00442 cd->call_dest_e164 = NULL;
00443 }
00444 if (cd->sourceIp) {
00445 ast_free(cd->sourceIp);
00446 cd->sourceIp = NULL;
00447 }
00448 if (cd->redirect_number) {
00449 ast_free(cd->redirect_number);
00450 cd->redirect_number = NULL;
00451 }
00452 }
00453
00454 static void __oh323_destroy(struct oh323_pvt *pvt)
00455 {
00456 struct oh323_pvt *cur, *prev = NULL;
00457
00458 AST_SCHED_DEL(sched, pvt->DTMFsched);
00459
00460 if (pvt->rtp) {
00461 ast_rtp_instance_destroy(pvt->rtp);
00462 }
00463
00464
00465 if (pvt->vad) {
00466 ast_dsp_free(pvt->vad);
00467 }
00468 cleanup_call_details(&pvt->cd);
00469
00470
00471 if (pvt->owner) {
00472 ast_channel_lock(pvt->owner);
00473 if (h323debug)
00474 ast_debug(1, "Detaching from %s\n", ast_channel_name(pvt->owner));
00475 pvt->owner->tech_pvt = NULL;
00476 ast_channel_unlock(pvt->owner);
00477 }
00478 cur = iflist;
00479 while(cur) {
00480 if (cur == pvt) {
00481 if (prev)
00482 prev->next = cur->next;
00483 else
00484 iflist = cur->next;
00485 break;
00486 }
00487 prev = cur;
00488 cur = cur->next;
00489 }
00490 if (!cur) {
00491 ast_log(LOG_WARNING, "%p is not in list?!?! \n", cur);
00492 } else {
00493 ast_mutex_unlock(&pvt->lock);
00494 ast_mutex_destroy(&pvt->lock);
00495 ast_free(pvt);
00496 }
00497 }
00498
00499 static void oh323_destroy(struct oh323_pvt *pvt)
00500 {
00501 if (h323debug) {
00502 ast_debug(1, "Destroying channel %s\n", (pvt->owner ? ast_channel_name(pvt->owner) : "<unknown>"));
00503 }
00504 ast_mutex_lock(&iflock);
00505 ast_mutex_lock(&pvt->lock);
00506 __oh323_destroy(pvt);
00507 ast_mutex_unlock(&iflock);
00508 }
00509
00510 static int oh323_digit_begin(struct ast_channel *c, char digit)
00511 {
00512 struct oh323_pvt *pvt = (struct oh323_pvt *) c->tech_pvt;
00513 char *token;
00514
00515 if (!pvt) {
00516 ast_log(LOG_ERROR, "No private structure?! This is bad\n");
00517 return -1;
00518 }
00519 ast_mutex_lock(&pvt->lock);
00520 if (pvt->rtp &&
00521 (((pvt->options.dtmfmode & H323_DTMF_RFC2833) && pvt->dtmf_pt[0])
00522 )) {
00523
00524 if (h323debug) {
00525 ast_log(LOG_DTMF, "Begin sending out-of-band digit %c on %s\n", digit, ast_channel_name(c));
00526 }
00527 ast_rtp_instance_dtmf_begin(pvt->rtp, digit);
00528 ast_mutex_unlock(&pvt->lock);
00529 } else if (pvt->txDtmfDigit != digit) {
00530
00531 if (h323debug) {
00532 ast_log(LOG_DTMF, "Begin sending inband digit %c on %s\n", digit, ast_channel_name(c));
00533 }
00534 pvt->txDtmfDigit = digit;
00535 token = pvt->cd.call_token ? ast_strdup(pvt->cd.call_token) : NULL;
00536 ast_mutex_unlock(&pvt->lock);
00537 h323_send_tone(token, digit);
00538 if (token) {
00539 ast_free(token);
00540 }
00541 } else
00542 ast_mutex_unlock(&pvt->lock);
00543 oh323_update_info(c);
00544 return 0;
00545 }
00546
00547
00548
00549
00550
00551 static int oh323_digit_end(struct ast_channel *c, char digit, unsigned int duration)
00552 {
00553 struct oh323_pvt *pvt = (struct oh323_pvt *) c->tech_pvt;
00554 char *token;
00555
00556 if (!pvt) {
00557 ast_log(LOG_ERROR, "No private structure?! This is bad\n");
00558 return -1;
00559 }
00560 ast_mutex_lock(&pvt->lock);
00561 if (pvt->rtp && (pvt->options.dtmfmode & H323_DTMF_RFC2833) && ((pvt->dtmf_pt[0] > 0) || (pvt->dtmf_pt[0] > 0))) {
00562
00563 if (h323debug) {
00564 ast_log(LOG_DTMF, "End sending out-of-band digit %c on %s, duration %d\n", digit, ast_channel_name(c), duration);
00565 }
00566 ast_rtp_instance_dtmf_end(pvt->rtp, digit);
00567 ast_mutex_unlock(&pvt->lock);
00568 } else {
00569
00570 if (h323debug) {
00571 ast_log(LOG_DTMF, "End sending inband digit %c on %s, duration %d\n", digit, ast_channel_name(c), duration);
00572 }
00573 pvt->txDtmfDigit = ' ';
00574 token = pvt->cd.call_token ? ast_strdup(pvt->cd.call_token) : NULL;
00575 ast_mutex_unlock(&pvt->lock);
00576 h323_send_tone(token, ' ');
00577 if (token) {
00578 ast_free(token);
00579 }
00580 }
00581 oh323_update_info(c);
00582 return 0;
00583 }
00584
00585
00586
00587
00588
00589
00590 static int oh323_call(struct ast_channel *c, const char *dest, int timeout)
00591 {
00592 int res = 0;
00593 struct oh323_pvt *pvt = (struct oh323_pvt *)c->tech_pvt;
00594 const char *addr;
00595 char called_addr[1024];
00596
00597 if (h323debug) {
00598 ast_debug(1, "Calling to %s on %s\n", dest, ast_channel_name(c));
00599 }
00600 if ((c->_state != AST_STATE_DOWN) && (c->_state != AST_STATE_RESERVED)) {
00601 ast_log(LOG_WARNING, "Line is already in use (%s)\n", ast_channel_name(c));
00602 return -1;
00603 }
00604 ast_mutex_lock(&pvt->lock);
00605 if (!gatekeeper_disable) {
00606 if (ast_strlen_zero(pvt->exten)) {
00607 ast_copy_string(called_addr, dest, sizeof(called_addr));
00608 } else {
00609 snprintf(called_addr, sizeof(called_addr), "%s@%s", pvt->exten, dest);
00610 }
00611 } else {
00612 res = htons(pvt->sa.sin_port);
00613 addr = ast_inet_ntoa(pvt->sa.sin_addr);
00614 if (ast_strlen_zero(pvt->exten)) {
00615 snprintf(called_addr, sizeof(called_addr), "%s:%d", addr, res);
00616 } else {
00617 snprintf(called_addr, sizeof(called_addr), "%s@%s:%d", pvt->exten, addr, res);
00618 }
00619 }
00620
00621 called_addr[sizeof(called_addr) - 1] = '\0';
00622
00623 if (c->connected.id.number.valid && c->connected.id.number.str) {
00624 ast_copy_string(pvt->options.cid_num, c->connected.id.number.str, sizeof(pvt->options.cid_num));
00625 }
00626
00627 if (c->connected.id.name.valid && c->connected.id.name.str) {
00628 ast_copy_string(pvt->options.cid_name, c->connected.id.name.str, sizeof(pvt->options.cid_name));
00629 }
00630
00631 if (c->redirecting.from.number.valid && c->redirecting.from.number.str) {
00632 ast_copy_string(pvt->options.cid_rdnis, c->redirecting.from.number.str, sizeof(pvt->options.cid_rdnis));
00633 }
00634
00635 pvt->options.presentation = ast_party_id_presentation(&c->connected.id);
00636 pvt->options.type_of_number = c->connected.id.number.plan;
00637
00638 if ((addr = pbx_builtin_getvar_helper(c, "PRIREDIRECTREASON"))) {
00639 if (!strcasecmp(addr, "UNKNOWN"))
00640 pvt->options.redirect_reason = 0;
00641 else if (!strcasecmp(addr, "BUSY"))
00642 pvt->options.redirect_reason = 1;
00643 else if (!strcasecmp(addr, "NO_REPLY"))
00644 pvt->options.redirect_reason = 2;
00645 else if (!strcasecmp(addr, "UNCONDITIONAL"))
00646 pvt->options.redirect_reason = 15;
00647 else
00648 pvt->options.redirect_reason = -1;
00649 } else
00650 pvt->options.redirect_reason = -1;
00651
00652 pvt->options.transfer_capability = c->transfercapability;
00653
00654
00655 pvt->outgoing = 1;
00656
00657 ast_verb(3, "Requested transfer capability: 0x%.2x - %s\n", c->transfercapability, ast_transfercapability2str(c->transfercapability));
00658 if (h323debug)
00659 ast_debug(1, "Placing outgoing call to %s, %d/%d\n", called_addr, pvt->options.dtmfcodec[0], pvt->options.dtmfcodec[1]);
00660 ast_mutex_unlock(&pvt->lock);
00661 res = h323_make_call(called_addr, &(pvt->cd), &pvt->options);
00662 if (res) {
00663 ast_log(LOG_NOTICE, "h323_make_call failed(%s)\n", ast_channel_name(c));
00664 return -1;
00665 }
00666 oh323_update_info(c);
00667 return 0;
00668 }
00669
00670 static int oh323_answer(struct ast_channel *c)
00671 {
00672 int res;
00673 struct oh323_pvt *pvt = (struct oh323_pvt *) c->tech_pvt;
00674 char *token;
00675
00676 if (h323debug)
00677 ast_debug(1, "Answering on %s\n", ast_channel_name(c));
00678
00679 ast_mutex_lock(&pvt->lock);
00680 token = pvt->cd.call_token ? ast_strdup(pvt->cd.call_token) : NULL;
00681 ast_mutex_unlock(&pvt->lock);
00682 res = h323_answering_call(token, 0);
00683 if (token)
00684 ast_free(token);
00685
00686 oh323_update_info(c);
00687 if (c->_state != AST_STATE_UP) {
00688 ast_setstate(c, AST_STATE_UP);
00689 }
00690 return res;
00691 }
00692
00693 static int oh323_hangup(struct ast_channel *c)
00694 {
00695 struct oh323_pvt *pvt = (struct oh323_pvt *) c->tech_pvt;
00696 int q931cause = AST_CAUSE_NORMAL_CLEARING;
00697 char *call_token;
00698
00699
00700 if (h323debug)
00701 ast_debug(1, "Hanging up and scheduling destroy of call %s\n", ast_channel_name(c));
00702
00703 if (!c->tech_pvt) {
00704 ast_log(LOG_WARNING, "Asked to hangup channel not connected\n");
00705 return 0;
00706 }
00707 ast_mutex_lock(&pvt->lock);
00708
00709 if (pvt->owner != c) {
00710 ast_log(LOG_WARNING, "Huh? We aren't the owner?\n");
00711 ast_mutex_unlock(&pvt->lock);
00712 return 0;
00713 }
00714
00715 pvt->owner = NULL;
00716 c->tech_pvt = NULL;
00717
00718 if (c->hangupcause) {
00719 q931cause = c->hangupcause;
00720 } else {
00721 const char *cause = pbx_builtin_getvar_helper(c, "DIALSTATUS");
00722 if (cause) {
00723 if (!strcmp(cause, "CONGESTION")) {
00724 q931cause = AST_CAUSE_NORMAL_CIRCUIT_CONGESTION;
00725 } else if (!strcmp(cause, "BUSY")) {
00726 q931cause = AST_CAUSE_USER_BUSY;
00727 } else if (!strcmp(cause, "CHANISUNVAIL")) {
00728 q931cause = AST_CAUSE_REQUESTED_CHAN_UNAVAIL;
00729 } else if (!strcmp(cause, "NOANSWER")) {
00730 q931cause = AST_CAUSE_NO_ANSWER;
00731 } else if (!strcmp(cause, "CANCEL")) {
00732 q931cause = AST_CAUSE_CALL_REJECTED;
00733 }
00734 }
00735 }
00736
00737
00738 if (!pvt->alreadygone && !pvt->hangupcause) {
00739 call_token = pvt->cd.call_token ? ast_strdup(pvt->cd.call_token) : NULL;
00740 if (call_token) {
00741
00742 ast_mutex_unlock(&pvt->lock);
00743 if (h323_clear_call(call_token, q931cause)) {
00744 ast_log(LOG_WARNING, "ClearCall failed.\n");
00745 }
00746 ast_free(call_token);
00747 ast_mutex_lock(&pvt->lock);
00748 }
00749 }
00750 pvt->needdestroy = 1;
00751 ast_mutex_unlock(&pvt->lock);
00752
00753
00754 ast_module_unref(ast_module_info->self);
00755
00756 return 0;
00757 }
00758
00759
00760 static struct ast_frame *oh323_rtp_read(struct oh323_pvt *pvt)
00761 {
00762 struct ast_frame *f;
00763
00764
00765 if (pvt->options.nat) {
00766 ast_rtp_instance_set_prop(pvt->rtp, AST_RTP_PROPERTY_NAT, pvt->options.nat);
00767 pvt->options.nat = 0;
00768 }
00769
00770 f = ast_rtp_instance_read(pvt->rtp, 0);
00771
00772 if (f && (f->frametype == AST_FRAME_DTMF) && !(pvt->options.dtmfmode & (H323_DTMF_RFC2833 | H323_DTMF_CISCO))) {
00773 return &ast_null_frame;
00774 }
00775 if (f && pvt->owner) {
00776
00777 if (f->frametype == AST_FRAME_VOICE) {
00778 if (!ast_format_cap_iscompatible(pvt->owner->nativeformats, &f->subclass.format)) {
00779
00780 if (ast_channel_trylock(pvt->owner)) {
00781 ast_log(LOG_NOTICE, "Format changed but channel is locked. Ignoring frame...\n");
00782 return &ast_null_frame;
00783 }
00784 if (h323debug)
00785 ast_debug(1, "Oooh, format changed to '%s'\n", ast_getformatname(&f->subclass.format));
00786 ast_format_cap_set(pvt->owner->nativeformats, &f->subclass.format);
00787
00788 pvt->nativeformats = ast_format_to_old_bitfield(&f->subclass.format);
00789
00790 ast_set_read_format(pvt->owner, &pvt->owner->readformat);
00791 ast_set_write_format(pvt->owner, &pvt->owner->writeformat);
00792 ast_channel_unlock(pvt->owner);
00793 }
00794
00795 if ((pvt->options.dtmfmode & H323_DTMF_INBAND) && pvt->vad) {
00796 if ((pvt->nativeformats & (AST_FORMAT_SLINEAR | AST_FORMAT_ALAW | AST_FORMAT_ULAW))) {
00797 if (!ast_channel_trylock(pvt->owner)) {
00798 f = ast_dsp_process(pvt->owner, pvt->vad, f);
00799 ast_channel_unlock(pvt->owner);
00800 }
00801 else
00802 ast_log(LOG_NOTICE, "Unable to process inband DTMF while channel is locked\n");
00803 } else if (pvt->nativeformats && !pvt->noInbandDtmf) {
00804 ast_log(LOG_NOTICE, "Inband DTMF is not supported on codec %s. Use RFC2833\n", ast_getformatname(&f->subclass.format));
00805 pvt->noInbandDtmf = 1;
00806 }
00807 if (f &&(f->frametype == AST_FRAME_DTMF)) {
00808 if (h323debug)
00809 ast_log(LOG_DTMF, "Received in-band digit %c.\n", f->subclass.integer);
00810 }
00811 }
00812 }
00813 }
00814 return f;
00815 }
00816
00817 static struct ast_frame *oh323_read(struct ast_channel *c)
00818 {
00819 struct ast_frame *fr;
00820 struct oh323_pvt *pvt = (struct oh323_pvt *)c->tech_pvt;
00821 ast_mutex_lock(&pvt->lock);
00822 __oh323_update_info(c, pvt);
00823 switch(c->fdno) {
00824 case 0:
00825 fr = oh323_rtp_read(pvt);
00826 break;
00827 case 1:
00828 if (pvt->rtp)
00829 fr = ast_rtp_instance_read(pvt->rtp, 1);
00830 else
00831 fr = &ast_null_frame;
00832 break;
00833 default:
00834 ast_log(LOG_ERROR, "Unable to handle fd %d on channel %s\n", c->fdno, ast_channel_name(c));
00835 fr = &ast_null_frame;
00836 break;
00837 }
00838 ast_mutex_unlock(&pvt->lock);
00839 return fr;
00840 }
00841
00842 static int oh323_write(struct ast_channel *c, struct ast_frame *frame)
00843 {
00844 struct oh323_pvt *pvt = (struct oh323_pvt *) c->tech_pvt;
00845 int res = 0;
00846 if (frame->frametype != AST_FRAME_VOICE) {
00847 if (frame->frametype == AST_FRAME_IMAGE) {
00848 return 0;
00849 } else {
00850 ast_log(LOG_WARNING, "Can't send %d type frames with H323 write\n", frame->frametype);
00851 return 0;
00852 }
00853 } else {
00854 if (!(ast_format_cap_iscompatible(c->nativeformats, &frame->subclass.format))) {
00855 char tmp[256];
00856 ast_log(LOG_WARNING, "Asked to transmit frame type '%s', while native formats is '%s' (read/write = %s/%s)\n",
00857 ast_getformatname(&frame->subclass.format), ast_getformatname_multiple(tmp, sizeof(tmp), c->nativeformats), ast_getformatname(&c->readformat), ast_getformatname(&c->writeformat));
00858 return 0;
00859 }
00860 }
00861 if (pvt) {
00862 ast_mutex_lock(&pvt->lock);
00863 if (pvt->rtp && !pvt->recvonly)
00864 res = ast_rtp_instance_write(pvt->rtp, frame);
00865 __oh323_update_info(c, pvt);
00866 ast_mutex_unlock(&pvt->lock);
00867 }
00868 return res;
00869 }
00870
00871 static int oh323_indicate(struct ast_channel *c, int condition, const void *data, size_t datalen)
00872 {
00873
00874 struct oh323_pvt *pvt = (struct oh323_pvt *) c->tech_pvt;
00875 char *token = (char *)NULL;
00876 int res = -1;
00877 int got_progress;
00878
00879 ast_mutex_lock(&pvt->lock);
00880 token = (pvt->cd.call_token ? ast_strdup(pvt->cd.call_token) : NULL);
00881 got_progress = pvt->got_progress;
00882 if (condition == AST_CONTROL_PROGRESS)
00883 pvt->got_progress = 1;
00884 else if ((condition == AST_CONTROL_BUSY) || (condition == AST_CONTROL_CONGESTION))
00885 pvt->alreadygone = 1;
00886 ast_mutex_unlock(&pvt->lock);
00887
00888 if (h323debug)
00889 ast_debug(1, "OH323: Indicating %d on %s (%s)\n", condition, token, ast_channel_name(c));
00890
00891 switch(condition) {
00892 case AST_CONTROL_RINGING:
00893 if (c->_state == AST_STATE_RING || c->_state == AST_STATE_RINGING) {
00894 h323_send_alerting(token);
00895 res = (got_progress ? 0 : -1);
00896 }
00897 break;
00898 case AST_CONTROL_PROGRESS:
00899 if (c->_state != AST_STATE_UP) {
00900
00901 if (!got_progress)
00902 h323_send_progress(token);
00903 res = 0;
00904 }
00905 break;
00906 case AST_CONTROL_BUSY:
00907 if (c->_state != AST_STATE_UP) {
00908 h323_answering_call(token, 1);
00909 ast_softhangup_nolock(c, AST_SOFTHANGUP_DEV);
00910 res = 0;
00911 }
00912 break;
00913 case AST_CONTROL_INCOMPLETE:
00914
00915
00916
00917 case AST_CONTROL_CONGESTION:
00918 if (c->_state != AST_STATE_UP) {
00919 h323_answering_call(token, 1);
00920 ast_softhangup_nolock(c, AST_SOFTHANGUP_DEV);
00921 res = 0;
00922 }
00923 break;
00924 case AST_CONTROL_HOLD:
00925 h323_hold_call(token, 1);
00926
00927 ast_moh_start(c, data, NULL);
00928 res = 0;
00929 break;
00930 case AST_CONTROL_UNHOLD:
00931 h323_hold_call(token, 0);
00932 ast_moh_stop(c);
00933 res = 0;
00934 break;
00935 case AST_CONTROL_SRCUPDATE:
00936 ast_rtp_instance_update_source(pvt->rtp);
00937 res = 0;
00938 break;
00939 case AST_CONTROL_SRCCHANGE:
00940 ast_rtp_instance_change_source(pvt->rtp);
00941 res = 0;
00942 break;
00943 case AST_CONTROL_PROCEEDING:
00944 case -1:
00945 break;
00946 default:
00947 ast_log(LOG_WARNING, "OH323: Don't know how to indicate condition %d on %s\n", condition, token);
00948 break;
00949 }
00950
00951 if (h323debug)
00952 ast_debug(1, "OH323: Indicated %d on %s, res=%d\n", condition, token, res);
00953 if (token)
00954 ast_free(token);
00955 oh323_update_info(c);
00956
00957 return res;
00958 }
00959
00960 static int oh323_fixup(struct ast_channel *oldchan, struct ast_channel *newchan)
00961 {
00962 struct oh323_pvt *pvt = (struct oh323_pvt *) newchan->tech_pvt;
00963
00964 ast_mutex_lock(&pvt->lock);
00965 if (pvt->owner != oldchan) {
00966 ast_log(LOG_WARNING, "old channel wasn't %p but was %p\n", oldchan, pvt->owner);
00967 return -1;
00968 }
00969 pvt->owner = newchan;
00970 ast_mutex_unlock(&pvt->lock);
00971 return 0;
00972 }
00973
00974 static int __oh323_rtp_create(struct oh323_pvt *pvt)
00975 {
00976 struct ast_sockaddr our_addr;
00977
00978 if (pvt->rtp)
00979 return 0;
00980
00981 {
00982 struct ast_sockaddr tmp;
00983
00984 ast_sockaddr_from_sin(&tmp, &bindaddr);
00985 if (ast_find_ourip(&our_addr, &tmp, AF_INET)) {
00986 ast_mutex_unlock(&pvt->lock);
00987 ast_log(LOG_ERROR, "Unable to locate local IP address for RTP stream\n");
00988 return -1;
00989 }
00990 }
00991 our_addr.ss.ss_family = AF_INET;
00992 pvt->rtp = ast_rtp_instance_new("asterisk", sched, &our_addr, NULL);
00993 if (!pvt->rtp) {
00994 ast_mutex_unlock(&pvt->lock);
00995 ast_log(LOG_WARNING, "Unable to create RTP session: %s\n", strerror(errno));
00996 return -1;
00997 }
00998 if (h323debug)
00999 ast_debug(1, "Created RTP channel\n");
01000
01001 ast_rtp_instance_set_qos(pvt->rtp, tos, cos, "H323 RTP");
01002
01003 if (h323debug)
01004 ast_debug(1, "Setting NAT on RTP to %d\n", pvt->options.nat);
01005 ast_rtp_instance_set_prop(pvt->rtp, AST_RTP_PROPERTY_NAT, pvt->options.nat);
01006
01007 if (pvt->dtmf_pt[0] > 0)
01008 ast_rtp_codecs_payloads_set_rtpmap_type(ast_rtp_instance_get_codecs(pvt->rtp), pvt->rtp, pvt->dtmf_pt[0], "audio", "telephone-event", 0);
01009 if (pvt->dtmf_pt[1] > 0)
01010 ast_rtp_codecs_payloads_set_rtpmap_type(ast_rtp_instance_get_codecs(pvt->rtp), pvt->rtp, pvt->dtmf_pt[1], "audio", "cisco-telephone-event", 0);
01011
01012 if (pvt->peercapability)
01013 ast_rtp_codecs_packetization_set(ast_rtp_instance_get_codecs(pvt->rtp), pvt->rtp, &pvt->peer_prefs);
01014
01015 if (pvt->owner && !ast_channel_trylock(pvt->owner)) {
01016 ast_jb_configure(pvt->owner, &global_jbconf);
01017 ast_channel_set_fd(pvt->owner, 0, ast_rtp_instance_fd(pvt->rtp, 0));
01018 ast_channel_set_fd(pvt->owner, 1, ast_rtp_instance_fd(pvt->rtp, 1));
01019 ast_queue_frame(pvt->owner, &ast_null_frame);
01020 ast_channel_unlock(pvt->owner);
01021 } else
01022 pvt->update_rtp_info = 1;
01023
01024 return 0;
01025 }
01026
01027
01028 static struct ast_channel *__oh323_new(struct oh323_pvt *pvt, int state, const char *host, const char *linkedid)
01029 {
01030 struct ast_channel *ch;
01031 char *cid_num, *cid_name;
01032 h323_format fmt;
01033 struct ast_format tmpfmt;
01034
01035 if (!ast_strlen_zero(pvt->options.cid_num))
01036 cid_num = pvt->options.cid_num;
01037 else
01038 cid_num = pvt->cd.call_source_e164;
01039
01040 if (!ast_strlen_zero(pvt->options.cid_name))
01041 cid_name = pvt->options.cid_name;
01042 else
01043 cid_name = pvt->cd.call_source_name;
01044
01045
01046 ast_mutex_unlock(&pvt->lock);
01047 ch = ast_channel_alloc(1, state, cid_num, cid_name, pvt->accountcode, pvt->exten, pvt->context, linkedid, pvt->amaflags, "H323/%s", host);
01048
01049 ast_module_ref(ast_module_info->self);
01050 ast_mutex_lock(&pvt->lock);
01051 if (ch) {
01052 ch->tech = &oh323_tech;
01053 if (!(fmt = pvt->jointcapability) && !(fmt = pvt->options.capability))
01054 fmt = global_options.capability;
01055
01056 ast_format_cap_from_old_bitfield(ch->nativeformats, fmt);
01057 ast_codec_choose(&pvt->options.prefs, ch->nativeformats, 1, &tmpfmt);
01058
01059 ast_format_cap_set(ch->nativeformats, &tmpfmt);
01060
01061 pvt->nativeformats = ast_format_cap_to_old_bitfield(ch->nativeformats);
01062 ast_best_codec(ch->nativeformats, &tmpfmt);
01063 ast_format_copy(&ch->writeformat, &tmpfmt);
01064 ast_format_copy(&ch->rawwriteformat, &tmpfmt);
01065 ast_format_copy(&ch->readformat, &tmpfmt);
01066 ast_format_copy(&ch->rawreadformat, &tmpfmt);
01067 if (!pvt->rtp)
01068 __oh323_rtp_create(pvt);
01069 #if 0
01070 ast_channel_set_fd(ch, 0, ast_rtp_instance_fd(pvt->rtp, 0));
01071 ast_channel_set_fd(ch, 1, ast_rtp_instance_fd(pvt->rtp, 1));
01072 #endif
01073 #ifdef VIDEO_SUPPORT
01074 if (pvt->vrtp) {
01075 ast_channel_set_fd(ch, 2, ast_rtp_instance_fd(pvt->vrtp, 0));
01076 ast_channel_set_fd(ch, 3, ast_rtp_instance_fd(pvt->vrtp, 1));
01077 }
01078 #endif
01079 #ifdef T38_SUPPORT
01080 if (pvt->udptl) {
01081 ast_channel_set_fd(ch, 4, ast_udptl_fd(pvt->udptl));
01082 }
01083 #endif
01084 if (state == AST_STATE_RING) {
01085 ch->rings = 1;
01086 }
01087
01088 if (pvt->options.dtmfmode & H323_DTMF_INBAND) {
01089 pvt->vad = ast_dsp_new();
01090 ast_dsp_set_features(pvt->vad, DSP_FEATURE_DIGIT_DETECT);
01091 }
01092
01093 ch->tech_pvt = pvt;
01094
01095 pvt->owner = ch;
01096
01097 ast_copy_string(ch->context, pvt->context, sizeof(ch->context));
01098 ast_copy_string(ch->exten, pvt->exten, sizeof(ch->exten));
01099 ch->priority = 1;
01100 if (!ast_strlen_zero(pvt->accountcode)) {
01101 ast_channel_accountcode_set(ch, pvt->accountcode);
01102 }
01103 if (pvt->amaflags) {
01104 ch->amaflags = pvt->amaflags;
01105 }
01106
01107
01108
01109 if (!ast_strlen_zero(cid_num)) {
01110 ch->caller.ani.number.valid = 1;
01111 ch->caller.ani.number.str = ast_strdup(cid_num);
01112 }
01113
01114 if (pvt->cd.redirect_reason >= 0) {
01115 ch->redirecting.from.number.valid = 1;
01116 ch->redirecting.from.number.str = ast_strdup(pvt->cd.redirect_number);
01117 pbx_builtin_setvar_helper(ch, "PRIREDIRECTREASON", redirectingreason2str(pvt->cd.redirect_reason));
01118 }
01119 ch->caller.id.name.presentation = pvt->cd.presentation;
01120 ch->caller.id.number.presentation = pvt->cd.presentation;
01121 ch->caller.id.number.plan = pvt->cd.type_of_number;
01122
01123 if (!ast_strlen_zero(pvt->exten) && strcmp(pvt->exten, "s")) {
01124 ch->dialed.number.str = ast_strdup(pvt->exten);
01125 }
01126 if (pvt->cd.transfer_capability >= 0)
01127 ch->transfercapability = pvt->cd.transfer_capability;
01128 if (state != AST_STATE_DOWN) {
01129 if (ast_pbx_start(ch)) {
01130 ast_log(LOG_WARNING, "Unable to start PBX on %s\n", ast_channel_name(ch));
01131 ast_hangup(ch);
01132 ch = NULL;
01133 }
01134 }
01135 } else {
01136 ast_log(LOG_WARNING, "Unable to allocate channel structure\n");
01137 }
01138 return ch;
01139 }
01140
01141 static struct oh323_pvt *oh323_alloc(int callid)
01142 {
01143 struct oh323_pvt *pvt;
01144
01145 pvt = ast_calloc(1, sizeof(*pvt));
01146 if (!pvt) {
01147 ast_log(LOG_ERROR, "Couldn't allocate private structure. This is bad\n");
01148 return NULL;
01149 }
01150 pvt->cd.redirect_reason = -1;
01151 pvt->cd.transfer_capability = -1;
01152
01153 if (!callid) {
01154 if ((pvt->cd).call_token == NULL) {
01155 (pvt->cd).call_token = ast_calloc(1, 128);
01156 }
01157 if (!pvt->cd.call_token) {
01158 ast_log(LOG_ERROR, "Not enough memory to alocate call token\n");
01159 ast_rtp_instance_destroy(pvt->rtp);
01160 ast_free(pvt);
01161 return NULL;
01162 }
01163 memset((char *)(pvt->cd).call_token, 0, 128);
01164 pvt->cd.call_reference = callid;
01165 }
01166 memcpy(&pvt->options, &global_options, sizeof(pvt->options));
01167 pvt->jointcapability = pvt->options.capability;
01168 if (pvt->options.dtmfmode & (H323_DTMF_RFC2833 | H323_DTMF_CISCO)) {
01169 pvt->nonCodecCapability |= AST_RTP_DTMF;
01170 } else {
01171 pvt->nonCodecCapability &= ~AST_RTP_DTMF;
01172 }
01173 ast_copy_string(pvt->context, default_context, sizeof(pvt->context));
01174 pvt->newstate = pvt->newcontrol = pvt->newdigit = pvt->update_rtp_info = pvt->DTMFsched = -1;
01175 ast_mutex_init(&pvt->lock);
01176
01177 ast_mutex_lock(&iflock);
01178 pvt->next = iflist;
01179 iflist = pvt;
01180 ast_mutex_unlock(&iflock);
01181 return pvt;
01182 }
01183
01184 static struct oh323_pvt *find_call_locked(int call_reference, const char *token)
01185 {
01186 struct oh323_pvt *pvt;
01187
01188 ast_mutex_lock(&iflock);
01189 pvt = iflist;
01190 while(pvt) {
01191 if (!pvt->needdestroy && ((signed int)pvt->cd.call_reference == call_reference)) {
01192
01193 if ((token != NULL) && (pvt->cd.call_token != NULL) && (!strcmp(pvt->cd.call_token, token))) {
01194 ast_mutex_lock(&pvt->lock);
01195 ast_mutex_unlock(&iflock);
01196 return pvt;
01197 } else if (token == NULL) {
01198 ast_log(LOG_WARNING, "Call Token is NULL\n");
01199 ast_mutex_lock(&pvt->lock);
01200 ast_mutex_unlock(&iflock);
01201 return pvt;
01202 }
01203 }
01204 pvt = pvt->next;
01205 }
01206 ast_mutex_unlock(&iflock);
01207 return NULL;
01208 }
01209
01210 static int update_state(struct oh323_pvt *pvt, int state, int signal)
01211 {
01212 if (!pvt)
01213 return 0;
01214 if (pvt->owner && !ast_channel_trylock(pvt->owner)) {
01215 if (state >= 0)
01216 ast_setstate(pvt->owner, state);
01217 if (signal >= 0)
01218 ast_queue_control(pvt->owner, signal);
01219 ast_channel_unlock(pvt->owner);
01220 return 1;
01221 }
01222 else {
01223 if (state >= 0)
01224 pvt->newstate = state;
01225 if (signal >= 0)
01226 pvt->newcontrol = signal;
01227 return 0;
01228 }
01229 }
01230
01231 static struct oh323_alias *build_alias(const char *name, struct ast_variable *v, struct ast_variable *alt, int realtime)
01232 {
01233 struct oh323_alias *alias;
01234 int found = 0;
01235
01236 alias = ASTOBJ_CONTAINER_FIND_UNLINK_FULL(&aliasl, name, name, 0, 0, strcasecmp);
01237
01238 if (alias)
01239 found++;
01240 else {
01241 if (!(alias = ast_calloc(1, sizeof(*alias))))
01242 return NULL;
01243 ASTOBJ_INIT(alias);
01244 }
01245 if (!found && name)
01246 ast_copy_string(alias->name, name, sizeof(alias->name));
01247 for (; v || ((v = alt) && !(alt = NULL)); v = v->next) {
01248 if (!strcasecmp(v->name, "e164")) {
01249 ast_copy_string(alias->e164, v->value, sizeof(alias->e164));
01250 } else if (!strcasecmp(v->name, "prefix")) {
01251 ast_copy_string(alias->prefix, v->value, sizeof(alias->prefix));
01252 } else if (!strcasecmp(v->name, "context")) {
01253 ast_copy_string(alias->context, v->value, sizeof(alias->context));
01254 } else if (!strcasecmp(v->name, "secret")) {
01255 ast_copy_string(alias->secret, v->value, sizeof(alias->secret));
01256 } else {
01257 if (strcasecmp(v->value, "h323")) {
01258 ast_log(LOG_WARNING, "Keyword %s does not make sense in type=h323\n", v->name);
01259 }
01260 }
01261 }
01262 ASTOBJ_UNMARK(alias);
01263 return alias;
01264 }
01265
01266 static struct oh323_alias *realtime_alias(const char *alias)
01267 {
01268 struct ast_variable *var, *tmp;
01269 struct oh323_alias *a;
01270
01271 var = ast_load_realtime("h323", "name", alias, SENTINEL);
01272
01273 if (!var)
01274 return NULL;
01275
01276 for (tmp = var; tmp; tmp = tmp->next) {
01277 if (!strcasecmp(tmp->name, "type") &&
01278 !(!strcasecmp(tmp->value, "alias") || !strcasecmp(tmp->value, "h323"))) {
01279 ast_variables_destroy(var);
01280 return NULL;
01281 }
01282 }
01283
01284 a = build_alias(alias, var, NULL, 1);
01285
01286 ast_variables_destroy(var);
01287
01288 return a;
01289 }
01290
01291 static int h323_parse_allow_disallow(struct ast_codec_pref *pref, h323_format *formats, const char *list, int allowing)
01292 {
01293 int res;
01294 struct ast_format_cap *cap = ast_format_cap_alloc_nolock();
01295 if (!cap) {
01296 return 1;
01297 }
01298
01299 ast_format_cap_from_old_bitfield(cap, *formats);
01300 res = ast_parse_allow_disallow(pref, cap, list, allowing);
01301 *formats = ast_format_cap_to_old_bitfield(cap);
01302 cap = ast_format_cap_destroy(cap);
01303 return res;
01304
01305 }
01306
01307 static int update_common_options(struct ast_variable *v, struct call_options *options)
01308 {
01309 int tmp = 0;
01310 char *val, *opt;
01311
01312 if (!strcasecmp(v->name, "allow")) {
01313 h323_parse_allow_disallow(&options->prefs, &options->capability, v->value, 1);
01314 } else if (!strcasecmp(v->name, "autoframing")) {
01315 options->autoframing = ast_true(v->value);
01316 } else if (!strcasecmp(v->name, "disallow")) {
01317 h323_parse_allow_disallow(&options->prefs, &options->capability, v->value, 0);
01318 } else if (!strcasecmp(v->name, "dtmfmode")) {
01319 val = ast_strdupa(v->value);
01320 if ((opt = strchr(val, ':')) != (char *)NULL) {
01321 *opt++ = '\0';
01322 tmp = atoi(opt);
01323 }
01324 if (!strcasecmp(v->value, "inband")) {
01325 options->dtmfmode |= H323_DTMF_INBAND;
01326 } else if (!strcasecmp(val, "rfc2833")) {
01327 options->dtmfmode |= H323_DTMF_RFC2833;
01328 if (!opt) {
01329 options->dtmfcodec[0] = H323_DTMF_RFC2833_PT;
01330 } else if ((tmp >= 96) && (tmp < 128)) {
01331 options->dtmfcodec[0] = tmp;
01332 } else {
01333 options->dtmfcodec[0] = H323_DTMF_RFC2833_PT;
01334 ast_log(LOG_WARNING, "Unknown rfc2833 payload %s specified at line %d, using default %d\n", opt, v->lineno, options->dtmfcodec[0]);
01335 }
01336 } else if (!strcasecmp(val, "cisco")) {
01337 options->dtmfmode |= H323_DTMF_CISCO;
01338 if (!opt) {
01339 options->dtmfcodec[1] = H323_DTMF_CISCO_PT;
01340 } else if ((tmp >= 96) && (tmp < 128)) {
01341 options->dtmfcodec[1] = tmp;
01342 } else {
01343 options->dtmfcodec[1] = H323_DTMF_CISCO_PT;
01344 ast_log(LOG_WARNING, "Unknown Cisco DTMF payload %s specified at line %d, using default %d\n", opt, v->lineno, options->dtmfcodec[1]);
01345 }
01346 } else if (!strcasecmp(v->value, "h245-signal")) {
01347 options->dtmfmode |= H323_DTMF_SIGNAL;
01348 } else {
01349 ast_log(LOG_WARNING, "Unknown dtmf mode '%s' at line %d\n", v->value, v->lineno);
01350 }
01351 } else if (!strcasecmp(v->name, "dtmfcodec")) {
01352 ast_log(LOG_NOTICE, "Option %s at line %d is deprecated. Use dtmfmode=rfc2833[:<payload>] instead.\n", v->name, v->lineno);
01353 tmp = atoi(v->value);
01354 if (tmp < 96)
01355 ast_log(LOG_WARNING, "Invalid %s value %s at line %d\n", v->name, v->value, v->lineno);
01356 else
01357 options->dtmfcodec[0] = tmp;
01358 } else if (!strcasecmp(v->name, "bridge")) {
01359 options->bridge = ast_true(v->value);
01360 } else if (!strcasecmp(v->name, "nat")) {
01361 options->nat = ast_true(v->value);
01362 } else if (!strcasecmp(v->name, "fastStart")) {
01363 options->fastStart = ast_true(v->value);
01364 } else if (!strcasecmp(v->name, "h245Tunneling")) {
01365 options->h245Tunneling = ast_true(v->value);
01366 } else if (!strcasecmp(v->name, "silenceSuppression")) {
01367 options->silenceSuppression = ast_true(v->value);
01368 } else if (!strcasecmp(v->name, "progress_setup")) {
01369 tmp = atoi(v->value);
01370 if ((tmp != 0) && (tmp != 1) && (tmp != 3) && (tmp != 8)) {
01371 ast_log(LOG_WARNING, "Invalid value %s for %s at line %d, assuming 0\n", v->value, v->name, v->lineno);
01372 tmp = 0;
01373 }
01374 options->progress_setup = tmp;
01375 } else if (!strcasecmp(v->name, "progress_alert")) {
01376 tmp = atoi(v->value);
01377 if ((tmp != 0) && (tmp != 1) && (tmp != 8)) {
01378 ast_log(LOG_WARNING, "Invalid value %s for %s at line %d, assuming 0\n", v->value, v->name, v->lineno);
01379 tmp = 0;
01380 }
01381 options->progress_alert = tmp;
01382 } else if (!strcasecmp(v->name, "progress_audio")) {
01383 options->progress_audio = ast_true(v->value);
01384 } else if (!strcasecmp(v->name, "callerid")) {
01385 ast_callerid_split(v->value, options->cid_name, sizeof(options->cid_name), options->cid_num, sizeof(options->cid_num));
01386 } else if (!strcasecmp(v->name, "fullname")) {
01387 ast_copy_string(options->cid_name, v->value, sizeof(options->cid_name));
01388 } else if (!strcasecmp(v->name, "cid_number")) {
01389 ast_copy_string(options->cid_num, v->value, sizeof(options->cid_num));
01390 } else if (!strcasecmp(v->name, "tunneling")) {
01391 if (!strcasecmp(v->value, "none"))
01392 options->tunnelOptions = 0;
01393 else if (!strcasecmp(v->value, "cisco"))
01394 options->tunnelOptions |= H323_TUNNEL_CISCO;
01395 else if (!strcasecmp(v->value, "qsig"))
01396 options->tunnelOptions |= H323_TUNNEL_QSIG;
01397 else
01398 ast_log(LOG_WARNING, "Invalid value %s for %s at line %d\n", v->value, v->name, v->lineno);
01399 } else if (!strcasecmp(v->name, "hold")) {
01400 if (!strcasecmp(v->value, "none"))
01401 options->holdHandling = ~0;
01402 else if (!strcasecmp(v->value, "notify"))
01403 options->holdHandling |= H323_HOLD_NOTIFY;
01404 else if (!strcasecmp(v->value, "q931only"))
01405 options->holdHandling |= H323_HOLD_NOTIFY | H323_HOLD_Q931ONLY;
01406 else if (!strcasecmp(v->value, "h450"))
01407 options->holdHandling |= H323_HOLD_H450;
01408 else
01409 ast_log(LOG_WARNING, "Invalid value %s for %s at line %d\n", v->value, v->name, v->lineno);
01410 } else
01411 return 1;
01412
01413 return 0;
01414 }
01415
01416 static struct oh323_user *build_user(const char *name, struct ast_variable *v, struct ast_variable *alt, int realtime)
01417 {
01418 struct oh323_user *user;
01419 struct ast_ha *oldha;
01420 int found = 0;
01421 int format;
01422
01423 user = ASTOBJ_CONTAINER_FIND_UNLINK_FULL(&userl, name, name, 0, 0, strcmp);
01424
01425 if (user)
01426 found++;
01427 else {
01428 if (!(user = ast_calloc(1, sizeof(*user))))
01429 return NULL;
01430 ASTOBJ_INIT(user);
01431 }
01432 oldha = user->ha;
01433 user->ha = (struct ast_ha *)NULL;
01434 memcpy(&user->options, &global_options, sizeof(user->options));
01435 user->options.dtmfmode = 0;
01436 user->options.holdHandling = 0;
01437
01438 ast_copy_string(user->context, default_context, sizeof(user->context));
01439 if (user && !found)
01440 ast_copy_string(user->name, name, sizeof(user->name));
01441
01442 #if 0
01443 if (user->chanvars) {
01444 ast_variables_destroy(user->chanvars);
01445 user->chanvars = NULL;
01446 }
01447 #endif
01448
01449 for (; v || ((v = alt) && !(alt = NULL)); v = v->next) {
01450 if (!update_common_options(v, &user->options))
01451 continue;
01452 if (!strcasecmp(v->name, "context")) {
01453 ast_copy_string(user->context, v->value, sizeof(user->context));
01454 } else if (!strcasecmp(v->name, "secret")) {
01455 ast_copy_string(user->secret, v->value, sizeof(user->secret));
01456 } else if (!strcasecmp(v->name, "accountcode")) {
01457 ast_copy_string(user->accountcode, v->value, sizeof(user->accountcode));
01458 } else if (!strcasecmp(v->name, "host")) {
01459 if (!strcasecmp(v->value, "dynamic")) {
01460 ast_log(LOG_ERROR, "A dynamic host on a type=user does not make any sense\n");
01461 ASTOBJ_UNREF(user, oh323_destroy_user);
01462 return NULL;
01463 } else {
01464 struct ast_sockaddr tmp;
01465
01466 tmp.ss.ss_family = AF_INET;
01467 if (ast_get_ip(&tmp, v->value)) {
01468 ASTOBJ_UNREF(user, oh323_destroy_user);
01469 return NULL;
01470 }
01471 ast_sockaddr_to_sin(&tmp, &user->addr);
01472 }
01473
01474 user->host = 1;
01475 } else if (!strcasecmp(v->name, "amaflags")) {
01476 format = ast_cdr_amaflags2int(v->value);
01477 if (format < 0) {
01478 ast_log(LOG_WARNING, "Invalid AMA Flags: %s at line %d\n", v->value, v->lineno);
01479 } else {
01480 user->amaflags = format;
01481 }
01482 } else if (!strcasecmp(v->name, "permit") ||
01483 !strcasecmp(v->name, "deny")) {
01484 int ha_error = 0;
01485
01486 user->ha = ast_append_ha(v->name, v->value, user->ha, &ha_error);
01487 if (ha_error)
01488 ast_log(LOG_ERROR, "Bad ACL entry in configuration line %d : %s\n", v->lineno, v->value);
01489 }
01490 }
01491 if (!user->options.dtmfmode)
01492 user->options.dtmfmode = global_options.dtmfmode;
01493 if (user->options.holdHandling == ~0)
01494 user->options.holdHandling = 0;
01495 else if (!user->options.holdHandling)
01496 user->options.holdHandling = global_options.holdHandling;
01497 ASTOBJ_UNMARK(user);
01498 ast_free_ha(oldha);
01499 return user;
01500 }
01501
01502 static struct oh323_user *realtime_user(const call_details_t *cd)
01503 {
01504 struct ast_variable *var, *tmp;
01505 struct oh323_user *user;
01506 const char *username;
01507
01508 if (userbyalias)
01509 var = ast_load_realtime("h323", "name", username = cd->call_source_aliases, SENTINEL);
01510 else {
01511 username = (char *)NULL;
01512 var = ast_load_realtime("h323", "host", cd->sourceIp, SENTINEL);
01513 }
01514
01515 if (!var)
01516 return NULL;
01517
01518 for (tmp = var; tmp; tmp = tmp->next) {
01519 if (!strcasecmp(tmp->name, "type") &&
01520 !(!strcasecmp(tmp->value, "user") || !strcasecmp(tmp->value, "friend"))) {
01521 ast_variables_destroy(var);
01522 return NULL;
01523 } else if (!username && !strcasecmp(tmp->name, "name"))
01524 username = tmp->value;
01525 }
01526
01527 if (!username) {
01528 ast_log(LOG_WARNING, "Cannot determine user name for IP address %s\n", cd->sourceIp);
01529 ast_variables_destroy(var);
01530 return NULL;
01531 }
01532
01533 user = build_user(username, var, NULL, 1);
01534
01535 ast_variables_destroy(var);
01536
01537 return user;
01538 }
01539
01540 static struct oh323_peer *build_peer(const char *name, struct ast_variable *v, struct ast_variable *alt, int realtime)
01541 {
01542 struct oh323_peer *peer;
01543 struct ast_ha *oldha;
01544 int found = 0;
01545
01546 peer = ASTOBJ_CONTAINER_FIND_UNLINK_FULL(&peerl, name, name, 0, 0, strcmp);
01547
01548 if (peer)
01549 found++;
01550 else {
01551 if (!(peer = ast_calloc(1, sizeof(*peer))))
01552 return NULL;
01553 ASTOBJ_INIT(peer);
01554 }
01555 oldha = peer->ha;
01556 peer->ha = NULL;
01557 memcpy(&peer->options, &global_options, sizeof(peer->options));
01558 peer->options.dtmfmode = 0;
01559 peer->options.holdHandling = 0;
01560 peer->addr.sin_port = htons(h323_signalling_port);
01561 peer->addr.sin_family = AF_INET;
01562 if (!found && name)
01563 ast_copy_string(peer->name, name, sizeof(peer->name));
01564
01565 #if 0
01566 if (peer->chanvars) {
01567 ast_variables_destroy(peer->chanvars);
01568 peer->chanvars = NULL;
01569 }
01570 #endif
01571
01572 peer->mailbox[0] = '\0';
01573
01574 for (; v || ((v = alt) && !(alt = NULL)); v = v->next) {
01575 if (!update_common_options(v, &peer->options))
01576 continue;
01577 if (!strcasecmp(v->name, "host")) {
01578 if (!strcasecmp(v->value, "dynamic")) {
01579 ast_log(LOG_ERROR, "Dynamic host configuration not implemented.\n");
01580 ASTOBJ_UNREF(peer, oh323_destroy_peer);
01581 return NULL;
01582 }
01583 {
01584 struct ast_sockaddr tmp;
01585
01586 tmp.ss.ss_family = AF_INET;
01587 if (ast_get_ip(&tmp, v->value)) {
01588 ast_log(LOG_ERROR, "Could not determine IP for %s\n", v->value);
01589 ASTOBJ_UNREF(peer, oh323_destroy_peer);
01590 return NULL;
01591 }
01592 ast_sockaddr_to_sin(&tmp, &peer->addr);
01593 }
01594 } else if (!strcasecmp(v->name, "port")) {
01595 peer->addr.sin_port = htons(atoi(v->value));
01596 } else if (!strcasecmp(v->name, "permit") ||
01597 !strcasecmp(v->name, "deny")) {
01598 int ha_error = 0;
01599
01600 peer->ha = ast_append_ha(v->name, v->value, peer->ha, &ha_error);
01601 if (ha_error)
01602 ast_log(LOG_ERROR, "Bad ACL entry in configuration line %d : %s\n", v->lineno, v->value);
01603 } else if (!strcasecmp(v->name, "mailbox")) {
01604 ast_copy_string(peer->mailbox, v->value, sizeof(peer->mailbox));
01605 } else if (!strcasecmp(v->name, "hasvoicemail")) {
01606 if (ast_true(v->value) && ast_strlen_zero(peer->mailbox)) {
01607 ast_copy_string(peer->mailbox, name, sizeof(peer->mailbox));
01608 }
01609 }
01610 }
01611 if (!peer->options.dtmfmode)
01612 peer->options.dtmfmode = global_options.dtmfmode;
01613 if (peer->options.holdHandling == ~0)
01614 peer->options.holdHandling = 0;
01615 else if (!peer->options.holdHandling)
01616 peer->options.holdHandling = global_options.holdHandling;
01617 ASTOBJ_UNMARK(peer);
01618 ast_free_ha(oldha);
01619 return peer;
01620 }
01621
01622 static struct oh323_peer *realtime_peer(const char *peername, struct sockaddr_in *sin)
01623 {
01624 struct oh323_peer *peer;
01625 struct ast_variable *var;
01626 struct ast_variable *tmp;
01627 const char *addr = NULL;
01628
01629
01630 if (peername)
01631 var = ast_load_realtime("h323", "name", peername, SENTINEL);
01632 else if (sin)
01633 var = ast_load_realtime("h323", "host", addr = ast_inet_ntoa(sin->sin_addr), SENTINEL);
01634 else
01635 return NULL;
01636
01637 if (!var)
01638 return NULL;
01639
01640 for (tmp = var; tmp; tmp = tmp->next) {
01641
01642 if (!strcasecmp(tmp->name, "type") &&
01643 !(!strcasecmp(tmp->value, "peer") || !strcasecmp(tmp->value, "friend"))) {
01644 ast_variables_destroy(var);
01645 return NULL;
01646 } else if (!peername && !strcasecmp(tmp->name, "name")) {
01647 peername = tmp->value;
01648 }
01649 }
01650
01651 if (!peername) {
01652 ast_log(LOG_WARNING, "Cannot determine peer name for IP address %s\n", addr);
01653 ast_variables_destroy(var);
01654 return NULL;
01655 }
01656
01657
01658 peer = build_peer(peername, var, NULL, 1);
01659
01660 ast_variables_destroy(var);
01661
01662 return peer;
01663 }
01664
01665 static int oh323_addrcmp_str(struct in_addr inaddr, char *addr)
01666 {
01667 return strcmp(ast_inet_ntoa(inaddr), addr);
01668 }
01669
01670 static struct oh323_user *find_user(const call_details_t *cd, int realtime)
01671 {
01672 struct oh323_user *u;
01673
01674 if (userbyalias)
01675 u = ASTOBJ_CONTAINER_FIND(&userl, cd->call_source_aliases);
01676 else
01677 u = ASTOBJ_CONTAINER_FIND_FULL(&userl, cd->sourceIp, addr.sin_addr, 0, 0, oh323_addrcmp_str);
01678
01679 if (!u && realtime)
01680 u = realtime_user(cd);
01681
01682 if (!u && h323debug)
01683 ast_debug(1, "Could not find user by name %s or address %s\n", cd->call_source_aliases, cd->sourceIp);
01684
01685 return u;
01686 }
01687
01688 static int oh323_addrcmp(struct sockaddr_in addr, struct sockaddr_in *sin)
01689 {
01690 int res;
01691
01692 if (!sin)
01693 res = -1;
01694 else
01695 res = inaddrcmp(&addr , sin);
01696
01697 return res;
01698 }
01699
01700 static struct oh323_peer *find_peer(const char *peer, struct sockaddr_in *sin, int realtime)
01701 {
01702 struct oh323_peer *p;
01703
01704 if (peer)
01705 p = ASTOBJ_CONTAINER_FIND(&peerl, peer);
01706 else
01707 p = ASTOBJ_CONTAINER_FIND_FULL(&peerl, sin, addr, 0, 0, oh323_addrcmp);
01708
01709 if (!p && realtime)
01710 p = realtime_peer(peer, sin);
01711
01712 if (!p && h323debug)
01713 ast_debug(1, "Could not find peer by name %s or address %s\n", (peer ? peer : "<NONE>"), (sin ? ast_inet_ntoa(sin->sin_addr) : "<NONE>"));
01714
01715 return p;
01716 }
01717
01718 static int create_addr(struct oh323_pvt *pvt, char *opeer)
01719 {
01720 struct hostent *hp;
01721 struct ast_hostent ahp;
01722 struct oh323_peer *p;
01723 int portno;
01724 int found = 0;
01725 char *port;
01726 char *hostn;
01727 char peer[256] = "";
01728
01729 ast_copy_string(peer, opeer, sizeof(peer));
01730 port = strchr(peer, ':');
01731 if (port) {
01732 *port = '\0';
01733 port++;
01734 }
01735 pvt->sa.sin_family = AF_INET;
01736 p = find_peer(peer, NULL, 1);
01737 if (p) {
01738 found++;
01739 memcpy(&pvt->options, &p->options, sizeof(pvt->options));
01740 pvt->jointcapability = pvt->options.capability;
01741 if (pvt->options.dtmfmode) {
01742 if (pvt->options.dtmfmode & H323_DTMF_RFC2833) {
01743 pvt->nonCodecCapability |= AST_RTP_DTMF;
01744 } else {
01745 pvt->nonCodecCapability &= ~AST_RTP_DTMF;
01746 }
01747 }
01748 if (p->addr.sin_addr.s_addr) {
01749 pvt->sa.sin_addr = p->addr.sin_addr;
01750 pvt->sa.sin_port = p->addr.sin_port;
01751 }
01752 ASTOBJ_UNREF(p, oh323_destroy_peer);
01753 }
01754 if (!p && !found) {
01755 hostn = peer;
01756 if (port) {
01757 portno = atoi(port);
01758 } else {
01759 portno = h323_signalling_port;
01760 }
01761 hp = ast_gethostbyname(hostn, &ahp);
01762 if (hp) {
01763 memcpy(&pvt->sa.sin_addr, hp->h_addr, sizeof(pvt->sa.sin_addr));
01764 pvt->sa.sin_port = htons(portno);
01765
01766 p = find_peer(NULL, &pvt->sa, 1);
01767 memcpy(&pvt->options, (p ? &p->options : &global_options), sizeof(pvt->options));
01768 pvt->jointcapability = pvt->options.capability;
01769 if (p) {
01770 ASTOBJ_UNREF(p, oh323_destroy_peer);
01771 }
01772 if (pvt->options.dtmfmode) {
01773 if (pvt->options.dtmfmode & H323_DTMF_RFC2833) {
01774 pvt->nonCodecCapability |= AST_RTP_DTMF;
01775 } else {
01776 pvt->nonCodecCapability &= ~AST_RTP_DTMF;
01777 }
01778 }
01779 return 0;
01780 } else {
01781 ast_log(LOG_WARNING, "No such host: %s\n", peer);
01782 return -1;
01783 }
01784 } else if (!found) {
01785 return -1;
01786 } else {
01787 return 0;
01788 }
01789 }
01790 static struct ast_channel *oh323_request(const char *type, struct ast_format_cap *cap, const struct ast_channel *requestor, const char *dest, int *cause)
01791 {
01792 struct oh323_pvt *pvt;
01793 struct ast_channel *tmpc = NULL;
01794 char *ext, *host;
01795 char *h323id = NULL;
01796 char tmp[256], tmp1[256];
01797
01798 if (h323debug)
01799 ast_debug(1, "type=%s, format=%s, data=%s.\n", type, ast_getformatname_multiple(tmp, sizeof(tmp), cap), dest);
01800
01801 pvt = oh323_alloc(0);
01802 if (!pvt) {
01803 ast_log(LOG_WARNING, "Unable to build pvt data for '%s'\n", dest);
01804 return NULL;
01805 }
01806 if (!(ast_format_cap_has_type(cap, AST_FORMAT_TYPE_AUDIO))) {
01807 ast_log(LOG_NOTICE, "Asked to get a channel of unsupported format '%s'\n", ast_getformatname_multiple(tmp, sizeof(tmp), cap));
01808 oh323_destroy(pvt);
01809 if (cause)
01810 *cause = AST_CAUSE_INCOMPATIBLE_DESTINATION;
01811 return NULL;
01812 }
01813 ast_copy_string(tmp, dest, sizeof(tmp));
01814 host = strchr(tmp, '@');
01815 if (host) {
01816 *host = '\0';
01817 host++;
01818 ext = tmp;
01819 } else {
01820 ext = strrchr(tmp, '/');
01821 if (ext)
01822 *ext++ = '\0';
01823 host = tmp;
01824 }
01825 strtok_r(host, "/", &(h323id));
01826 if (!ast_strlen_zero(h323id)) {
01827 h323_set_id(h323id);
01828 }
01829 if (ext) {
01830 ast_copy_string(pvt->exten, ext, sizeof(pvt->exten));
01831 }
01832 if (h323debug)
01833 ast_debug(1, "Extension: %s Host: %s\n", pvt->exten, host);
01834
01835 if (gatekeeper_disable) {
01836 if (create_addr(pvt, host)) {
01837 oh323_destroy(pvt);
01838 if (cause)
01839 *cause = AST_CAUSE_DESTINATION_OUT_OF_ORDER;
01840 return NULL;
01841 }
01842 }
01843 else {
01844 memcpy(&pvt->options, &global_options, sizeof(pvt->options));
01845 pvt->jointcapability = pvt->options.capability;
01846 if (pvt->options.dtmfmode) {
01847 if (pvt->options.dtmfmode & H323_DTMF_RFC2833) {
01848 pvt->nonCodecCapability |= AST_RTP_DTMF;
01849 } else {
01850 pvt->nonCodecCapability &= ~AST_RTP_DTMF;
01851 }
01852 }
01853 }
01854
01855 ast_mutex_lock(&caplock);
01856
01857 snprintf(tmp1, sizeof(tmp1)-1, "%s-%u", host, ++unique);
01858 tmp1[sizeof(tmp1)-1] = '\0';
01859 ast_mutex_unlock(&caplock);
01860
01861 ast_mutex_lock(&pvt->lock);
01862 tmpc = __oh323_new(pvt, AST_STATE_DOWN, tmp1, requestor ? ast_channel_linkedid(requestor) : NULL);
01863 ast_mutex_unlock(&pvt->lock);
01864 if (!tmpc) {
01865 oh323_destroy(pvt);
01866 if (cause)
01867 *cause = AST_CAUSE_NORMAL_TEMPORARY_FAILURE;
01868 }
01869 ast_update_use_count();
01870 restart_monitor();
01871 return tmpc;
01872 }
01873
01874
01875 static struct oh323_alias *find_alias(const char *source_aliases, int realtime)
01876 {
01877 struct oh323_alias *a;
01878
01879 a = ASTOBJ_CONTAINER_FIND(&aliasl, source_aliases);
01880
01881 if (!a && realtime)
01882 a = realtime_alias(source_aliases);
01883
01884 return a;
01885 }
01886
01887
01888
01889
01890
01891 static int receive_digit(unsigned call_reference, char digit, const char *token, int duration)
01892 {
01893 struct oh323_pvt *pvt;
01894 int res;
01895
01896 pvt = find_call_locked(call_reference, token);
01897 if (!pvt) {
01898 ast_log(LOG_ERROR, "Received digit '%c' (%u ms) for call %s without private structure\n", digit, duration, token);
01899 return -1;
01900 }
01901 if (h323debug)
01902 ast_log(LOG_DTMF, "Received %s digit '%c' (%u ms) for call %s\n", (digit == ' ' ? "update for" : "new"), (digit == ' ' ? pvt->curDTMF : digit), duration, token);
01903
01904 if (pvt->owner && !ast_channel_trylock(pvt->owner)) {
01905 if (digit == '!')
01906 res = ast_queue_control(pvt->owner, AST_CONTROL_FLASH);
01907 else {
01908 struct ast_frame f = {
01909 .frametype = AST_FRAME_DTMF_END,
01910 .subclass.integer = digit,
01911 .samples = duration * 8,
01912 .len = duration,
01913 .src = "SEND_DIGIT",
01914 };
01915 if (digit == ' ') {
01916 f.subclass.integer = pvt->curDTMF;
01917 AST_SCHED_DEL(sched, pvt->DTMFsched);
01918 } else {
01919 if (pvt->DTMFsched >= 0) {
01920
01921 AST_SCHED_DEL(sched, pvt->DTMFsched);
01922 f.subclass.integer = pvt->curDTMF;
01923 f.samples = f.len = 0;
01924 ast_queue_frame(pvt->owner, &f);
01925
01926 f.subclass.integer = digit;
01927 f.samples = duration * 8;
01928 f.len = duration;
01929 }
01930 if (duration) {
01931 f.frametype = AST_FRAME_DTMF_BEGIN;
01932 pvt->DTMFsched = ast_sched_add(sched, duration, oh323_simulate_dtmf_end, pvt);
01933 if (h323debug)
01934 ast_log(LOG_DTMF, "Scheduled DTMF END simulation for %d ms, id=%d\n", duration, pvt->DTMFsched);
01935 }
01936 pvt->curDTMF = digit;
01937 }
01938 res = ast_queue_frame(pvt->owner, &f);
01939 }
01940 ast_channel_unlock(pvt->owner);
01941 } else {
01942 if (digit == '!')
01943 pvt->newcontrol = AST_CONTROL_FLASH;
01944 else {
01945 pvt->newduration = duration;
01946 pvt->newdigit = digit;
01947 }
01948 res = 0;
01949 }
01950 ast_mutex_unlock(&pvt->lock);
01951 return res;
01952 }
01953
01954
01955
01956
01957
01958
01959 static struct rtp_info *external_rtp_create(unsigned call_reference, const char * token)
01960 {
01961 struct oh323_pvt *pvt;
01962 struct sockaddr_in us;
01963 struct rtp_info *info;
01964
01965 info = ast_calloc(1, sizeof(*info));
01966 if (!info) {
01967 ast_log(LOG_ERROR, "Unable to allocated info structure, this is very bad\n");
01968 return NULL;
01969 }
01970 pvt = find_call_locked(call_reference, token);
01971 if (!pvt) {
01972 ast_free(info);
01973 ast_log(LOG_ERROR, "Unable to find call %s(%d)\n", token, call_reference);
01974 return NULL;
01975 }
01976 if (!pvt->rtp)
01977 __oh323_rtp_create(pvt);
01978 if (!pvt->rtp) {
01979 ast_mutex_unlock(&pvt->lock);
01980 ast_free(info);
01981 ast_log(LOG_ERROR, "No RTP stream is available for call %s (%d)", token, call_reference);
01982 return NULL;
01983 }
01984
01985 {
01986 struct ast_sockaddr tmp;
01987
01988 ast_rtp_instance_get_local_address(pvt->rtp, &tmp);
01989 ast_sockaddr_to_sin(&tmp, &us);
01990 }
01991 ast_mutex_unlock(&pvt->lock);
01992
01993 ast_copy_string(info->addr, ast_inet_ntoa(us.sin_addr), sizeof(info->addr));
01994 info->port = ntohs(us.sin_port);
01995 if (h323debug)
01996 ast_debug(1, "Sending RTP 'US' %s:%d\n", info->addr, info->port);
01997 return info;
01998 }
01999
02000
02001
02002
02003
02004
02005 static void setup_rtp_connection(unsigned call_reference, const char *remoteIp, int remotePort, const char *token, int pt)
02006 {
02007 struct oh323_pvt *pvt;
02008 struct sockaddr_in them;
02009 int nativeformats_changed;
02010 enum { NEED_NONE, NEED_HOLD, NEED_UNHOLD } rtp_change = NEED_NONE;
02011
02012 if (h323debug)
02013 ast_debug(1, "Setting up RTP connection for %s\n", token);
02014
02015
02016 pvt = find_call_locked(call_reference, token);
02017 if (!pvt) {
02018 ast_log(LOG_ERROR, "Something is wrong: rtp\n");
02019 return;
02020 }
02021 if (pvt->alreadygone) {
02022 ast_mutex_unlock(&pvt->lock);
02023 return;
02024 }
02025
02026 if (!pvt->rtp)
02027 __oh323_rtp_create(pvt);
02028
02029 if ((pt == 2) && (pvt->jointcapability & AST_FORMAT_G726_AAL2)) {
02030 ast_rtp_codecs_payloads_set_rtpmap_type(ast_rtp_instance_get_codecs(pvt->rtp), pvt->rtp, pt, "audio", "G726-32", AST_RTP_OPT_G726_NONSTANDARD);
02031 }
02032
02033 them.sin_family = AF_INET;
02034
02035 them.sin_addr.s_addr = inet_addr(remoteIp);
02036 them.sin_port = htons(remotePort);
02037
02038 if (them.sin_addr.s_addr) {
02039 {
02040 struct ast_sockaddr tmp;
02041
02042 ast_sockaddr_from_sin(&tmp, &them);
02043 ast_rtp_instance_set_remote_address(pvt->rtp, &tmp);
02044 }
02045 if (pvt->recvonly) {
02046 pvt->recvonly = 0;
02047 rtp_change = NEED_UNHOLD;
02048 }
02049 } else {
02050 ast_rtp_instance_stop(pvt->rtp);
02051 if (!pvt->recvonly) {
02052 pvt->recvonly = 1;
02053 rtp_change = NEED_HOLD;
02054 }
02055 }
02056
02057
02058 nativeformats_changed = 0;
02059 if (pt != 128 && pvt->rtp) {
02060 struct ast_rtp_payload_type rtptype = ast_rtp_codecs_payload_lookup(ast_rtp_instance_get_codecs(pvt->rtp), pt);
02061 if (rtptype.asterisk_format) {
02062 if (pvt->nativeformats != ast_format_to_old_bitfield(&rtptype.format)) {
02063 pvt->nativeformats = ast_format_to_old_bitfield(&rtptype.format);
02064 nativeformats_changed = 1;
02065 }
02066 }
02067 } else if (h323debug)
02068 ast_log(LOG_NOTICE, "Payload type is unknown, formats isn't changed\n");
02069
02070
02071 if (nativeformats_changed || pvt->options.progress_audio || (rtp_change != NEED_NONE)) {
02072 if (pvt->owner && !ast_channel_trylock(pvt->owner)) {
02073 struct ast_format_cap *pvt_native = ast_format_cap_alloc_nolock();
02074 ast_format_cap_from_old_bitfield(pvt_native, pvt->nativeformats);
02075
02076
02077 if (!(ast_format_cap_identical(pvt->owner->nativeformats, pvt_native))) {
02078 if (h323debug) {
02079 char tmp[256], tmp2[256];
02080 ast_debug(1, "Native format changed to '%s' from '%s', read format is %s, write format is %s\n", ast_getformatname_multiple(tmp, sizeof(tmp), pvt_native), ast_getformatname_multiple(tmp2, sizeof(tmp2), pvt->owner->nativeformats), ast_getformatname(&pvt->owner->readformat), ast_getformatname(&pvt->owner->writeformat));
02081 }
02082 ast_format_cap_copy(pvt->owner->nativeformats, pvt_native);
02083 ast_set_read_format(pvt->owner, &pvt->owner->readformat);
02084 ast_set_write_format(pvt->owner, &pvt->owner->writeformat);
02085 }
02086 if (pvt->options.progress_audio)
02087 ast_queue_control(pvt->owner, AST_CONTROL_PROGRESS);
02088 switch (rtp_change) {
02089 case NEED_HOLD:
02090 ast_queue_control(pvt->owner, AST_CONTROL_HOLD);
02091 break;
02092 case NEED_UNHOLD:
02093 ast_queue_control(pvt->owner, AST_CONTROL_UNHOLD);
02094 break;
02095 default:
02096 break;
02097 }
02098 ast_channel_unlock(pvt->owner);
02099 pvt_native = ast_format_cap_destroy(pvt_native);
02100 }
02101 else {
02102 if (pvt->options.progress_audio)
02103 pvt->newcontrol = AST_CONTROL_PROGRESS;
02104 else if (rtp_change == NEED_HOLD)
02105 pvt->newcontrol = AST_CONTROL_HOLD;
02106 else if (rtp_change == NEED_UNHOLD)
02107 pvt->newcontrol = AST_CONTROL_UNHOLD;
02108 if (h323debug)
02109 ast_debug(1, "RTP connection preparation for %s is pending...\n", token);
02110 }
02111 }
02112 ast_mutex_unlock(&pvt->lock);
02113
02114 if (h323debug)
02115 ast_debug(1, "RTP connection prepared for %s\n", token);
02116
02117 return;
02118 }
02119
02120
02121
02122
02123
02124 static void connection_made(unsigned call_reference, const char *token)
02125 {
02126 struct oh323_pvt *pvt;
02127
02128 if (h323debug)
02129 ast_debug(1, "Call %s answered\n", token);
02130
02131 pvt = find_call_locked(call_reference, token);
02132 if (!pvt) {
02133 ast_log(LOG_ERROR, "Something is wrong: connection\n");
02134 return;
02135 }
02136
02137
02138 if (!pvt->outgoing) {
02139 ast_mutex_unlock(&pvt->lock);
02140 return;
02141 }
02142
02143 if (!pvt->connection_established) {
02144 pvt->connection_established = 1;
02145 update_state(pvt, -1, AST_CONTROL_ANSWER);
02146 }
02147 ast_mutex_unlock(&pvt->lock);
02148 return;
02149 }
02150
02151 static int progress(unsigned call_reference, const char *token, int inband)
02152 {
02153 struct oh323_pvt *pvt;
02154
02155 if (h323debug)
02156 ast_debug(1, "Received ALERT/PROGRESS message for %s tones\n", (inband ? "inband" : "self-generated"));
02157
02158 pvt = find_call_locked(call_reference, token);
02159 if (!pvt) {
02160 ast_log(LOG_ERROR, "Private structure not found in progress.\n");
02161 return -1;
02162 }
02163 if (!pvt->owner) {
02164 ast_mutex_unlock(&pvt->lock);
02165 ast_log(LOG_ERROR, "No Asterisk channel associated with private structure.\n");
02166 return -1;
02167 }
02168 update_state(pvt, -1, (inband ? AST_CONTROL_PROGRESS : AST_CONTROL_RINGING));
02169 ast_mutex_unlock(&pvt->lock);
02170
02171 return 0;
02172 }
02173
02174
02175
02176
02177
02178
02179 static call_options_t *setup_incoming_call(call_details_t *cd)
02180 {
02181 struct oh323_pvt *pvt;
02182 struct oh323_user *user = NULL;
02183 struct oh323_alias *alias = NULL;
02184
02185 if (h323debug)
02186 ast_debug(1, "Setting up incoming call for %s\n", cd->call_token);
02187
02188
02189 pvt = oh323_alloc(cd->call_reference);
02190
02191 if (!pvt) {
02192 ast_log(LOG_ERROR, "Unable to allocate private structure, this is bad.\n");
02193 cleanup_call_details(cd);
02194 return NULL;
02195 }
02196
02197
02198 memcpy(&pvt->cd, cd, sizeof(pvt->cd));
02199 memcpy(&pvt->options, &global_options, sizeof(pvt->options));
02200 pvt->jointcapability = pvt->options.capability;
02201
02202 if (h323debug) {
02203 ast_verb(3, "Setting up Call\n");
02204 ast_verb(3, " \tCall token: [%s]\n", pvt->cd.call_token);
02205 ast_verb(3, " \tCalling party name: [%s]\n", pvt->cd.call_source_name);
02206 ast_verb(3, " \tCalling party number: [%s]\n", pvt->cd.call_source_e164);
02207 ast_verb(3, " \tCalled party name: [%s]\n", pvt->cd.call_dest_alias);
02208 ast_verb(3, " \tCalled party number: [%s]\n", pvt->cd.call_dest_e164);
02209 if (pvt->cd.redirect_reason >= 0)
02210 ast_verb(3, " \tRedirecting party number: [%s] (reason %d)\n", pvt->cd.redirect_number, pvt->cd.redirect_reason);
02211 ast_verb(3, " \tCalling party IP: [%s]\n", pvt->cd.sourceIp);
02212 }
02213
02214
02215 if ((!strcasecmp(cd->sourceIp, gatekeeper)) && (gkroute == -1) && !gatekeeper_disable) {
02216 if (!ast_strlen_zero(cd->call_dest_e164)) {
02217 ast_copy_string(pvt->exten, cd->call_dest_e164, sizeof(pvt->exten));
02218 ast_copy_string(pvt->context, default_context, sizeof(pvt->context));
02219 } else {
02220 alias = find_alias(cd->call_dest_alias, 1);
02221 if (!alias) {
02222 ast_log(LOG_ERROR, "Call for %s rejected, alias not found\n", cd->call_dest_alias);
02223 oh323_destroy(pvt);
02224 return NULL;
02225 }
02226 ast_copy_string(pvt->exten, alias->name, sizeof(pvt->exten));
02227 ast_copy_string(pvt->context, alias->context, sizeof(pvt->context));
02228 }
02229 } else {
02230
02231
02232 user = find_user(cd, 1);
02233 if (!user) {
02234 if (!acceptAnonymous) {
02235 ast_log(LOG_NOTICE, "Anonymous call from '%s@%s' rejected\n", pvt->cd.call_source_aliases, pvt->cd.sourceIp);
02236 oh323_destroy(pvt);
02237 return NULL;
02238 }
02239 if (ast_strlen_zero(default_context)) {
02240 ast_log(LOG_ERROR, "Call from '%s@%s' rejected due to no default context\n", pvt->cd.call_source_aliases, pvt->cd.sourceIp);
02241 oh323_destroy(pvt);
02242 return NULL;
02243 }
02244 ast_copy_string(pvt->context, default_context, sizeof(pvt->context));
02245 if (!ast_strlen_zero(pvt->cd.call_dest_e164)) {
02246 ast_copy_string(pvt->exten, cd->call_dest_e164, sizeof(pvt->exten));
02247 } else {
02248 ast_copy_string(pvt->exten, cd->call_dest_alias, sizeof(pvt->exten));
02249 }
02250 if (h323debug)
02251 ast_debug(1, "Sending %s@%s to context [%s] extension %s\n", cd->call_source_aliases, cd->sourceIp, pvt->context, pvt->exten);
02252 } else {
02253 if (user->host) {
02254 if (strcasecmp(cd->sourceIp, ast_inet_ntoa(user->addr.sin_addr))) {
02255 if (ast_strlen_zero(user->context)) {
02256 if (ast_strlen_zero(default_context)) {
02257 ast_log(LOG_ERROR, "Call from '%s' rejected due to non-matching IP address (%s) and no default context\n", user->name, cd->sourceIp);
02258 oh323_destroy(pvt);
02259 ASTOBJ_UNREF(user, oh323_destroy_user);
02260 return NULL;
02261 }
02262 ast_copy_string(pvt->context, default_context, sizeof(pvt->context));
02263 } else {
02264 ast_copy_string(pvt->context, user->context, sizeof(pvt->context));
02265 }
02266 pvt->exten[0] = 'i';
02267 pvt->exten[1] = '\0';
02268 ast_log(LOG_ERROR, "Call from '%s' rejected due to non-matching IP address (%s)s\n", user->name, cd->sourceIp);
02269 oh323_destroy(pvt);
02270 ASTOBJ_UNREF(user, oh323_destroy_user);
02271 return NULL;
02272 }
02273 }
02274 ast_copy_string(pvt->context, user->context, sizeof(pvt->context));
02275 memcpy(&pvt->options, &user->options, sizeof(pvt->options));
02276 pvt->jointcapability = pvt->options.capability;
02277 if (!ast_strlen_zero(pvt->cd.call_dest_e164)) {
02278 ast_copy_string(pvt->exten, cd->call_dest_e164, sizeof(pvt->exten));
02279 } else {
02280 ast_copy_string(pvt->exten, cd->call_dest_alias, sizeof(pvt->exten));
02281 }
02282 if (!ast_strlen_zero(user->accountcode)) {
02283 ast_copy_string(pvt->accountcode, user->accountcode, sizeof(pvt->accountcode));
02284 }
02285 if (user->amaflags) {
02286 pvt->amaflags = user->amaflags;
02287 }
02288 ASTOBJ_UNREF(user, oh323_destroy_user);
02289 }
02290 }
02291 return &pvt->options;
02292 }
02293
02294
02295
02296
02297
02298
02299 static int answer_call(unsigned call_reference, const char *token)
02300 {
02301 struct oh323_pvt *pvt;
02302 struct ast_channel *c = NULL;
02303 enum {ext_original, ext_s, ext_i, ext_notexists} try_exten;
02304 char tmp_exten[sizeof(pvt->exten)];
02305
02306 if (h323debug)
02307 ast_debug(1, "Preparing Asterisk to answer for %s\n", token);
02308
02309
02310 pvt = find_call_locked(call_reference, token);
02311 if (!pvt) {
02312 ast_log(LOG_ERROR, "Something is wrong: answer_call\n");
02313 return 0;
02314 }
02315
02316 ast_copy_string(tmp_exten, pvt->exten, sizeof(tmp_exten));
02317
02318
02319 if ((tmp_exten[0] != '\0') && (tmp_exten[1] == '\0')) {
02320 if (tmp_exten[0] == 's')
02321 try_exten = ext_s;
02322 else if (tmp_exten[0] == 'i')
02323 try_exten = ext_i;
02324 else
02325 try_exten = ext_original;
02326 } else
02327 try_exten = ext_original;
02328 do {
02329 if (ast_exists_extension(NULL, pvt->context, tmp_exten, 1, NULL))
02330 break;
02331 switch (try_exten) {
02332 case ext_original:
02333 tmp_exten[0] = 's';
02334 tmp_exten[1] = '\0';
02335 try_exten = ext_s;
02336 break;
02337 case ext_s:
02338 tmp_exten[0] = 'i';
02339 try_exten = ext_i;
02340 break;
02341 case ext_i:
02342 try_exten = ext_notexists;
02343 break;
02344 default:
02345 break;
02346 }
02347 } while (try_exten != ext_notexists);
02348
02349
02350 if (try_exten == ext_notexists) {
02351 ast_log(LOG_NOTICE, "Dropping call because extensions '%s', 's' and 'i' doesn't exists in context [%s]\n", pvt->exten, pvt->context);
02352 ast_mutex_unlock(&pvt->lock);
02353 h323_clear_call(token, AST_CAUSE_UNALLOCATED);
02354 return 0;
02355 } else if ((try_exten != ext_original) && (strcmp(pvt->exten, tmp_exten) != 0)) {
02356 if (h323debug)
02357 ast_debug(1, "Going to extension %s@%s because %s@%s isn't exists\n", tmp_exten, pvt->context, pvt->exten, pvt->context);
02358 ast_copy_string(pvt->exten, tmp_exten, sizeof(pvt->exten));
02359 }
02360
02361
02362 c = __oh323_new(pvt, AST_STATE_RINGING, pvt->cd.call_token, NULL);
02363
02364
02365 ast_mutex_unlock(&pvt->lock);
02366 if (!c) {
02367 ast_log(LOG_ERROR, "Couldn't create channel. This is bad\n");
02368 return 0;
02369 }
02370 return 1;
02371 }
02372
02373
02374
02375
02376
02377
02378 static int setup_outgoing_call(call_details_t *cd)
02379 {
02380
02381 cleanup_call_details(cd);
02382
02383 return 1;
02384 }
02385
02386
02387
02388
02389
02390 static void chan_ringing(unsigned call_reference, const char *token)
02391 {
02392 struct oh323_pvt *pvt;
02393
02394 if (h323debug)
02395 ast_debug(1, "Ringing on %s\n", token);
02396
02397 pvt = find_call_locked(call_reference, token);
02398 if (!pvt) {
02399 ast_log(LOG_ERROR, "Something is wrong: ringing\n");
02400 return;
02401 }
02402 if (!pvt->owner) {
02403 ast_mutex_unlock(&pvt->lock);
02404 ast_log(LOG_ERROR, "Channel has no owner\n");
02405 return;
02406 }
02407 update_state(pvt, AST_STATE_RINGING, AST_CONTROL_RINGING);
02408 ast_mutex_unlock(&pvt->lock);
02409 return;
02410 }
02411
02412
02413
02414
02415
02416 static void cleanup_connection(unsigned call_reference, const char *call_token)
02417 {
02418 struct oh323_pvt *pvt;
02419
02420 if (h323debug)
02421 ast_debug(1, "Cleaning connection to %s\n", call_token);
02422
02423 while (1) {
02424 pvt = find_call_locked(call_reference, call_token);
02425 if (!pvt) {
02426 if (h323debug)
02427 ast_debug(1, "No connection for %s\n", call_token);
02428 return;
02429 }
02430 if (!pvt->owner || !ast_channel_trylock(pvt->owner))
02431 break;
02432 #if 1
02433 ast_log(LOG_NOTICE, "Avoiding H.323 destory deadlock on %s\n", call_token);
02434 #ifdef DEBUG_THREADS
02435
02436
02437
02438
02439
02440 #endif
02441 #endif
02442 ast_mutex_unlock(&pvt->lock);
02443 usleep(1);
02444 }
02445 if (pvt->rtp) {
02446
02447 ast_rtp_instance_destroy(pvt->rtp);
02448 pvt->rtp = NULL;
02449 }
02450
02451 if (pvt->vad) {
02452 ast_dsp_free(pvt->vad);
02453 pvt->vad = NULL;
02454 }
02455 cleanup_call_details(&pvt->cd);
02456 pvt->alreadygone = 1;
02457
02458 if (pvt->owner) {
02459 pvt->owner->_softhangup |= AST_SOFTHANGUP_DEV;
02460 ast_queue_hangup(pvt->owner);
02461 ast_channel_unlock(pvt->owner);
02462 }
02463 ast_mutex_unlock(&pvt->lock);
02464 if (h323debug)
02465 ast_debug(1, "Connection to %s cleaned\n", call_token);
02466 return;
02467 }
02468
02469 static void hangup_connection(unsigned int call_reference, const char *token, int cause)
02470 {
02471 struct oh323_pvt *pvt;
02472
02473 if (h323debug)
02474 ast_debug(1, "Hanging up connection to %s with cause %d\n", token, cause);
02475
02476 pvt = find_call_locked(call_reference, token);
02477 if (!pvt) {
02478 if (h323debug)
02479 ast_debug(1, "Connection to %s already cleared\n", token);
02480 return;
02481 }
02482 if (pvt->owner && !ast_channel_trylock(pvt->owner)) {
02483 pvt->owner->_softhangup |= AST_SOFTHANGUP_DEV;
02484 pvt->owner->hangupcause = pvt->hangupcause = cause;
02485 ast_queue_hangup_with_cause(pvt->owner, cause);
02486 ast_channel_unlock(pvt->owner);
02487 }
02488 else {
02489 pvt->needhangup = 1;
02490 pvt->hangupcause = cause;
02491 if (h323debug)
02492 ast_debug(1, "Hangup for %s is pending\n", token);
02493 }
02494 ast_mutex_unlock(&pvt->lock);
02495 }
02496
02497 static void set_dtmf_payload(unsigned call_reference, const char *token, int payload, int is_cisco)
02498 {
02499 struct oh323_pvt *pvt;
02500
02501 if (h323debug)
02502 ast_debug(1, "Setting %s DTMF payload to %d on %s\n", (is_cisco ? "Cisco" : "RFC2833"), payload, token);
02503
02504 pvt = find_call_locked(call_reference, token);
02505 if (!pvt) {
02506 return;
02507 }
02508 if (pvt->rtp) {
02509 ast_rtp_codecs_payloads_set_rtpmap_type(ast_rtp_instance_get_codecs(pvt->rtp), pvt->rtp, payload, "audio", (is_cisco ? "cisco-telephone-event" : "telephone-event"), 0);
02510 }
02511 pvt->dtmf_pt[is_cisco ? 1 : 0] = payload;
02512 ast_mutex_unlock(&pvt->lock);
02513 if (h323debug)
02514 ast_debug(1, "DTMF payload on %s set to %d\n", token, payload);
02515 }
02516
02517 static void set_peer_capabilities(unsigned call_reference, const char *token, int capabilities, struct ast_codec_pref *prefs)
02518 {
02519 struct oh323_pvt *pvt;
02520
02521 if (h323debug)
02522 ast_debug(1, "Got remote capabilities from connection %s\n", token);
02523
02524 pvt = find_call_locked(call_reference, token);
02525 if (!pvt)
02526 return;
02527 pvt->peercapability = capabilities;
02528 pvt->jointcapability = pvt->options.capability & capabilities;
02529 if (prefs) {
02530 memcpy(&pvt->peer_prefs, prefs, sizeof(pvt->peer_prefs));
02531 if (h323debug) {
02532 int i;
02533 for (i = 0; i < 32; ++i) {
02534 if (!prefs->order[i])
02535 break;
02536 ast_debug(1, "prefs[%d]=%s:%d\n", i, (prefs->order[i] ? ast_getformatname(&prefs->formats[i]) : "<none>"), prefs->framing[i]);
02537 }
02538 }
02539 if (pvt->rtp) {
02540 if (pvt->options.autoframing) {
02541 ast_debug(2, "Autoframing option set, using peer's packetization settings\n");
02542 ast_rtp_codecs_packetization_set(ast_rtp_instance_get_codecs(pvt->rtp), pvt->rtp, &pvt->peer_prefs);
02543 } else {
02544 ast_debug(2, "Autoframing option not set, ignoring peer's packetization settings\n");
02545 ast_rtp_codecs_packetization_set(ast_rtp_instance_get_codecs(pvt->rtp), pvt->rtp, &pvt->options.prefs);
02546 }
02547 }
02548 }
02549 ast_mutex_unlock(&pvt->lock);
02550 }
02551
02552 static void set_local_capabilities(unsigned call_reference, const char *token)
02553 {
02554 struct oh323_pvt *pvt;
02555 int capability, dtmfmode, pref_codec;
02556 struct ast_codec_pref prefs;
02557
02558 if (h323debug)
02559 ast_debug(1, "Setting capabilities for connection %s\n", token);
02560
02561 pvt = find_call_locked(call_reference, token);
02562 if (!pvt)
02563 return;
02564 capability = (pvt->jointcapability) ? pvt->jointcapability : pvt->options.capability;
02565 dtmfmode = pvt->options.dtmfmode;
02566 prefs = pvt->options.prefs;
02567 pref_codec = pvt->pref_codec;
02568 ast_mutex_unlock(&pvt->lock);
02569 h323_set_capabilities(token, capability, dtmfmode, &prefs, pref_codec);
02570
02571 if (h323debug) {
02572 int i;
02573 for (i = 0; i < 32; i++) {
02574 if (!prefs.order[i])
02575 break;
02576 ast_debug(1, "local prefs[%d]=%s:%d\n", i, (prefs.order[i] ? ast_getformatname(&prefs.formats[i]) : "<none>"), prefs.framing[i]);
02577 }
02578 ast_debug(1, "Capabilities for connection %s is set\n", token);
02579 }
02580 }
02581
02582 static void remote_hold(unsigned call_reference, const char *token, int is_hold)
02583 {
02584 struct oh323_pvt *pvt;
02585
02586 if (h323debug)
02587 ast_debug(1, "Setting %shold status for connection %s\n", (is_hold ? "" : "un"), token);
02588
02589 pvt = find_call_locked(call_reference, token);
02590 if (!pvt)
02591 return;
02592 if (pvt->owner && !ast_channel_trylock(pvt->owner)) {
02593 if (is_hold)
02594 ast_queue_control(pvt->owner, AST_CONTROL_HOLD);
02595 else
02596 ast_queue_control(pvt->owner, AST_CONTROL_UNHOLD);
02597 ast_channel_unlock(pvt->owner);
02598 }
02599 else {
02600 if (is_hold)
02601 pvt->newcontrol = AST_CONTROL_HOLD;
02602 else
02603 pvt->newcontrol = AST_CONTROL_UNHOLD;
02604 }
02605 ast_mutex_unlock(&pvt->lock);
02606 }
02607
02608 static void *do_monitor(void *data)
02609 {
02610 int res;
02611 int reloading;
02612 struct oh323_pvt *oh323 = NULL;
02613
02614 for(;;) {
02615
02616 ast_mutex_lock(&h323_reload_lock);
02617 reloading = h323_reloading;
02618 h323_reloading = 0;
02619 ast_mutex_unlock(&h323_reload_lock);
02620 if (reloading) {
02621 ast_verb(1, "Reloading H.323\n");
02622 h323_do_reload();
02623 }
02624
02625 if (!ast_mutex_trylock(&iflock)) {
02626 #if 1
02627 do {
02628 for (oh323 = iflist; oh323; oh323 = oh323->next) {
02629 if (!ast_mutex_trylock(&oh323->lock)) {
02630 if (oh323->needdestroy) {
02631 __oh323_destroy(oh323);
02632 break;
02633 }
02634 ast_mutex_unlock(&oh323->lock);
02635 }
02636 }
02637 } while ( 0);
02638 #else
02639 restartsearch:
02640 oh323 = iflist;
02641 while(oh323) {
02642 if (!ast_mutex_trylock(&oh323->lock)) {
02643 if (oh323->needdestroy) {
02644 __oh323_destroy(oh323);
02645 goto restartsearch;
02646 }
02647 ast_mutex_unlock(&oh323->lock);
02648 oh323 = oh323->next;
02649 }
02650 }
02651 #endif
02652 ast_mutex_unlock(&iflock);
02653 } else
02654 oh323 = (struct oh323_pvt *)1;
02655 pthread_testcancel();
02656
02657 res = ast_sched_wait(sched);
02658 if ((res < 0) || (res > 1000)) {
02659 res = 1000;
02660 }
02661
02662 if (oh323)
02663 res = 1;
02664 res = ast_io_wait(io, res);
02665 pthread_testcancel();
02666 ast_mutex_lock(&monlock);
02667 if (res >= 0) {
02668 ast_sched_runq(sched);
02669 }
02670 ast_mutex_unlock(&monlock);
02671 }
02672
02673 return NULL;
02674 }
02675
02676 static int restart_monitor(void)
02677 {
02678
02679 if (ast_mutex_lock(&monlock)) {
02680 ast_log(LOG_WARNING, "Unable to lock monitor\n");
02681 return -1;
02682 }
02683 if (monitor_thread == AST_PTHREADT_STOP) {
02684 ast_mutex_unlock(&monlock);
02685 return 0;
02686 }
02687 if (monitor_thread == pthread_self()) {
02688 ast_mutex_unlock(&monlock);
02689 ast_log(LOG_WARNING, "Cannot kill myself\n");
02690 return -1;
02691 }
02692 if (monitor_thread && (monitor_thread != AST_PTHREADT_NULL)) {
02693
02694 pthread_kill(monitor_thread, SIGURG);
02695 } else {
02696
02697 if (ast_pthread_create_background(&monitor_thread, NULL, do_monitor, NULL) < 0) {
02698 monitor_thread = AST_PTHREADT_NULL;
02699 ast_mutex_unlock(&monlock);
02700 ast_log(LOG_ERROR, "Unable to start monitor thread.\n");
02701 return -1;
02702 }
02703 }
02704 ast_mutex_unlock(&monlock);
02705 return 0;
02706 }
02707
02708 static char *handle_cli_h323_set_trace(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
02709 {
02710 switch (cmd) {
02711 case CLI_INIT:
02712 e->command = "h323 set trace [on|off]";
02713 e->usage =
02714 "Usage: h323 set trace (on|off|<trace level>)\n"
02715 " Enable/Disable H.323 stack tracing for debugging purposes\n";
02716 return NULL;
02717 case CLI_GENERATE:
02718 return NULL;
02719 }
02720
02721 if (a->argc != e->args)
02722 return CLI_SHOWUSAGE;
02723 if (!strcasecmp(a->argv[3], "off")) {
02724 h323_debug(0, 0);
02725 ast_cli(a->fd, "H.323 Trace Disabled\n");
02726 } else if (!strcasecmp(a->argv[3], "on")) {
02727 h323_debug(1, 1);
02728 ast_cli(a->fd, "H.323 Trace Enabled\n");
02729 } else {
02730 int tracelevel = atoi(a->argv[3]);
02731 h323_debug(1, tracelevel);
02732 ast_cli(a->fd, "H.323 Trace Enabled (Trace Level: %d)\n", tracelevel);
02733 }
02734 return CLI_SUCCESS;
02735 }
02736
02737 static char *handle_cli_h323_set_debug(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
02738 {
02739 switch (cmd) {
02740 case CLI_INIT:
02741 e->command = "h323 set debug [on|off]";
02742 e->usage =
02743 "Usage: h323 set debug [on|off]\n"
02744 " Enable/Disable H.323 debugging output\n";
02745 return NULL;
02746 case CLI_GENERATE:
02747 return NULL;
02748 }
02749
02750 if (a->argc != e->args)
02751 return CLI_SHOWUSAGE;
02752 if (strcasecmp(a->argv[3], "on") && strcasecmp(a->argv[3], "off"))
02753 return CLI_SHOWUSAGE;
02754
02755 h323debug = (strcasecmp(a->argv[3], "on")) ? 0 : 1;
02756 ast_cli(a->fd, "H.323 Debugging %s\n", h323debug ? "Enabled" : "Disabled");
02757 return CLI_SUCCESS;
02758 }
02759
02760 static char *handle_cli_h323_cycle_gk(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
02761 {
02762 switch (cmd) {
02763 case CLI_INIT:
02764 e->command = "h323 cycle gk";
02765 e->usage =
02766 "Usage: h323 cycle gk\n"
02767 " Manually re-register with the Gatekeper (Currently Disabled)\n";
02768 return NULL;
02769 case CLI_GENERATE:
02770 return NULL;
02771 }
02772
02773 if (a->argc != 3)
02774 return CLI_SHOWUSAGE;
02775
02776 h323_gk_urq();
02777
02778
02779 if (!gatekeeper_disable) {
02780 if (h323_set_gk(gatekeeper_discover, gatekeeper, secret)) {
02781 ast_log(LOG_ERROR, "Gatekeeper registration failed.\n");
02782 }
02783 }
02784 return CLI_SUCCESS;
02785 }
02786
02787 static char *handle_cli_h323_hangup(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
02788 {
02789 switch (cmd) {
02790 case CLI_INIT:
02791 e->command = "h323 hangup";
02792 e->usage =
02793 "Usage: h323 hangup <token>\n"
02794 " Manually try to hang up the call identified by <token>\n";
02795 return NULL;
02796 case CLI_GENERATE:
02797 return NULL;
02798 }
02799
02800 if (a->argc != 3)
02801 return CLI_SHOWUSAGE;
02802 if (h323_soft_hangup(a->argv[2])) {
02803 ast_verb(3, "Hangup succeeded on %s\n", a->argv[2]);
02804 } else {
02805 ast_verb(3, "Hangup failed for %s\n", a->argv[2]);
02806 }
02807 return CLI_SUCCESS;
02808 }
02809
02810 static char *handle_cli_h323_show_tokens(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
02811 {
02812 switch (cmd) {
02813 case CLI_INIT:
02814 e->command = "h323 show tokens";
02815 e->usage =
02816 "Usage: h323 show tokens\n"
02817 " Print out all active call tokens\n";
02818 return NULL;
02819 case CLI_GENERATE:
02820 return NULL;
02821 }
02822
02823 if (a->argc != 3)
02824 return CLI_SHOWUSAGE;
02825
02826 h323_show_tokens();
02827
02828 return CLI_SUCCESS;
02829 }
02830
02831 static char *handle_cli_h323_show_version(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
02832 {
02833 switch (cmd) {
02834 case CLI_INIT:
02835 e->command = "h323 show version";
02836 e->usage =
02837 "Usage: h323 show version\n"
02838 " Show the version of the H.323 library in use\n";
02839 return NULL;
02840 case CLI_GENERATE:
02841 return NULL;
02842 }
02843
02844 if (a->argc != 3)
02845 return CLI_SHOWUSAGE;
02846
02847 h323_show_version();
02848
02849 return CLI_SUCCESS;
02850 }
02851
02852 static struct ast_cli_entry cli_h323[] = {
02853 AST_CLI_DEFINE(handle_cli_h323_set_trace, "Enable/Disable H.323 Stack Tracing"),
02854 AST_CLI_DEFINE(handle_cli_h323_set_debug, "Enable/Disable H.323 Debugging"),
02855 AST_CLI_DEFINE(handle_cli_h323_cycle_gk, "Manually re-register with the Gatekeper"),
02856 AST_CLI_DEFINE(handle_cli_h323_hangup, "Manually try to hang up a call"),
02857 AST_CLI_DEFINE(handle_cli_h323_show_tokens, "Show all active call tokens"),
02858 AST_CLI_DEFINE(handle_cli_h323_show_version, "Show the version of the H.323 library in use"),
02859 };
02860
02861 static void delete_users(void)
02862 {
02863 int pruned = 0;
02864
02865
02866 ASTOBJ_CONTAINER_WRLOCK(&userl);
02867 ASTOBJ_CONTAINER_TRAVERSE(&userl, 1, do {
02868 ASTOBJ_RDLOCK(iterator);
02869 ASTOBJ_MARK(iterator);
02870 ++pruned;
02871 ASTOBJ_UNLOCK(iterator);
02872 } while (0) );
02873 if (pruned) {
02874 ASTOBJ_CONTAINER_PRUNE_MARKED(&userl, oh323_destroy_user);
02875 }
02876 ASTOBJ_CONTAINER_UNLOCK(&userl);
02877
02878 ASTOBJ_CONTAINER_WRLOCK(&peerl);
02879 ASTOBJ_CONTAINER_TRAVERSE(&peerl, 1, do {
02880 ASTOBJ_RDLOCK(iterator);
02881 ASTOBJ_MARK(iterator);
02882 ASTOBJ_UNLOCK(iterator);
02883 } while (0) );
02884 ASTOBJ_CONTAINER_UNLOCK(&peerl);
02885 }
02886
02887 static void delete_aliases(void)
02888 {
02889 int pruned = 0;
02890
02891
02892 ASTOBJ_CONTAINER_WRLOCK(&aliasl);
02893 ASTOBJ_CONTAINER_TRAVERSE(&aliasl, 1, do {
02894 ASTOBJ_RDLOCK(iterator);
02895 ASTOBJ_MARK(iterator);
02896 ++pruned;
02897 ASTOBJ_UNLOCK(iterator);
02898 } while (0) );
02899 if (pruned) {
02900 ASTOBJ_CONTAINER_PRUNE_MARKED(&aliasl, oh323_destroy_alias);
02901 }
02902 ASTOBJ_CONTAINER_UNLOCK(&aliasl);
02903 }
02904
02905 static void prune_peers(void)
02906 {
02907
02908 ASTOBJ_CONTAINER_PRUNE_MARKED(&peerl, oh323_destroy_peer);
02909 }
02910
02911 static int reload_config(int is_reload)
02912 {
02913 struct ast_config *cfg, *ucfg;
02914 struct ast_variable *v;
02915 struct oh323_peer *peer = NULL;
02916 struct oh323_user *user = NULL;
02917 struct oh323_alias *alias = NULL;
02918 struct ast_hostent ahp; struct hostent *hp;
02919 char *cat;
02920 const char *utype;
02921 int is_user, is_peer, is_alias;
02922 char _gatekeeper[100];
02923 int gk_discover, gk_disable, gk_changed;
02924 struct ast_flags config_flags = { is_reload ? CONFIG_FLAG_FILEUNCHANGED : 0 };
02925
02926 cfg = ast_config_load(config, config_flags);
02927
02928
02929 if (!cfg) {
02930 ast_log(LOG_NOTICE, "Unable to load config %s, H.323 disabled\n", config);
02931 return 1;
02932 } else if (cfg == CONFIG_STATUS_FILEUNCHANGED) {
02933 ucfg = ast_config_load("users.conf", config_flags);
02934 if (ucfg == CONFIG_STATUS_FILEUNCHANGED) {
02935 return 0;
02936 } else if (ucfg == CONFIG_STATUS_FILEINVALID) {
02937 ast_log(LOG_ERROR, "Config file users.conf is in an invalid format. Aborting.\n");
02938 return 0;
02939 }
02940 ast_clear_flag(&config_flags, CONFIG_FLAG_FILEUNCHANGED);
02941 if ((cfg = ast_config_load(config, config_flags)) == CONFIG_STATUS_FILEINVALID) {
02942 ast_log(LOG_ERROR, "Config file %s is in an invalid format. Aborting.\n", config);
02943 ast_config_destroy(ucfg);
02944 return 0;
02945 }
02946 } else if (cfg == CONFIG_STATUS_FILEINVALID) {
02947 ast_log(LOG_ERROR, "Config file %s is in an invalid format. Aborting.\n", config);
02948 return 0;
02949 } else {
02950 ast_clear_flag(&config_flags, CONFIG_FLAG_FILEUNCHANGED);
02951 if ((ucfg = ast_config_load("users.conf", config_flags)) == CONFIG_STATUS_FILEINVALID) {
02952 ast_log(LOG_ERROR, "Config file users.conf is in an invalid format. Aborting.\n");
02953 ast_config_destroy(cfg);
02954 return 0;
02955 }
02956 }
02957
02958 if (is_reload) {
02959 delete_users();
02960 delete_aliases();
02961 prune_peers();
02962 }
02963
02964
02965 if (!h323_end_point_exist()) {
02966 h323_end_point_create();
02967 }
02968 ast_copy_string(_gatekeeper, gatekeeper, sizeof(_gatekeeper));
02969 gk_discover = gatekeeper_discover;
02970 gk_disable = gatekeeper_disable;
02971 memset(&bindaddr, 0, sizeof(bindaddr));
02972 memset(&global_options, 0, sizeof(global_options));
02973 global_options.fastStart = 1;
02974 global_options.h245Tunneling = 1;
02975 global_options.dtmfcodec[0] = H323_DTMF_RFC2833_PT;
02976 global_options.dtmfcodec[1] = H323_DTMF_CISCO_PT;
02977 global_options.dtmfmode = 0;
02978 global_options.holdHandling = 0;
02979 global_options.capability = GLOBAL_CAPABILITY;
02980 global_options.bridge = 1;
02981 global_options.autoframing = 0;
02982 strcpy(default_context, "default");
02983 h323_signalling_port = 1720;
02984 gatekeeper_disable = 1;
02985 gatekeeper_discover = 0;
02986 gkroute = 0;
02987 userbyalias = 1;
02988 acceptAnonymous = 1;
02989 tos = 0;
02990 cos = 0;
02991
02992
02993 memcpy(&global_jbconf, &default_jbconf, sizeof(struct ast_jb_conf));
02994
02995 if (ucfg) {
02996 struct ast_variable *gen;
02997 int genhas_h323;
02998 const char *has_h323;
02999
03000 genhas_h323 = ast_true(ast_variable_retrieve(ucfg, "general", "hash323"));
03001 gen = ast_variable_browse(ucfg, "general");
03002 for (cat = ast_category_browse(ucfg, NULL); cat; cat = ast_category_browse(ucfg, cat)) {
03003 if (strcasecmp(cat, "general")) {
03004 has_h323 = ast_variable_retrieve(ucfg, cat, "hash323");
03005 if (ast_true(has_h323) || (!has_h323 && genhas_h323)) {
03006 user = build_user(cat, gen, ast_variable_browse(ucfg, cat), 0);
03007 if (user) {
03008 ASTOBJ_CONTAINER_LINK(&userl, user);
03009 ASTOBJ_UNREF(user, oh323_destroy_user);
03010 }
03011 peer = build_peer(cat, gen, ast_variable_browse(ucfg, cat), 0);
03012 if (peer) {
03013 ASTOBJ_CONTAINER_LINK(&peerl, peer);
03014 ASTOBJ_UNREF(peer, oh323_destroy_peer);
03015 }
03016 }
03017 }
03018 }
03019 ast_config_destroy(ucfg);
03020 }
03021
03022 for (v = ast_variable_browse(cfg, "general"); v; v = v->next) {
03023
03024 if (!ast_jb_read_conf(&global_jbconf, v->name, v->value))
03025 continue;
03026
03027 if (!strcasecmp(v->name, "port")) {
03028 h323_signalling_port = (int)strtol(v->value, NULL, 10);
03029 } else if (!strcasecmp(v->name, "bindaddr")) {
03030 if (!(hp = ast_gethostbyname(v->value, &ahp))) {
03031 ast_log(LOG_WARNING, "Invalid address: %s\n", v->value);
03032 } else {
03033 memcpy(&bindaddr.sin_addr, hp->h_addr, sizeof(bindaddr.sin_addr));
03034 }
03035 } else if (!strcasecmp(v->name, "tos")) {
03036 ast_log(LOG_WARNING, "The \"tos\" setting is deprecated in this version of Asterisk. Please change to \"tos_audio\".\n");
03037 if (ast_str2tos(v->value, &tos)) {
03038 ast_log(LOG_WARNING, "Invalid tos_audio value at line %d, refer to QoS documentation\n", v->lineno);
03039 }
03040 } else if (!strcasecmp(v->name, "tos_audio")) {
03041 if (ast_str2tos(v->value, &tos)) {
03042 ast_log(LOG_WARNING, "Invalid tos_audio value at line %d, refer to QoS documentation\n", v->lineno);
03043 }
03044 } else if (!strcasecmp(v->name, "cos")) {
03045 ast_log(LOG_WARNING, "The \"cos\" setting is deprecated in this version of Asterisk. Please change to \"cos_audio\".\n");
03046 if (ast_str2cos(v->value, &cos)) {
03047 ast_log(LOG_WARNING, "Invalid cos_audio value at line %d, refer to QoS documentation\n", v->lineno);
03048 }
03049 } else if (!strcasecmp(v->name, "cos_audio")) {
03050 if (ast_str2cos(v->value, &cos)) {
03051 ast_log(LOG_WARNING, "Invalid cos_audio value at line %d, refer to QoS documentation\n", v->lineno);
03052 }
03053 } else if (!strcasecmp(v->name, "gatekeeper")) {
03054 if (!strcasecmp(v->value, "DISABLE")) {
03055 gatekeeper_disable = 1;
03056 } else if (!strcasecmp(v->value, "DISCOVER")) {
03057 gatekeeper_disable = 0;
03058 gatekeeper_discover = 1;
03059 } else {
03060 gatekeeper_disable = 0;
03061 ast_copy_string(gatekeeper, v->value, sizeof(gatekeeper));
03062 }
03063 } else if (!strcasecmp(v->name, "secret")) {
03064 ast_copy_string(secret, v->value, sizeof(secret));
03065 } else if (!strcasecmp(v->name, "AllowGKRouted")) {
03066 gkroute = ast_true(v->value);
03067 } else if (!strcasecmp(v->name, "context")) {
03068 ast_copy_string(default_context, v->value, sizeof(default_context));
03069 ast_verb(2, "Setting default context to %s\n", default_context);
03070 } else if (!strcasecmp(v->name, "UserByAlias")) {
03071 userbyalias = ast_true(v->value);
03072 } else if (!strcasecmp(v->name, "AcceptAnonymous")) {
03073 acceptAnonymous = ast_true(v->value);
03074 } else if (!update_common_options(v, &global_options)) {
03075
03076 }
03077 }
03078 if (!global_options.dtmfmode)
03079 global_options.dtmfmode = H323_DTMF_RFC2833;
03080 if (global_options.holdHandling == ~0)
03081 global_options.holdHandling = 0;
03082 else if (!global_options.holdHandling)
03083 global_options.holdHandling = H323_HOLD_H450;
03084
03085 for (cat = ast_category_browse(cfg, NULL); cat; cat = ast_category_browse(cfg, cat)) {
03086 if (strcasecmp(cat, "general")) {
03087 utype = ast_variable_retrieve(cfg, cat, "type");
03088 if (utype) {
03089 is_user = is_peer = is_alias = 0;
03090 if (!strcasecmp(utype, "user"))
03091 is_user = 1;
03092 else if (!strcasecmp(utype, "peer"))
03093 is_peer = 1;
03094 else if (!strcasecmp(utype, "friend"))
03095 is_user = is_peer = 1;
03096 else if (!strcasecmp(utype, "h323") || !strcasecmp(utype, "alias"))
03097 is_alias = 1;
03098 else {
03099 ast_log(LOG_WARNING, "Unknown type '%s' for '%s' in %s\n", utype, cat, config);
03100 continue;
03101 }
03102 if (is_user) {
03103 user = build_user(cat, ast_variable_browse(cfg, cat), NULL, 0);
03104 if (user) {
03105 ASTOBJ_CONTAINER_LINK(&userl, user);
03106 ASTOBJ_UNREF(user, oh323_destroy_user);
03107 }
03108 }
03109 if (is_peer) {
03110 peer = build_peer(cat, ast_variable_browse(cfg, cat), NULL, 0);
03111 if (peer) {
03112 ASTOBJ_CONTAINER_LINK(&peerl, peer);
03113 ASTOBJ_UNREF(peer, oh323_destroy_peer);
03114 }
03115 }
03116 if (is_alias) {
03117 alias = build_alias(cat, ast_variable_browse(cfg, cat), NULL, 0);
03118 if (alias) {
03119 ASTOBJ_CONTAINER_LINK(&aliasl, alias);
03120 ASTOBJ_UNREF(alias, oh323_destroy_alias);
03121 }
03122 }
03123 } else {
03124 ast_log(LOG_WARNING, "Section '%s' lacks type\n", cat);
03125 }
03126 }
03127 }
03128 ast_config_destroy(cfg);
03129
03130
03131 ASTOBJ_CONTAINER_WRLOCK(&aliasl);
03132 ASTOBJ_CONTAINER_TRAVERSE(&aliasl, 1, do {
03133 ASTOBJ_RDLOCK(iterator);
03134 if (h323_set_alias(iterator)) {
03135 ast_log(LOG_ERROR, "Alias %s rejected by endpoint\n", alias->name);
03136 ASTOBJ_UNLOCK(iterator);
03137 continue;
03138 }
03139 ASTOBJ_UNLOCK(iterator);
03140 } while (0) );
03141 ASTOBJ_CONTAINER_UNLOCK(&aliasl);
03142
03143
03144 gk_changed = 0;
03145 if (gatekeeper_disable != gk_disable)
03146 gk_changed = is_reload;
03147 else if(!gatekeeper_disable && (gatekeeper_discover != gk_discover))
03148 gk_changed = is_reload;
03149 else if(!gatekeeper_disable && (strncmp(_gatekeeper, gatekeeper, sizeof(_gatekeeper)) != 0))
03150 gk_changed = is_reload;
03151 if (gk_changed) {
03152 if(!gk_disable)
03153 h323_gk_urq();
03154 if (!gatekeeper_disable) {
03155 if (h323_set_gk(gatekeeper_discover, gatekeeper, secret)) {
03156 ast_log(LOG_ERROR, "Gatekeeper registration failed.\n");
03157 gatekeeper_disable = 1;
03158 }
03159 }
03160 }
03161 return 0;
03162 }
03163
03164 static int h323_reload(void)
03165 {
03166 ast_mutex_lock(&h323_reload_lock);
03167 if (h323_reloading) {
03168 ast_verbose("Previous H.323 reload not yet done\n");
03169 } else {
03170 h323_reloading = 1;
03171 }
03172 ast_mutex_unlock(&h323_reload_lock);
03173 restart_monitor();
03174 return 0;
03175 }
03176
03177 static char *handle_cli_h323_reload(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
03178 {
03179 switch (cmd) {
03180 case CLI_INIT:
03181 e->command = "h323 reload";
03182 e->usage =
03183 "Usage: h323 reload\n"
03184 " Reloads H.323 configuration from h323.conf\n";
03185 return NULL;
03186 case CLI_GENERATE:
03187 return NULL;
03188 }
03189
03190 if (a->argc != 2)
03191 return CLI_SHOWUSAGE;
03192
03193 h323_reload();
03194
03195 return CLI_SUCCESS;
03196 }
03197
03198 static int h323_do_reload(void)
03199 {
03200 reload_config(1);
03201 return 0;
03202 }
03203
03204 static int reload(void)
03205 {
03206 if (!sched || !io) {
03207 ast_log(LOG_NOTICE, "Unload and load chan_h323.so again in order to receive configuration changes.\n");
03208 return 0;
03209 }
03210 return h323_reload();
03211 }
03212
03213 static struct ast_cli_entry cli_h323_reload =
03214 AST_CLI_DEFINE(handle_cli_h323_reload, "Reload H.323 configuration");
03215
03216 static enum ast_rtp_glue_result oh323_get_rtp_peer(struct ast_channel *chan, struct ast_rtp_instance **instance)
03217 {
03218 struct oh323_pvt *pvt;
03219 enum ast_rtp_glue_result res = AST_RTP_GLUE_RESULT_LOCAL;
03220
03221 if (!(pvt = (struct oh323_pvt *)chan->tech_pvt))
03222 return AST_RTP_GLUE_RESULT_FORBID;
03223
03224 ast_mutex_lock(&pvt->lock);
03225 *instance = pvt->rtp ? ao2_ref(pvt->rtp, +1), pvt->rtp : NULL;
03226 #if 0
03227 if (pvt->options.bridge) {
03228 res = AST_RTP_GLUE_RESULT_REMOTE;
03229 }
03230 #endif
03231 ast_mutex_unlock(&pvt->lock);
03232
03233 return res;
03234 }
03235
03236 #if 0
03237 static char *convertcap(struct ast_format *format)
03238 {
03239 switch (format->id) {
03240 case AST_FORMAT_G723_1:
03241 return "G.723";
03242 case AST_FORMAT_GSM:
03243 return "GSM";
03244 case AST_FORMAT_ULAW:
03245 return "ULAW";
03246 case AST_FORMAT_ALAW:
03247 return "ALAW";
03248 case AST_FORMAT_G722:
03249 return "G.722";
03250 case AST_FORMAT_ADPCM:
03251 return "G.728";
03252 case AST_FORMAT_G729A:
03253 return "G.729";
03254 case AST_FORMAT_SPEEX:
03255 return "SPEEX";
03256 case AST_FORMAT_ILBC:
03257 return "ILBC";
03258 default:
03259 ast_log(LOG_NOTICE, "Don't know how to deal with mode %s\n", ast_getformatname(format));
03260 return NULL;
03261 }
03262 }
03263 #endif
03264
03265 static int oh323_set_rtp_peer(struct ast_channel *chan, struct ast_rtp_instance *rtp, struct ast_rtp_instance *vrtp, struct ast_rtp_instance *trtp, const struct ast_format_cap *codecs, int nat_active)
03266 {
03267
03268 struct oh323_pvt *pvt;
03269 struct sockaddr_in them = { 0, };
03270 struct sockaddr_in us = { 0, };
03271 #if 0
03272 char *mode;
03273 #endif
03274
03275 if (!rtp) {
03276 return 0;
03277 }
03278
03279 #if 0
03280 mode = convertcap(&chan->writeformat);
03281 #endif
03282
03283 pvt = (struct oh323_pvt *) chan->tech_pvt;
03284 if (!pvt) {
03285 ast_log(LOG_ERROR, "No Private Structure, this is bad\n");
03286 return -1;
03287 }
03288 {
03289 struct ast_sockaddr tmp;
03290
03291 ast_rtp_instance_get_remote_address(rtp, &tmp);
03292 ast_sockaddr_to_sin(&tmp, &them);
03293 ast_rtp_instance_get_local_address(rtp, &tmp);
03294 ast_sockaddr_to_sin(&tmp, &us);
03295 }
03296 #if 0
03297 h323_native_bridge(pvt->cd.call_token, ast_inet_ntoa(them.sin_addr), mode);
03298 #endif
03299 return 0;
03300 }
03301
03302 static struct ast_rtp_glue oh323_rtp_glue = {
03303 .type = "H323",
03304 .get_rtp_info = oh323_get_rtp_peer,
03305 .update_peer = oh323_set_rtp_peer,
03306 };
03307
03308 static enum ast_module_load_result load_module(void)
03309 {
03310 int res;
03311
03312 if (!(oh323_tech.capabilities = ast_format_cap_alloc())) {
03313 return AST_MODULE_LOAD_FAILURE;
03314 }
03315 ast_format_cap_add_all_by_type(oh323_tech.capabilities, AST_FORMAT_TYPE_AUDIO);
03316
03317 h323debug = 0;
03318 sched = ast_sched_context_create();
03319 if (!sched) {
03320 ast_log(LOG_WARNING, "Unable to create schedule context\n");
03321 return AST_MODULE_LOAD_FAILURE;
03322 }
03323 io = io_context_create();
03324 if (!io) {
03325 ast_log(LOG_WARNING, "Unable to create I/O context\n");
03326 return AST_MODULE_LOAD_FAILURE;
03327 }
03328 ast_cli_register(&cli_h323_reload);
03329 ASTOBJ_CONTAINER_INIT(&userl);
03330 ASTOBJ_CONTAINER_INIT(&peerl);
03331 ASTOBJ_CONTAINER_INIT(&aliasl);
03332 res = reload_config(0);
03333 if (res) {
03334
03335 ast_log(LOG_NOTICE, "Unload and load chan_h323.so again in order to receive configuration changes.\n");
03336 ast_cli_unregister(&cli_h323_reload);
03337 io_context_destroy(io);
03338 io = NULL;
03339 ast_sched_context_destroy(sched);
03340 sched = NULL;
03341 ASTOBJ_CONTAINER_DESTROY(&userl);
03342 ASTOBJ_CONTAINER_DESTROY(&peerl);
03343 ASTOBJ_CONTAINER_DESTROY(&aliasl);
03344 return AST_MODULE_LOAD_DECLINE;
03345 } else {
03346
03347 if (ast_channel_register(&oh323_tech)) {
03348 ast_log(LOG_ERROR, "Unable to register channel class 'H323'\n");
03349 ast_cli_unregister(&cli_h323_reload);
03350 h323_end_process();
03351 io_context_destroy(io);
03352 ast_sched_context_destroy(sched);
03353
03354 ASTOBJ_CONTAINER_DESTROYALL(&userl, oh323_destroy_user);
03355 ASTOBJ_CONTAINER_DESTROY(&userl);
03356 ASTOBJ_CONTAINER_DESTROYALL(&peerl, oh323_destroy_peer);
03357 ASTOBJ_CONTAINER_DESTROY(&peerl);
03358 ASTOBJ_CONTAINER_DESTROYALL(&aliasl, oh323_destroy_alias);
03359 ASTOBJ_CONTAINER_DESTROY(&aliasl);
03360
03361 return AST_MODULE_LOAD_FAILURE;
03362 }
03363 ast_cli_register_multiple(cli_h323, sizeof(cli_h323) / sizeof(struct ast_cli_entry));
03364
03365 ast_rtp_glue_register(&oh323_rtp_glue);
03366
03367
03368 h323_callback_register(setup_incoming_call,
03369 setup_outgoing_call,
03370 external_rtp_create,
03371 setup_rtp_connection,
03372 cleanup_connection,
03373 chan_ringing,
03374 connection_made,
03375 receive_digit,
03376 answer_call,
03377 progress,
03378 set_dtmf_payload,
03379 hangup_connection,
03380 set_local_capabilities,
03381 set_peer_capabilities,
03382 remote_hold);
03383
03384 if (h323_start_listener(h323_signalling_port, bindaddr)) {
03385 ast_log(LOG_ERROR, "Unable to create H323 listener.\n");
03386 ast_rtp_glue_unregister(&oh323_rtp_glue);
03387 ast_cli_unregister_multiple(cli_h323, sizeof(cli_h323) / sizeof(struct ast_cli_entry));
03388 ast_cli_unregister(&cli_h323_reload);
03389 h323_end_process();
03390 io_context_destroy(io);
03391 ast_sched_context_destroy(sched);
03392
03393 ASTOBJ_CONTAINER_DESTROYALL(&userl, oh323_destroy_user);
03394 ASTOBJ_CONTAINER_DESTROY(&userl);
03395 ASTOBJ_CONTAINER_DESTROYALL(&peerl, oh323_destroy_peer);
03396 ASTOBJ_CONTAINER_DESTROY(&peerl);
03397 ASTOBJ_CONTAINER_DESTROYALL(&aliasl, oh323_destroy_alias);
03398 ASTOBJ_CONTAINER_DESTROY(&aliasl);
03399
03400 return AST_MODULE_LOAD_DECLINE;
03401 }
03402
03403 if (!gatekeeper_disable) {
03404 if (h323_set_gk(gatekeeper_discover, gatekeeper, secret)) {
03405 ast_log(LOG_ERROR, "Gatekeeper registration failed.\n");
03406 gatekeeper_disable = 1;
03407 res = AST_MODULE_LOAD_SUCCESS;
03408 }
03409 }
03410
03411 restart_monitor();
03412 }
03413 return res;
03414 }
03415
03416 static int unload_module(void)
03417 {
03418 struct oh323_pvt *p, *pl;
03419
03420
03421 ast_cli_unregister_multiple(cli_h323, sizeof(cli_h323) / sizeof(struct ast_cli_entry));
03422 ast_cli_unregister(&cli_h323_reload);
03423
03424 ast_channel_unregister(&oh323_tech);
03425 ast_rtp_glue_unregister(&oh323_rtp_glue);
03426
03427 if (!ast_mutex_lock(&iflock)) {
03428
03429 p = iflist;
03430 while(p) {
03431 if (p->owner) {
03432 ast_softhangup(p->owner, AST_SOFTHANGUP_APPUNLOAD);
03433 }
03434 p = p->next;
03435 }
03436 iflist = NULL;
03437 ast_mutex_unlock(&iflock);
03438 } else {
03439 ast_log(LOG_WARNING, "Unable to lock the interface list\n");
03440 return -1;
03441 }
03442 if (!ast_mutex_lock(&monlock)) {
03443 if ((monitor_thread != AST_PTHREADT_STOP) && (monitor_thread != AST_PTHREADT_NULL)) {
03444 if (monitor_thread != pthread_self()) {
03445 pthread_cancel(monitor_thread);
03446 }
03447 pthread_kill(monitor_thread, SIGURG);
03448 pthread_join(monitor_thread, NULL);
03449 }
03450 monitor_thread = AST_PTHREADT_STOP;
03451 ast_mutex_unlock(&monlock);
03452 } else {
03453 ast_log(LOG_WARNING, "Unable to lock the monitor\n");
03454 return -1;
03455 }
03456 if (!ast_mutex_lock(&iflock)) {
03457
03458 p = iflist;
03459 while(p) {
03460 pl = p;
03461 p = p->next;
03462
03463 ast_mutex_destroy(&pl->lock);
03464 ast_free(pl);
03465 }
03466 iflist = NULL;
03467 ast_mutex_unlock(&iflock);
03468 } else {
03469 ast_log(LOG_WARNING, "Unable to lock the interface list\n");
03470 return -1;
03471 }
03472 if (!gatekeeper_disable)
03473 h323_gk_urq();
03474 h323_end_process();
03475 if (io)
03476 io_context_destroy(io);
03477 if (sched)
03478 ast_sched_context_destroy(sched);
03479
03480 ASTOBJ_CONTAINER_DESTROYALL(&userl, oh323_destroy_user);
03481 ASTOBJ_CONTAINER_DESTROY(&userl);
03482 ASTOBJ_CONTAINER_DESTROYALL(&peerl, oh323_destroy_peer);
03483 ASTOBJ_CONTAINER_DESTROY(&peerl);
03484 ASTOBJ_CONTAINER_DESTROYALL(&aliasl, oh323_destroy_alias);
03485 ASTOBJ_CONTAINER_DESTROY(&aliasl);
03486
03487 oh323_tech.capabilities = ast_format_cap_destroy(oh323_tech.capabilities);
03488 return 0;
03489 }
03490
03491 AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_LOAD_ORDER, "The NuFone Network's OpenH323 Channel Driver",
03492 .load = load_module,
03493 .unload = unload_module,
03494 .reload = reload,
03495 .load_pri = AST_MODPRI_CHANNEL_DRIVER,
03496 );