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: 398510 $")
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(ast_channel_nativeformats(c));
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(ast_channel_nativeformats(c), pvt->nativeformats);
00349 ast_set_read_format(c, ast_channel_readformat(c));
00350 ast_set_write_format(c, ast_channel_writeformat(c));
00351 }
00352 if (pvt->needhangup) {
00353 if (h323debug)
00354 ast_debug(1, "Process pending hangup for %s\n", ast_channel_name(c));
00355 ast_channel_softhangup_internal_flag_add(c, AST_SOFTHANGUP_DEV);
00356 ast_channel_hangupcause_set(c, 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 = ast_channel_tech_pvt(c);
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 ast_channel_tech_pvt_set(pvt->owner, 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 *) ast_channel_tech_pvt(c);
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 *) ast_channel_tech_pvt(c);
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 *)ast_channel_tech_pvt(c);
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 ((ast_channel_state(c) != AST_STATE_DOWN) && (ast_channel_state(c) != 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 (ast_channel_connected(c)->id.number.valid && ast_channel_connected(c)->id.number.str) {
00624 ast_copy_string(pvt->options.cid_num, ast_channel_connected(c)->id.number.str, sizeof(pvt->options.cid_num));
00625 }
00626
00627 if (ast_channel_connected(c)->id.name.valid && ast_channel_connected(c)->id.name.str) {
00628 ast_copy_string(pvt->options.cid_name, ast_channel_connected(c)->id.name.str, sizeof(pvt->options.cid_name));
00629 }
00630
00631 if (ast_channel_redirecting(c)->from.number.valid && ast_channel_redirecting(c)->from.number.str) {
00632 ast_copy_string(pvt->options.cid_rdnis, ast_channel_redirecting(c)->from.number.str, sizeof(pvt->options.cid_rdnis));
00633 }
00634
00635 pvt->options.presentation = ast_party_id_presentation(&ast_channel_connected(c)->id);
00636 pvt->options.type_of_number = ast_channel_connected(c)->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 = ast_channel_transfercapability(c);
00653
00654
00655 pvt->outgoing = 1;
00656
00657 ast_verb(3, "Requested transfer capability: 0x%.2x - %s\n", ast_channel_transfercapability(c), ast_transfercapability2str(ast_channel_transfercapability(c)));
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 *) ast_channel_tech_pvt(c);
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 (ast_channel_state(c) != 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 *) ast_channel_tech_pvt(c);
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 (!ast_channel_tech_pvt(c)) {
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 ast_channel_tech_pvt_set(c, NULL);
00717
00718 if (ast_channel_hangupcause(c)) {
00719 q931cause = ast_channel_hangupcause(c);
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(ast_channel_nativeformats(pvt->owner), &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(ast_channel_nativeformats(pvt->owner), &f->subclass.format);
00787
00788 pvt->nativeformats = ast_format_to_old_bitfield(&f->subclass.format);
00789
00790 ast_set_read_format(pvt->owner, ast_channel_readformat(pvt->owner));
00791 ast_set_write_format(pvt->owner, ast_channel_writeformat(pvt->owner));
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 *)ast_channel_tech_pvt(c);
00821 ast_mutex_lock(&pvt->lock);
00822 __oh323_update_info(c, pvt);
00823 switch(ast_channel_fdno(c)) {
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", ast_channel_fdno(c), 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 *) ast_channel_tech_pvt(c);
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(ast_channel_nativeformats(c), &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),
00858 ast_getformatname_multiple(tmp, sizeof(tmp), ast_channel_nativeformats(c)),
00859 ast_getformatname(ast_channel_readformat(c)),
00860 ast_getformatname(ast_channel_writeformat(c)));
00861 return 0;
00862 }
00863 }
00864 if (pvt) {
00865 ast_mutex_lock(&pvt->lock);
00866 if (pvt->rtp && !pvt->recvonly)
00867 res = ast_rtp_instance_write(pvt->rtp, frame);
00868 __oh323_update_info(c, pvt);
00869 ast_mutex_unlock(&pvt->lock);
00870 }
00871 return res;
00872 }
00873
00874 static int oh323_indicate(struct ast_channel *c, int condition, const void *data, size_t datalen)
00875 {
00876
00877 struct oh323_pvt *pvt = (struct oh323_pvt *) ast_channel_tech_pvt(c);
00878 char *token = (char *)NULL;
00879 int res = -1;
00880 int got_progress;
00881
00882 ast_mutex_lock(&pvt->lock);
00883 token = (pvt->cd.call_token ? ast_strdup(pvt->cd.call_token) : NULL);
00884 got_progress = pvt->got_progress;
00885 if (condition == AST_CONTROL_PROGRESS)
00886 pvt->got_progress = 1;
00887 else if ((condition == AST_CONTROL_BUSY) || (condition == AST_CONTROL_CONGESTION))
00888 pvt->alreadygone = 1;
00889 ast_mutex_unlock(&pvt->lock);
00890
00891 if (h323debug)
00892 ast_debug(1, "OH323: Indicating %d on %s (%s)\n", condition, token, ast_channel_name(c));
00893
00894 switch(condition) {
00895 case AST_CONTROL_RINGING:
00896 if (ast_channel_state(c) == AST_STATE_RING || ast_channel_state(c) == AST_STATE_RINGING) {
00897 h323_send_alerting(token);
00898 res = (got_progress ? 0 : -1);
00899 }
00900 break;
00901 case AST_CONTROL_PROGRESS:
00902 if (ast_channel_state(c) != AST_STATE_UP) {
00903
00904 if (!got_progress)
00905 h323_send_progress(token);
00906 res = 0;
00907 }
00908 break;
00909 case AST_CONTROL_BUSY:
00910 if (ast_channel_state(c) != AST_STATE_UP) {
00911 h323_answering_call(token, 1);
00912 ast_softhangup_nolock(c, AST_SOFTHANGUP_DEV);
00913 res = 0;
00914 }
00915 break;
00916 case AST_CONTROL_INCOMPLETE:
00917
00918
00919
00920 case AST_CONTROL_CONGESTION:
00921 if (ast_channel_state(c) != AST_STATE_UP) {
00922 h323_answering_call(token, 1);
00923 ast_softhangup_nolock(c, AST_SOFTHANGUP_DEV);
00924 res = 0;
00925 }
00926 break;
00927 case AST_CONTROL_HOLD:
00928 h323_hold_call(token, 1);
00929
00930 ast_moh_start(c, data, NULL);
00931 res = 0;
00932 break;
00933 case AST_CONTROL_UNHOLD:
00934 h323_hold_call(token, 0);
00935 ast_moh_stop(c);
00936 res = 0;
00937 break;
00938 case AST_CONTROL_SRCUPDATE:
00939 ast_rtp_instance_update_source(pvt->rtp);
00940 res = 0;
00941 break;
00942 case AST_CONTROL_SRCCHANGE:
00943 ast_rtp_instance_change_source(pvt->rtp);
00944 res = 0;
00945 break;
00946 case AST_CONTROL_PROCEEDING:
00947 case AST_CONTROL_PVT_CAUSE_CODE:
00948 case -1:
00949 break;
00950 default:
00951 ast_log(LOG_WARNING, "OH323: Don't know how to indicate condition %d on %s\n", condition, token);
00952 break;
00953 }
00954
00955 if (h323debug)
00956 ast_debug(1, "OH323: Indicated %d on %s, res=%d\n", condition, token, res);
00957 if (token)
00958 ast_free(token);
00959 oh323_update_info(c);
00960
00961 return res;
00962 }
00963
00964 static int oh323_fixup(struct ast_channel *oldchan, struct ast_channel *newchan)
00965 {
00966 struct oh323_pvt *pvt = (struct oh323_pvt *) ast_channel_tech_pvt(newchan);
00967
00968 ast_mutex_lock(&pvt->lock);
00969 if (pvt->owner != oldchan) {
00970 ast_log(LOG_WARNING, "old channel wasn't %p but was %p\n", oldchan, pvt->owner);
00971 return -1;
00972 }
00973 pvt->owner = newchan;
00974 ast_mutex_unlock(&pvt->lock);
00975 return 0;
00976 }
00977
00978 static int __oh323_rtp_create(struct oh323_pvt *pvt)
00979 {
00980 struct ast_sockaddr our_addr;
00981
00982 if (pvt->rtp)
00983 return 0;
00984
00985 {
00986 struct ast_sockaddr tmp;
00987
00988 ast_sockaddr_from_sin(&tmp, &bindaddr);
00989 if (ast_find_ourip(&our_addr, &tmp, AF_INET)) {
00990 ast_mutex_unlock(&pvt->lock);
00991 ast_log(LOG_ERROR, "Unable to locate local IP address for RTP stream\n");
00992 return -1;
00993 }
00994 }
00995 our_addr.ss.ss_family = AF_INET;
00996 pvt->rtp = ast_rtp_instance_new("asterisk", sched, &our_addr, NULL);
00997 if (!pvt->rtp) {
00998 ast_mutex_unlock(&pvt->lock);
00999 ast_log(LOG_WARNING, "Unable to create RTP session: %s\n", strerror(errno));
01000 return -1;
01001 }
01002 if (h323debug)
01003 ast_debug(1, "Created RTP channel\n");
01004
01005 ast_rtp_instance_set_qos(pvt->rtp, tos, cos, "H323 RTP");
01006
01007 if (h323debug)
01008 ast_debug(1, "Setting NAT on RTP to %d\n", pvt->options.nat);
01009 ast_rtp_instance_set_prop(pvt->rtp, AST_RTP_PROPERTY_NAT, pvt->options.nat);
01010
01011 if (pvt->dtmf_pt[0] > 0)
01012 ast_rtp_codecs_payloads_set_rtpmap_type(ast_rtp_instance_get_codecs(pvt->rtp), pvt->rtp, pvt->dtmf_pt[0], "audio", "telephone-event", 0);
01013 if (pvt->dtmf_pt[1] > 0)
01014 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);
01015
01016 if (pvt->peercapability)
01017 ast_rtp_codecs_packetization_set(ast_rtp_instance_get_codecs(pvt->rtp), pvt->rtp, &pvt->peer_prefs);
01018
01019 if (pvt->owner && !ast_channel_trylock(pvt->owner)) {
01020 ast_jb_configure(pvt->owner, &global_jbconf);
01021 ast_channel_set_fd(pvt->owner, 0, ast_rtp_instance_fd(pvt->rtp, 0));
01022 ast_channel_set_fd(pvt->owner, 1, ast_rtp_instance_fd(pvt->rtp, 1));
01023 ast_queue_frame(pvt->owner, &ast_null_frame);
01024 ast_channel_unlock(pvt->owner);
01025 } else
01026 pvt->update_rtp_info = 1;
01027
01028 return 0;
01029 }
01030
01031
01032 static struct ast_channel *__oh323_new(struct oh323_pvt *pvt, int state, const char *host, const char *linkedid)
01033 {
01034 struct ast_channel *ch;
01035 char *cid_num, *cid_name;
01036 h323_format fmt;
01037 struct ast_format tmpfmt;
01038
01039 if (!ast_strlen_zero(pvt->options.cid_num))
01040 cid_num = pvt->options.cid_num;
01041 else
01042 cid_num = pvt->cd.call_source_e164;
01043
01044 if (!ast_strlen_zero(pvt->options.cid_name))
01045 cid_name = pvt->options.cid_name;
01046 else
01047 cid_name = pvt->cd.call_source_name;
01048
01049
01050 ast_mutex_unlock(&pvt->lock);
01051 ch = ast_channel_alloc(1, state, cid_num, cid_name, pvt->accountcode, pvt->exten, pvt->context, linkedid, pvt->amaflags, "H323/%s", host);
01052
01053 ast_module_ref(ast_module_info->self);
01054 ast_mutex_lock(&pvt->lock);
01055 if (ch) {
01056 ast_channel_tech_set(ch, &oh323_tech);
01057 if (!(fmt = pvt->jointcapability) && !(fmt = pvt->options.capability))
01058 fmt = global_options.capability;
01059
01060 ast_format_cap_from_old_bitfield(ast_channel_nativeformats(ch), fmt);
01061 ast_codec_choose(&pvt->options.prefs, ast_channel_nativeformats(ch), 1, &tmpfmt);
01062
01063 ast_format_cap_set(ast_channel_nativeformats(ch), &tmpfmt);
01064
01065 pvt->nativeformats = ast_format_cap_to_old_bitfield(ast_channel_nativeformats(ch));
01066 ast_best_codec(ast_channel_nativeformats(ch), &tmpfmt);
01067 ast_format_copy(ast_channel_writeformat(ch), &tmpfmt);
01068 ast_format_copy(ast_channel_rawwriteformat(ch), &tmpfmt);
01069 ast_format_copy(ast_channel_readformat(ch), &tmpfmt);
01070 ast_format_copy(ast_channel_rawreadformat(ch), &tmpfmt);
01071 if (!pvt->rtp)
01072 __oh323_rtp_create(pvt);
01073 #if 0
01074 ast_channel_set_fd(ch, 0, ast_rtp_instance_fd(pvt->rtp, 0));
01075 ast_channel_set_fd(ch, 1, ast_rtp_instance_fd(pvt->rtp, 1));
01076 #endif
01077 #ifdef VIDEO_SUPPORT
01078 if (pvt->vrtp) {
01079 ast_channel_set_fd(ch, 2, ast_rtp_instance_fd(pvt->vrtp, 0));
01080 ast_channel_set_fd(ch, 3, ast_rtp_instance_fd(pvt->vrtp, 1));
01081 }
01082 #endif
01083 #ifdef T38_SUPPORT
01084 if (pvt->udptl) {
01085 ast_channel_set_fd(ch, 4, ast_udptl_fd(pvt->udptl));
01086 }
01087 #endif
01088 if (state == AST_STATE_RING) {
01089 ast_channel_rings_set(ch, 1);
01090 }
01091
01092 if (pvt->options.dtmfmode & H323_DTMF_INBAND) {
01093 pvt->vad = ast_dsp_new();
01094 ast_dsp_set_features(pvt->vad, DSP_FEATURE_DIGIT_DETECT);
01095 }
01096
01097 ast_channel_tech_pvt_set(ch, pvt);
01098
01099 pvt->owner = ch;
01100
01101 ast_channel_context_set(ch, pvt->context);
01102 ast_channel_exten_set(ch, pvt->exten);
01103 ast_channel_priority_set(ch, 1);
01104 if (!ast_strlen_zero(pvt->accountcode)) {
01105 ast_channel_accountcode_set(ch, pvt->accountcode);
01106 }
01107 if (pvt->amaflags) {
01108 ast_channel_amaflags_set(ch, pvt->amaflags);
01109 }
01110
01111
01112
01113 if (!ast_strlen_zero(cid_num)) {
01114 ast_channel_caller(ch)->ani.number.valid = 1;
01115 ast_channel_caller(ch)->ani.number.str = ast_strdup(cid_num);
01116 }
01117
01118 if (pvt->cd.redirect_reason >= 0) {
01119 ast_channel_redirecting(ch)->from.number.valid = 1;
01120 ast_channel_redirecting(ch)->from.number.str = ast_strdup(pvt->cd.redirect_number);
01121 pbx_builtin_setvar_helper(ch, "PRIREDIRECTREASON", redirectingreason2str(pvt->cd.redirect_reason));
01122 }
01123 ast_channel_caller(ch)->id.name.presentation = pvt->cd.presentation;
01124 ast_channel_caller(ch)->id.number.presentation = pvt->cd.presentation;
01125 ast_channel_caller(ch)->id.number.plan = pvt->cd.type_of_number;
01126
01127 if (!ast_strlen_zero(pvt->exten) && strcmp(pvt->exten, "s")) {
01128 ast_channel_dialed(ch)->number.str = ast_strdup(pvt->exten);
01129 }
01130 if (pvt->cd.transfer_capability >= 0)
01131 ast_channel_transfercapability_set(ch, pvt->cd.transfer_capability);
01132 if (state != AST_STATE_DOWN) {
01133 if (ast_pbx_start(ch)) {
01134 ast_log(LOG_WARNING, "Unable to start PBX on %s\n", ast_channel_name(ch));
01135 ast_hangup(ch);
01136 ch = NULL;
01137 }
01138 }
01139 } else {
01140 ast_log(LOG_WARNING, "Unable to allocate channel structure\n");
01141 }
01142 return ch;
01143 }
01144
01145 static struct oh323_pvt *oh323_alloc(int callid)
01146 {
01147 struct oh323_pvt *pvt;
01148
01149 pvt = ast_calloc(1, sizeof(*pvt));
01150 if (!pvt) {
01151 ast_log(LOG_ERROR, "Couldn't allocate private structure. This is bad\n");
01152 return NULL;
01153 }
01154 pvt->cd.redirect_reason = -1;
01155 pvt->cd.transfer_capability = -1;
01156
01157 if (!callid) {
01158 if ((pvt->cd).call_token == NULL) {
01159 (pvt->cd).call_token = ast_calloc(1, 128);
01160 }
01161 if (!pvt->cd.call_token) {
01162 ast_log(LOG_ERROR, "Not enough memory to alocate call token\n");
01163 ast_rtp_instance_destroy(pvt->rtp);
01164 ast_free(pvt);
01165 return NULL;
01166 }
01167 memset((char *)(pvt->cd).call_token, 0, 128);
01168 pvt->cd.call_reference = callid;
01169 }
01170 memcpy(&pvt->options, &global_options, sizeof(pvt->options));
01171 pvt->jointcapability = pvt->options.capability;
01172 if (pvt->options.dtmfmode & (H323_DTMF_RFC2833 | H323_DTMF_CISCO)) {
01173 pvt->nonCodecCapability |= AST_RTP_DTMF;
01174 } else {
01175 pvt->nonCodecCapability &= ~AST_RTP_DTMF;
01176 }
01177 ast_copy_string(pvt->context, default_context, sizeof(pvt->context));
01178 pvt->newstate = pvt->newcontrol = pvt->newdigit = pvt->update_rtp_info = pvt->DTMFsched = -1;
01179 ast_mutex_init(&pvt->lock);
01180
01181 ast_mutex_lock(&iflock);
01182 pvt->next = iflist;
01183 iflist = pvt;
01184 ast_mutex_unlock(&iflock);
01185 return pvt;
01186 }
01187
01188 static struct oh323_pvt *find_call_locked(int call_reference, const char *token)
01189 {
01190 struct oh323_pvt *pvt;
01191
01192 ast_mutex_lock(&iflock);
01193 pvt = iflist;
01194 while(pvt) {
01195 if (!pvt->needdestroy && ((signed int)pvt->cd.call_reference == call_reference)) {
01196
01197 if ((token != NULL) && (pvt->cd.call_token != NULL) && (!strcmp(pvt->cd.call_token, token))) {
01198 ast_mutex_lock(&pvt->lock);
01199 ast_mutex_unlock(&iflock);
01200 return pvt;
01201 } else if (token == NULL) {
01202 ast_log(LOG_WARNING, "Call Token is NULL\n");
01203 ast_mutex_lock(&pvt->lock);
01204 ast_mutex_unlock(&iflock);
01205 return pvt;
01206 }
01207 }
01208 pvt = pvt->next;
01209 }
01210 ast_mutex_unlock(&iflock);
01211 return NULL;
01212 }
01213
01214 static int update_state(struct oh323_pvt *pvt, int state, int signal)
01215 {
01216 if (!pvt)
01217 return 0;
01218 if (pvt->owner && !ast_channel_trylock(pvt->owner)) {
01219 if (state >= 0)
01220 ast_setstate(pvt->owner, state);
01221 if (signal >= 0)
01222 ast_queue_control(pvt->owner, signal);
01223 ast_channel_unlock(pvt->owner);
01224 return 1;
01225 }
01226 else {
01227 if (state >= 0)
01228 pvt->newstate = state;
01229 if (signal >= 0)
01230 pvt->newcontrol = signal;
01231 return 0;
01232 }
01233 }
01234
01235 static struct oh323_alias *build_alias(const char *name, struct ast_variable *v, struct ast_variable *alt, int realtime)
01236 {
01237 struct oh323_alias *alias;
01238 int found = 0;
01239
01240 alias = ASTOBJ_CONTAINER_FIND_UNLINK_FULL(&aliasl, name, name, 0, 0, strcasecmp);
01241
01242 if (alias)
01243 found++;
01244 else {
01245 if (!(alias = ast_calloc(1, sizeof(*alias))))
01246 return NULL;
01247 ASTOBJ_INIT(alias);
01248 }
01249 if (!found && name)
01250 ast_copy_string(alias->name, name, sizeof(alias->name));
01251 for (; v || ((v = alt) && !(alt = NULL)); v = v->next) {
01252 if (!strcasecmp(v->name, "e164")) {
01253 ast_copy_string(alias->e164, v->value, sizeof(alias->e164));
01254 } else if (!strcasecmp(v->name, "prefix")) {
01255 ast_copy_string(alias->prefix, v->value, sizeof(alias->prefix));
01256 } else if (!strcasecmp(v->name, "context")) {
01257 ast_copy_string(alias->context, v->value, sizeof(alias->context));
01258 } else if (!strcasecmp(v->name, "secret")) {
01259 ast_copy_string(alias->secret, v->value, sizeof(alias->secret));
01260 } else {
01261 if (strcasecmp(v->value, "h323")) {
01262 ast_log(LOG_WARNING, "Keyword %s does not make sense in type=h323\n", v->name);
01263 }
01264 }
01265 }
01266 ASTOBJ_UNMARK(alias);
01267 return alias;
01268 }
01269
01270 static struct oh323_alias *realtime_alias(const char *alias)
01271 {
01272 struct ast_variable *var, *tmp;
01273 struct oh323_alias *a;
01274
01275 var = ast_load_realtime("h323", "name", alias, SENTINEL);
01276
01277 if (!var)
01278 return NULL;
01279
01280 for (tmp = var; tmp; tmp = tmp->next) {
01281 if (!strcasecmp(tmp->name, "type") &&
01282 !(!strcasecmp(tmp->value, "alias") || !strcasecmp(tmp->value, "h323"))) {
01283 ast_variables_destroy(var);
01284 return NULL;
01285 }
01286 }
01287
01288 a = build_alias(alias, var, NULL, 1);
01289
01290 ast_variables_destroy(var);
01291
01292 return a;
01293 }
01294
01295 static int h323_parse_allow_disallow(struct ast_codec_pref *pref, h323_format *formats, const char *list, int allowing)
01296 {
01297 int res;
01298 struct ast_format_cap *cap = ast_format_cap_alloc_nolock();
01299 if (!cap) {
01300 return 1;
01301 }
01302
01303 ast_format_cap_from_old_bitfield(cap, *formats);
01304 res = ast_parse_allow_disallow(pref, cap, list, allowing);
01305 *formats = ast_format_cap_to_old_bitfield(cap);
01306 cap = ast_format_cap_destroy(cap);
01307 return res;
01308
01309 }
01310
01311 static int update_common_options(struct ast_variable *v, struct call_options *options)
01312 {
01313 int tmp = 0;
01314 char *val, *opt;
01315
01316 if (!strcasecmp(v->name, "allow")) {
01317 h323_parse_allow_disallow(&options->prefs, &options->capability, v->value, 1);
01318 } else if (!strcasecmp(v->name, "autoframing")) {
01319 options->autoframing = ast_true(v->value);
01320 } else if (!strcasecmp(v->name, "disallow")) {
01321 h323_parse_allow_disallow(&options->prefs, &options->capability, v->value, 0);
01322 } else if (!strcasecmp(v->name, "dtmfmode")) {
01323 val = ast_strdupa(v->value);
01324 if ((opt = strchr(val, ':')) != (char *)NULL) {
01325 *opt++ = '\0';
01326 tmp = atoi(opt);
01327 }
01328 if (!strcasecmp(v->value, "inband")) {
01329 options->dtmfmode |= H323_DTMF_INBAND;
01330 } else if (!strcasecmp(val, "rfc2833")) {
01331 options->dtmfmode |= H323_DTMF_RFC2833;
01332 if (!opt) {
01333 options->dtmfcodec[0] = H323_DTMF_RFC2833_PT;
01334 } else if ((tmp >= 96) && (tmp < 128)) {
01335 options->dtmfcodec[0] = tmp;
01336 } else {
01337 options->dtmfcodec[0] = H323_DTMF_RFC2833_PT;
01338 ast_log(LOG_WARNING, "Unknown rfc2833 payload %s specified at line %d, using default %d\n", opt, v->lineno, options->dtmfcodec[0]);
01339 }
01340 } else if (!strcasecmp(val, "cisco")) {
01341 options->dtmfmode |= H323_DTMF_CISCO;
01342 if (!opt) {
01343 options->dtmfcodec[1] = H323_DTMF_CISCO_PT;
01344 } else if ((tmp >= 96) && (tmp < 128)) {
01345 options->dtmfcodec[1] = tmp;
01346 } else {
01347 options->dtmfcodec[1] = H323_DTMF_CISCO_PT;
01348 ast_log(LOG_WARNING, "Unknown Cisco DTMF payload %s specified at line %d, using default %d\n", opt, v->lineno, options->dtmfcodec[1]);
01349 }
01350 } else if (!strcasecmp(v->value, "h245-signal")) {
01351 options->dtmfmode |= H323_DTMF_SIGNAL;
01352 } else {
01353 ast_log(LOG_WARNING, "Unknown dtmf mode '%s' at line %d\n", v->value, v->lineno);
01354 }
01355 } else if (!strcasecmp(v->name, "dtmfcodec")) {
01356 ast_log(LOG_NOTICE, "Option %s at line %d is deprecated. Use dtmfmode=rfc2833[:<payload>] instead.\n", v->name, v->lineno);
01357 tmp = atoi(v->value);
01358 if (tmp < 96)
01359 ast_log(LOG_WARNING, "Invalid %s value %s at line %d\n", v->name, v->value, v->lineno);
01360 else
01361 options->dtmfcodec[0] = tmp;
01362 } else if (!strcasecmp(v->name, "bridge")) {
01363 options->bridge = ast_true(v->value);
01364 } else if (!strcasecmp(v->name, "nat")) {
01365 options->nat = ast_true(v->value);
01366 } else if (!strcasecmp(v->name, "fastStart")) {
01367 options->fastStart = ast_true(v->value);
01368 } else if (!strcasecmp(v->name, "h245Tunneling")) {
01369 options->h245Tunneling = ast_true(v->value);
01370 } else if (!strcasecmp(v->name, "silenceSuppression")) {
01371 options->silenceSuppression = ast_true(v->value);
01372 } else if (!strcasecmp(v->name, "progress_setup")) {
01373 tmp = atoi(v->value);
01374 if ((tmp != 0) && (tmp != 1) && (tmp != 3) && (tmp != 8)) {
01375 ast_log(LOG_WARNING, "Invalid value %s for %s at line %d, assuming 0\n", v->value, v->name, v->lineno);
01376 tmp = 0;
01377 }
01378 options->progress_setup = tmp;
01379 } else if (!strcasecmp(v->name, "progress_alert")) {
01380 tmp = atoi(v->value);
01381 if ((tmp != 0) && (tmp != 1) && (tmp != 8)) {
01382 ast_log(LOG_WARNING, "Invalid value %s for %s at line %d, assuming 0\n", v->value, v->name, v->lineno);
01383 tmp = 0;
01384 }
01385 options->progress_alert = tmp;
01386 } else if (!strcasecmp(v->name, "progress_audio")) {
01387 options->progress_audio = ast_true(v->value);
01388 } else if (!strcasecmp(v->name, "callerid")) {
01389 ast_callerid_split(v->value, options->cid_name, sizeof(options->cid_name), options->cid_num, sizeof(options->cid_num));
01390 } else if (!strcasecmp(v->name, "fullname")) {
01391 ast_copy_string(options->cid_name, v->value, sizeof(options->cid_name));
01392 } else if (!strcasecmp(v->name, "cid_number")) {
01393 ast_copy_string(options->cid_num, v->value, sizeof(options->cid_num));
01394 } else if (!strcasecmp(v->name, "tunneling")) {
01395 if (!strcasecmp(v->value, "none"))
01396 options->tunnelOptions = 0;
01397 else if (!strcasecmp(v->value, "cisco"))
01398 options->tunnelOptions |= H323_TUNNEL_CISCO;
01399 else if (!strcasecmp(v->value, "qsig"))
01400 options->tunnelOptions |= H323_TUNNEL_QSIG;
01401 else
01402 ast_log(LOG_WARNING, "Invalid value %s for %s at line %d\n", v->value, v->name, v->lineno);
01403 } else if (!strcasecmp(v->name, "hold")) {
01404 if (!strcasecmp(v->value, "none"))
01405 options->holdHandling = ~0;
01406 else if (!strcasecmp(v->value, "notify"))
01407 options->holdHandling |= H323_HOLD_NOTIFY;
01408 else if (!strcasecmp(v->value, "q931only"))
01409 options->holdHandling |= H323_HOLD_NOTIFY | H323_HOLD_Q931ONLY;
01410 else if (!strcasecmp(v->value, "h450"))
01411 options->holdHandling |= H323_HOLD_H450;
01412 else
01413 ast_log(LOG_WARNING, "Invalid value %s for %s at line %d\n", v->value, v->name, v->lineno);
01414 } else
01415 return 1;
01416
01417 return 0;
01418 }
01419
01420 static struct oh323_user *build_user(const char *name, struct ast_variable *v, struct ast_variable *alt, int realtime)
01421 {
01422 struct oh323_user *user;
01423 struct ast_ha *oldha;
01424 int found = 0;
01425 int format;
01426
01427 user = ASTOBJ_CONTAINER_FIND_UNLINK_FULL(&userl, name, name, 0, 0, strcmp);
01428
01429 if (user)
01430 found++;
01431 else {
01432 if (!(user = ast_calloc(1, sizeof(*user))))
01433 return NULL;
01434 ASTOBJ_INIT(user);
01435 }
01436 oldha = user->ha;
01437 user->ha = (struct ast_ha *)NULL;
01438 memcpy(&user->options, &global_options, sizeof(user->options));
01439 user->options.dtmfmode = 0;
01440 user->options.holdHandling = 0;
01441
01442 ast_copy_string(user->context, default_context, sizeof(user->context));
01443 if (!found) {
01444 ast_copy_string(user->name, name, sizeof(user->name));
01445 }
01446
01447 #if 0
01448 if (user->chanvars) {
01449 ast_variables_destroy(user->chanvars);
01450 user->chanvars = NULL;
01451 }
01452 #endif
01453
01454 for (; v || ((v = alt) && !(alt = NULL)); v = v->next) {
01455 if (!update_common_options(v, &user->options))
01456 continue;
01457 if (!strcasecmp(v->name, "context")) {
01458 ast_copy_string(user->context, v->value, sizeof(user->context));
01459 } else if (!strcasecmp(v->name, "secret")) {
01460 ast_copy_string(user->secret, v->value, sizeof(user->secret));
01461 } else if (!strcasecmp(v->name, "accountcode")) {
01462 ast_copy_string(user->accountcode, v->value, sizeof(user->accountcode));
01463 } else if (!strcasecmp(v->name, "host")) {
01464 if (!strcasecmp(v->value, "dynamic")) {
01465 ast_log(LOG_ERROR, "A dynamic host on a type=user does not make any sense\n");
01466 ASTOBJ_UNREF(user, oh323_destroy_user);
01467 return NULL;
01468 } else {
01469 struct ast_sockaddr tmp;
01470
01471 tmp.ss.ss_family = AF_INET;
01472 if (ast_get_ip(&tmp, v->value)) {
01473 ASTOBJ_UNREF(user, oh323_destroy_user);
01474 return NULL;
01475 }
01476 ast_sockaddr_to_sin(&tmp, &user->addr);
01477 }
01478
01479 user->host = 1;
01480 } else if (!strcasecmp(v->name, "amaflags")) {
01481 format = ast_cdr_amaflags2int(v->value);
01482 if (format < 0) {
01483 ast_log(LOG_WARNING, "Invalid AMA Flags: %s at line %d\n", v->value, v->lineno);
01484 } else {
01485 user->amaflags = format;
01486 }
01487 } else if (!strcasecmp(v->name, "permit") ||
01488 !strcasecmp(v->name, "deny")) {
01489 int ha_error = 0;
01490
01491 user->ha = ast_append_ha(v->name, v->value, user->ha, &ha_error);
01492 if (ha_error)
01493 ast_log(LOG_ERROR, "Bad ACL entry in configuration line %d : %s\n", v->lineno, v->value);
01494 }
01495 }
01496 if (!user->options.dtmfmode)
01497 user->options.dtmfmode = global_options.dtmfmode;
01498 if (user->options.holdHandling == ~0)
01499 user->options.holdHandling = 0;
01500 else if (!user->options.holdHandling)
01501 user->options.holdHandling = global_options.holdHandling;
01502 ASTOBJ_UNMARK(user);
01503 ast_free_ha(oldha);
01504 return user;
01505 }
01506
01507 static struct oh323_user *realtime_user(const call_details_t *cd)
01508 {
01509 struct ast_variable *var, *tmp;
01510 struct oh323_user *user;
01511 const char *username;
01512
01513 if (userbyalias)
01514 var = ast_load_realtime("h323", "name", username = cd->call_source_aliases, SENTINEL);
01515 else {
01516 username = (char *)NULL;
01517 var = ast_load_realtime("h323", "host", cd->sourceIp, SENTINEL);
01518 }
01519
01520 if (!var)
01521 return NULL;
01522
01523 for (tmp = var; tmp; tmp = tmp->next) {
01524 if (!strcasecmp(tmp->name, "type") &&
01525 !(!strcasecmp(tmp->value, "user") || !strcasecmp(tmp->value, "friend"))) {
01526 ast_variables_destroy(var);
01527 return NULL;
01528 } else if (!username && !strcasecmp(tmp->name, "name"))
01529 username = tmp->value;
01530 }
01531
01532 if (!username) {
01533 ast_log(LOG_WARNING, "Cannot determine user name for IP address %s\n", cd->sourceIp);
01534 ast_variables_destroy(var);
01535 return NULL;
01536 }
01537
01538 user = build_user(username, var, NULL, 1);
01539
01540 ast_variables_destroy(var);
01541
01542 return user;
01543 }
01544
01545 static struct oh323_peer *build_peer(const char *name, struct ast_variable *v, struct ast_variable *alt, int realtime)
01546 {
01547 struct oh323_peer *peer;
01548 struct ast_ha *oldha;
01549 int found = 0;
01550
01551 peer = ASTOBJ_CONTAINER_FIND_UNLINK_FULL(&peerl, name, name, 0, 0, strcmp);
01552
01553 if (peer)
01554 found++;
01555 else {
01556 if (!(peer = ast_calloc(1, sizeof(*peer))))
01557 return NULL;
01558 ASTOBJ_INIT(peer);
01559 }
01560 oldha = peer->ha;
01561 peer->ha = NULL;
01562 memcpy(&peer->options, &global_options, sizeof(peer->options));
01563 peer->options.dtmfmode = 0;
01564 peer->options.holdHandling = 0;
01565 peer->addr.sin_port = htons(h323_signalling_port);
01566 peer->addr.sin_family = AF_INET;
01567 if (!found && name)
01568 ast_copy_string(peer->name, name, sizeof(peer->name));
01569
01570 #if 0
01571 if (peer->chanvars) {
01572 ast_variables_destroy(peer->chanvars);
01573 peer->chanvars = NULL;
01574 }
01575 #endif
01576
01577 peer->mailbox[0] = '\0';
01578
01579 for (; v || ((v = alt) && !(alt = NULL)); v = v->next) {
01580 if (!update_common_options(v, &peer->options))
01581 continue;
01582 if (!strcasecmp(v->name, "host")) {
01583 if (!strcasecmp(v->value, "dynamic")) {
01584 ast_log(LOG_ERROR, "Dynamic host configuration not implemented.\n");
01585 ASTOBJ_UNREF(peer, oh323_destroy_peer);
01586 return NULL;
01587 }
01588 {
01589 struct ast_sockaddr tmp;
01590
01591 tmp.ss.ss_family = AF_INET;
01592 if (ast_get_ip(&tmp, v->value)) {
01593 ast_log(LOG_ERROR, "Could not determine IP for %s\n", v->value);
01594 ASTOBJ_UNREF(peer, oh323_destroy_peer);
01595 return NULL;
01596 }
01597 ast_sockaddr_to_sin(&tmp, &peer->addr);
01598 }
01599 } else if (!strcasecmp(v->name, "port")) {
01600 peer->addr.sin_port = htons(atoi(v->value));
01601 } else if (!strcasecmp(v->name, "permit") ||
01602 !strcasecmp(v->name, "deny")) {
01603 int ha_error = 0;
01604
01605 peer->ha = ast_append_ha(v->name, v->value, peer->ha, &ha_error);
01606 if (ha_error)
01607 ast_log(LOG_ERROR, "Bad ACL entry in configuration line %d : %s\n", v->lineno, v->value);
01608 } else if (!strcasecmp(v->name, "mailbox")) {
01609 ast_copy_string(peer->mailbox, v->value, sizeof(peer->mailbox));
01610 } else if (!strcasecmp(v->name, "hasvoicemail")) {
01611 if (ast_true(v->value) && ast_strlen_zero(peer->mailbox)) {
01612 ast_copy_string(peer->mailbox, name, sizeof(peer->mailbox));
01613 }
01614 }
01615 }
01616 if (!peer->options.dtmfmode)
01617 peer->options.dtmfmode = global_options.dtmfmode;
01618 if (peer->options.holdHandling == ~0)
01619 peer->options.holdHandling = 0;
01620 else if (!peer->options.holdHandling)
01621 peer->options.holdHandling = global_options.holdHandling;
01622 ASTOBJ_UNMARK(peer);
01623 ast_free_ha(oldha);
01624 return peer;
01625 }
01626
01627 static struct oh323_peer *realtime_peer(const char *peername, struct sockaddr_in *sin)
01628 {
01629 struct oh323_peer *peer;
01630 struct ast_variable *var;
01631 struct ast_variable *tmp;
01632 const char *addr = NULL;
01633
01634
01635 if (peername)
01636 var = ast_load_realtime("h323", "name", peername, SENTINEL);
01637 else if (sin)
01638 var = ast_load_realtime("h323", "host", addr = ast_inet_ntoa(sin->sin_addr), SENTINEL);
01639 else
01640 return NULL;
01641
01642 if (!var)
01643 return NULL;
01644
01645 for (tmp = var; tmp; tmp = tmp->next) {
01646
01647 if (!strcasecmp(tmp->name, "type") &&
01648 !(!strcasecmp(tmp->value, "peer") || !strcasecmp(tmp->value, "friend"))) {
01649 ast_variables_destroy(var);
01650 return NULL;
01651 } else if (!peername && !strcasecmp(tmp->name, "name")) {
01652 peername = tmp->value;
01653 }
01654 }
01655
01656 if (!peername) {
01657 ast_log(LOG_WARNING, "Cannot determine peer name for IP address %s\n", addr);
01658 ast_variables_destroy(var);
01659 return NULL;
01660 }
01661
01662
01663 peer = build_peer(peername, var, NULL, 1);
01664
01665 ast_variables_destroy(var);
01666
01667 return peer;
01668 }
01669
01670 static int oh323_addrcmp_str(struct in_addr inaddr, char *addr)
01671 {
01672 return strcmp(ast_inet_ntoa(inaddr), addr);
01673 }
01674
01675 static struct oh323_user *find_user(const call_details_t *cd, int realtime)
01676 {
01677 struct oh323_user *u;
01678
01679 if (userbyalias)
01680 u = ASTOBJ_CONTAINER_FIND(&userl, cd->call_source_aliases);
01681 else
01682 u = ASTOBJ_CONTAINER_FIND_FULL(&userl, cd->sourceIp, addr.sin_addr, 0, 0, oh323_addrcmp_str);
01683
01684 if (!u && realtime)
01685 u = realtime_user(cd);
01686
01687 if (!u && h323debug)
01688 ast_debug(1, "Could not find user by name %s or address %s\n", cd->call_source_aliases, cd->sourceIp);
01689
01690 return u;
01691 }
01692
01693 static int oh323_addrcmp(struct sockaddr_in addr, struct sockaddr_in *sin)
01694 {
01695 int res;
01696
01697 if (!sin)
01698 res = -1;
01699 else
01700 res = inaddrcmp(&addr , sin);
01701
01702 return res;
01703 }
01704
01705 static struct oh323_peer *find_peer(const char *peer, struct sockaddr_in *sin, int realtime)
01706 {
01707 struct oh323_peer *p;
01708
01709 if (peer)
01710 p = ASTOBJ_CONTAINER_FIND(&peerl, peer);
01711 else
01712 p = ASTOBJ_CONTAINER_FIND_FULL(&peerl, sin, addr, 0, 0, oh323_addrcmp);
01713
01714 if (!p && realtime)
01715 p = realtime_peer(peer, sin);
01716
01717 if (!p && h323debug)
01718 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>"));
01719
01720 return p;
01721 }
01722
01723 static int create_addr(struct oh323_pvt *pvt, char *opeer)
01724 {
01725 struct hostent *hp;
01726 struct ast_hostent ahp;
01727 struct oh323_peer *p;
01728 int portno;
01729 int found = 0;
01730 char *port;
01731 char *hostn;
01732 char peer[256] = "";
01733
01734 ast_copy_string(peer, opeer, sizeof(peer));
01735 port = strchr(peer, ':');
01736 if (port) {
01737 *port = '\0';
01738 port++;
01739 }
01740 pvt->sa.sin_family = AF_INET;
01741 p = find_peer(peer, NULL, 1);
01742 if (p) {
01743 found++;
01744 memcpy(&pvt->options, &p->options, sizeof(pvt->options));
01745 pvt->jointcapability = pvt->options.capability;
01746 if (pvt->options.dtmfmode) {
01747 if (pvt->options.dtmfmode & H323_DTMF_RFC2833) {
01748 pvt->nonCodecCapability |= AST_RTP_DTMF;
01749 } else {
01750 pvt->nonCodecCapability &= ~AST_RTP_DTMF;
01751 }
01752 }
01753 if (p->addr.sin_addr.s_addr) {
01754 pvt->sa.sin_addr = p->addr.sin_addr;
01755 pvt->sa.sin_port = p->addr.sin_port;
01756 }
01757 ASTOBJ_UNREF(p, oh323_destroy_peer);
01758 }
01759 if (!p && !found) {
01760 hostn = peer;
01761 if (port) {
01762 portno = atoi(port);
01763 } else {
01764 portno = h323_signalling_port;
01765 }
01766 hp = ast_gethostbyname(hostn, &ahp);
01767 if (hp) {
01768 memcpy(&pvt->sa.sin_addr, hp->h_addr, sizeof(pvt->sa.sin_addr));
01769 pvt->sa.sin_port = htons(portno);
01770
01771 p = find_peer(NULL, &pvt->sa, 1);
01772 memcpy(&pvt->options, (p ? &p->options : &global_options), sizeof(pvt->options));
01773 pvt->jointcapability = pvt->options.capability;
01774 if (p) {
01775 ASTOBJ_UNREF(p, oh323_destroy_peer);
01776 }
01777 if (pvt->options.dtmfmode) {
01778 if (pvt->options.dtmfmode & H323_DTMF_RFC2833) {
01779 pvt->nonCodecCapability |= AST_RTP_DTMF;
01780 } else {
01781 pvt->nonCodecCapability &= ~AST_RTP_DTMF;
01782 }
01783 }
01784 return 0;
01785 } else {
01786 ast_log(LOG_WARNING, "No such host: %s\n", peer);
01787 return -1;
01788 }
01789 } else if (!found) {
01790 return -1;
01791 } else {
01792 return 0;
01793 }
01794 }
01795 static struct ast_channel *oh323_request(const char *type, struct ast_format_cap *cap, const struct ast_channel *requestor, const char *dest, int *cause)
01796 {
01797 struct oh323_pvt *pvt;
01798 struct ast_channel *tmpc = NULL;
01799 char *ext, *host;
01800 char *h323id = NULL;
01801 char tmp[256], tmp1[256];
01802
01803 if (h323debug)
01804 ast_debug(1, "type=%s, format=%s, data=%s.\n", type, ast_getformatname_multiple(tmp, sizeof(tmp), cap), dest);
01805
01806 pvt = oh323_alloc(0);
01807 if (!pvt) {
01808 ast_log(LOG_WARNING, "Unable to build pvt data for '%s'\n", dest);
01809 return NULL;
01810 }
01811 if (!(ast_format_cap_has_type(cap, AST_FORMAT_TYPE_AUDIO))) {
01812 ast_log(LOG_NOTICE, "Asked to get a channel of unsupported format '%s'\n", ast_getformatname_multiple(tmp, sizeof(tmp), cap));
01813 oh323_destroy(pvt);
01814 if (cause)
01815 *cause = AST_CAUSE_INCOMPATIBLE_DESTINATION;
01816 return NULL;
01817 }
01818 ast_copy_string(tmp, dest, sizeof(tmp));
01819 host = strchr(tmp, '@');
01820 if (host) {
01821 *host = '\0';
01822 host++;
01823 ext = tmp;
01824 } else {
01825 ext = strrchr(tmp, '/');
01826 if (ext)
01827 *ext++ = '\0';
01828 host = tmp;
01829 }
01830 strtok_r(host, "/", &(h323id));
01831 if (!ast_strlen_zero(h323id)) {
01832 h323_set_id(h323id);
01833 }
01834 if (ext) {
01835 ast_copy_string(pvt->exten, ext, sizeof(pvt->exten));
01836 }
01837 if (h323debug)
01838 ast_debug(1, "Extension: %s Host: %s\n", pvt->exten, host);
01839
01840 if (gatekeeper_disable) {
01841 if (create_addr(pvt, host)) {
01842 oh323_destroy(pvt);
01843 if (cause)
01844 *cause = AST_CAUSE_DESTINATION_OUT_OF_ORDER;
01845 return NULL;
01846 }
01847 }
01848 else {
01849 memcpy(&pvt->options, &global_options, sizeof(pvt->options));
01850 pvt->jointcapability = pvt->options.capability;
01851 if (pvt->options.dtmfmode) {
01852 if (pvt->options.dtmfmode & H323_DTMF_RFC2833) {
01853 pvt->nonCodecCapability |= AST_RTP_DTMF;
01854 } else {
01855 pvt->nonCodecCapability &= ~AST_RTP_DTMF;
01856 }
01857 }
01858 }
01859
01860 ast_mutex_lock(&caplock);
01861
01862 snprintf(tmp1, sizeof(tmp1)-1, "%s-%u", host, ++unique);
01863 tmp1[sizeof(tmp1)-1] = '\0';
01864 ast_mutex_unlock(&caplock);
01865
01866 ast_mutex_lock(&pvt->lock);
01867 tmpc = __oh323_new(pvt, AST_STATE_DOWN, tmp1, requestor ? ast_channel_linkedid(requestor) : NULL);
01868 ast_mutex_unlock(&pvt->lock);
01869 if (!tmpc) {
01870 oh323_destroy(pvt);
01871 if (cause)
01872 *cause = AST_CAUSE_NORMAL_TEMPORARY_FAILURE;
01873 }
01874 ast_update_use_count();
01875 restart_monitor();
01876 return tmpc;
01877 }
01878
01879
01880 static struct oh323_alias *find_alias(const char *source_aliases, int realtime)
01881 {
01882 struct oh323_alias *a;
01883
01884 a = ASTOBJ_CONTAINER_FIND(&aliasl, source_aliases);
01885
01886 if (!a && realtime)
01887 a = realtime_alias(source_aliases);
01888
01889 return a;
01890 }
01891
01892
01893
01894
01895
01896 static int receive_digit(unsigned call_reference, char digit, const char *token, int duration)
01897 {
01898 struct oh323_pvt *pvt;
01899 int res;
01900
01901 pvt = find_call_locked(call_reference, token);
01902 if (!pvt) {
01903 ast_log(LOG_ERROR, "Received digit '%c' (%u ms) for call %s without private structure\n", digit, duration, token);
01904 return -1;
01905 }
01906 if (h323debug)
01907 ast_log(LOG_DTMF, "Received %s digit '%c' (%u ms) for call %s\n", (digit == ' ' ? "update for" : "new"), (digit == ' ' ? pvt->curDTMF : digit), duration, token);
01908
01909 if (pvt->owner && !ast_channel_trylock(pvt->owner)) {
01910 if (digit == '!')
01911 res = ast_queue_control(pvt->owner, AST_CONTROL_FLASH);
01912 else {
01913 struct ast_frame f = {
01914 .frametype = AST_FRAME_DTMF_END,
01915 .subclass.integer = digit,
01916 .samples = duration * 8,
01917 .len = duration,
01918 .src = "SEND_DIGIT",
01919 };
01920 if (digit == ' ') {
01921 f.subclass.integer = pvt->curDTMF;
01922 AST_SCHED_DEL(sched, pvt->DTMFsched);
01923 } else {
01924 if (pvt->DTMFsched >= 0) {
01925
01926 AST_SCHED_DEL(sched, pvt->DTMFsched);
01927 f.subclass.integer = pvt->curDTMF;
01928 f.samples = f.len = 0;
01929 ast_queue_frame(pvt->owner, &f);
01930
01931 f.subclass.integer = digit;
01932 f.samples = duration * 8;
01933 f.len = duration;
01934 }
01935 if (duration) {
01936 f.frametype = AST_FRAME_DTMF_BEGIN;
01937 pvt->DTMFsched = ast_sched_add(sched, duration, oh323_simulate_dtmf_end, pvt);
01938 if (h323debug)
01939 ast_log(LOG_DTMF, "Scheduled DTMF END simulation for %d ms, id=%d\n", duration, pvt->DTMFsched);
01940 }
01941 pvt->curDTMF = digit;
01942 }
01943 res = ast_queue_frame(pvt->owner, &f);
01944 }
01945 ast_channel_unlock(pvt->owner);
01946 } else {
01947 if (digit == '!')
01948 pvt->newcontrol = AST_CONTROL_FLASH;
01949 else {
01950 pvt->newduration = duration;
01951 pvt->newdigit = digit;
01952 }
01953 res = 0;
01954 }
01955 ast_mutex_unlock(&pvt->lock);
01956 return res;
01957 }
01958
01959
01960
01961
01962
01963
01964 static struct rtp_info *external_rtp_create(unsigned call_reference, const char * token)
01965 {
01966 struct oh323_pvt *pvt;
01967 struct sockaddr_in us;
01968 struct rtp_info *info;
01969
01970 info = ast_calloc(1, sizeof(*info));
01971 if (!info) {
01972 ast_log(LOG_ERROR, "Unable to allocated info structure, this is very bad\n");
01973 return NULL;
01974 }
01975 pvt = find_call_locked(call_reference, token);
01976 if (!pvt) {
01977 ast_free(info);
01978 ast_log(LOG_ERROR, "Unable to find call %s(%d)\n", token, call_reference);
01979 return NULL;
01980 }
01981 if (!pvt->rtp)
01982 __oh323_rtp_create(pvt);
01983 if (!pvt->rtp) {
01984 ast_mutex_unlock(&pvt->lock);
01985 ast_free(info);
01986 ast_log(LOG_ERROR, "No RTP stream is available for call %s (%d)", token, call_reference);
01987 return NULL;
01988 }
01989
01990 {
01991 struct ast_sockaddr tmp;
01992
01993 ast_rtp_instance_get_local_address(pvt->rtp, &tmp);
01994 ast_sockaddr_to_sin(&tmp, &us);
01995 }
01996 ast_mutex_unlock(&pvt->lock);
01997
01998 ast_copy_string(info->addr, ast_inet_ntoa(us.sin_addr), sizeof(info->addr));
01999 info->port = ntohs(us.sin_port);
02000 if (h323debug)
02001 ast_debug(1, "Sending RTP 'US' %s:%d\n", info->addr, info->port);
02002 return info;
02003 }
02004
02005
02006
02007
02008
02009
02010 static void setup_rtp_connection(unsigned call_reference, const char *remoteIp, int remotePort, const char *token, int pt)
02011 {
02012 struct oh323_pvt *pvt;
02013 struct sockaddr_in them;
02014 int nativeformats_changed;
02015 enum { NEED_NONE, NEED_HOLD, NEED_UNHOLD } rtp_change = NEED_NONE;
02016
02017 if (h323debug)
02018 ast_debug(1, "Setting up RTP connection for %s\n", token);
02019
02020
02021 pvt = find_call_locked(call_reference, token);
02022 if (!pvt) {
02023 ast_log(LOG_ERROR, "Something is wrong: rtp\n");
02024 return;
02025 }
02026 if (pvt->alreadygone) {
02027 ast_mutex_unlock(&pvt->lock);
02028 return;
02029 }
02030
02031 if (!pvt->rtp)
02032 __oh323_rtp_create(pvt);
02033
02034 if ((pt == 2) && (pvt->jointcapability & AST_FORMAT_G726_AAL2)) {
02035 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);
02036 }
02037
02038 them.sin_family = AF_INET;
02039
02040 them.sin_addr.s_addr = inet_addr(remoteIp);
02041 them.sin_port = htons(remotePort);
02042
02043 if (them.sin_addr.s_addr) {
02044 {
02045 struct ast_sockaddr tmp;
02046
02047 ast_sockaddr_from_sin(&tmp, &them);
02048 ast_rtp_instance_set_remote_address(pvt->rtp, &tmp);
02049 }
02050 if (pvt->recvonly) {
02051 pvt->recvonly = 0;
02052 rtp_change = NEED_UNHOLD;
02053 }
02054 } else {
02055 ast_rtp_instance_stop(pvt->rtp);
02056 if (!pvt->recvonly) {
02057 pvt->recvonly = 1;
02058 rtp_change = NEED_HOLD;
02059 }
02060 }
02061
02062
02063 nativeformats_changed = 0;
02064 if (pt != 128 && pvt->rtp) {
02065 struct ast_rtp_payload_type rtptype = ast_rtp_codecs_payload_lookup(ast_rtp_instance_get_codecs(pvt->rtp), pt);
02066 if (rtptype.asterisk_format) {
02067 if (pvt->nativeformats != ast_format_to_old_bitfield(&rtptype.format)) {
02068 pvt->nativeformats = ast_format_to_old_bitfield(&rtptype.format);
02069 nativeformats_changed = 1;
02070 }
02071 }
02072 } else if (h323debug)
02073 ast_log(LOG_NOTICE, "Payload type is unknown, formats isn't changed\n");
02074
02075
02076 if (nativeformats_changed || pvt->options.progress_audio || (rtp_change != NEED_NONE)) {
02077 if (pvt->owner && !ast_channel_trylock(pvt->owner)) {
02078 struct ast_format_cap *pvt_native = ast_format_cap_alloc_nolock();
02079 ast_format_cap_from_old_bitfield(pvt_native, pvt->nativeformats);
02080
02081
02082 if (!(ast_format_cap_identical(ast_channel_nativeformats(pvt->owner), pvt_native))) {
02083 if (h323debug) {
02084 char tmp[256], tmp2[256];
02085 ast_debug(1, "Native format changed to '%s' from '%s', read format is %s, write format is %s\n",
02086 ast_getformatname_multiple(tmp, sizeof(tmp), pvt_native),
02087 ast_getformatname_multiple(tmp2, sizeof(tmp2), ast_channel_nativeformats(pvt->owner)),
02088 ast_getformatname(ast_channel_readformat(pvt->owner)),
02089 ast_getformatname(ast_channel_readformat(pvt->owner)));
02090 }
02091 ast_format_cap_copy(ast_channel_nativeformats(pvt->owner), pvt_native);
02092 ast_set_read_format(pvt->owner, ast_channel_readformat(pvt->owner));
02093 ast_set_write_format(pvt->owner, ast_channel_writeformat(pvt->owner));
02094 }
02095 if (pvt->options.progress_audio)
02096 ast_queue_control(pvt->owner, AST_CONTROL_PROGRESS);
02097 switch (rtp_change) {
02098 case NEED_HOLD:
02099 ast_queue_control(pvt->owner, AST_CONTROL_HOLD);
02100 break;
02101 case NEED_UNHOLD:
02102 ast_queue_control(pvt->owner, AST_CONTROL_UNHOLD);
02103 break;
02104 default:
02105 break;
02106 }
02107 ast_channel_unlock(pvt->owner);
02108 pvt_native = ast_format_cap_destroy(pvt_native);
02109 }
02110 else {
02111 if (pvt->options.progress_audio)
02112 pvt->newcontrol = AST_CONTROL_PROGRESS;
02113 else if (rtp_change == NEED_HOLD)
02114 pvt->newcontrol = AST_CONTROL_HOLD;
02115 else if (rtp_change == NEED_UNHOLD)
02116 pvt->newcontrol = AST_CONTROL_UNHOLD;
02117 if (h323debug)
02118 ast_debug(1, "RTP connection preparation for %s is pending...\n", token);
02119 }
02120 }
02121 ast_mutex_unlock(&pvt->lock);
02122
02123 if (h323debug)
02124 ast_debug(1, "RTP connection prepared for %s\n", token);
02125
02126 return;
02127 }
02128
02129
02130
02131
02132
02133 static void connection_made(unsigned call_reference, const char *token)
02134 {
02135 struct oh323_pvt *pvt;
02136
02137 if (h323debug)
02138 ast_debug(1, "Call %s answered\n", token);
02139
02140 pvt = find_call_locked(call_reference, token);
02141 if (!pvt) {
02142 ast_log(LOG_ERROR, "Something is wrong: connection\n");
02143 return;
02144 }
02145
02146
02147 if (!pvt->outgoing) {
02148 ast_mutex_unlock(&pvt->lock);
02149 return;
02150 }
02151
02152 if (!pvt->connection_established) {
02153 pvt->connection_established = 1;
02154 update_state(pvt, -1, AST_CONTROL_ANSWER);
02155 }
02156 ast_mutex_unlock(&pvt->lock);
02157 return;
02158 }
02159
02160 static int progress(unsigned call_reference, const char *token, int inband)
02161 {
02162 struct oh323_pvt *pvt;
02163
02164 if (h323debug)
02165 ast_debug(1, "Received ALERT/PROGRESS message for %s tones\n", (inband ? "inband" : "self-generated"));
02166
02167 pvt = find_call_locked(call_reference, token);
02168 if (!pvt) {
02169 ast_log(LOG_ERROR, "Private structure not found in progress.\n");
02170 return -1;
02171 }
02172 if (!pvt->owner) {
02173 ast_mutex_unlock(&pvt->lock);
02174 ast_log(LOG_ERROR, "No Asterisk channel associated with private structure.\n");
02175 return -1;
02176 }
02177 update_state(pvt, -1, (inband ? AST_CONTROL_PROGRESS : AST_CONTROL_RINGING));
02178 ast_mutex_unlock(&pvt->lock);
02179
02180 return 0;
02181 }
02182
02183
02184
02185
02186
02187
02188 static call_options_t *setup_incoming_call(call_details_t *cd)
02189 {
02190 struct oh323_pvt *pvt;
02191 struct oh323_user *user = NULL;
02192 struct oh323_alias *alias = NULL;
02193
02194 if (h323debug)
02195 ast_debug(1, "Setting up incoming call for %s\n", cd->call_token);
02196
02197
02198 pvt = oh323_alloc(cd->call_reference);
02199
02200 if (!pvt) {
02201 ast_log(LOG_ERROR, "Unable to allocate private structure, this is bad.\n");
02202 cleanup_call_details(cd);
02203 return NULL;
02204 }
02205
02206
02207 memcpy(&pvt->cd, cd, sizeof(pvt->cd));
02208 memcpy(&pvt->options, &global_options, sizeof(pvt->options));
02209 pvt->jointcapability = pvt->options.capability;
02210
02211 if (h323debug) {
02212 ast_verb(3, "Setting up Call\n");
02213 ast_verb(3, " \tCall token: [%s]\n", pvt->cd.call_token);
02214 ast_verb(3, " \tCalling party name: [%s]\n", pvt->cd.call_source_name);
02215 ast_verb(3, " \tCalling party number: [%s]\n", pvt->cd.call_source_e164);
02216 ast_verb(3, " \tCalled party name: [%s]\n", pvt->cd.call_dest_alias);
02217 ast_verb(3, " \tCalled party number: [%s]\n", pvt->cd.call_dest_e164);
02218 if (pvt->cd.redirect_reason >= 0)
02219 ast_verb(3, " \tRedirecting party number: [%s] (reason %d)\n", pvt->cd.redirect_number, pvt->cd.redirect_reason);
02220 ast_verb(3, " \tCalling party IP: [%s]\n", pvt->cd.sourceIp);
02221 }
02222
02223
02224 if ((!strcasecmp(cd->sourceIp, gatekeeper)) && (gkroute == -1) && !gatekeeper_disable) {
02225 if (!ast_strlen_zero(cd->call_dest_e164)) {
02226 ast_copy_string(pvt->exten, cd->call_dest_e164, sizeof(pvt->exten));
02227 ast_copy_string(pvt->context, default_context, sizeof(pvt->context));
02228 } else {
02229 alias = find_alias(cd->call_dest_alias, 1);
02230 if (!alias) {
02231 ast_log(LOG_ERROR, "Call for %s rejected, alias not found\n", cd->call_dest_alias);
02232 oh323_destroy(pvt);
02233 return NULL;
02234 }
02235 ast_copy_string(pvt->exten, alias->name, sizeof(pvt->exten));
02236 ast_copy_string(pvt->context, alias->context, sizeof(pvt->context));
02237 }
02238 } else {
02239
02240
02241 user = find_user(cd, 1);
02242 if (!user) {
02243 if (!acceptAnonymous) {
02244 ast_log(LOG_NOTICE, "Anonymous call from '%s@%s' rejected\n", pvt->cd.call_source_aliases, pvt->cd.sourceIp);
02245 oh323_destroy(pvt);
02246 return NULL;
02247 }
02248 if (ast_strlen_zero(default_context)) {
02249 ast_log(LOG_ERROR, "Call from '%s@%s' rejected due to no default context\n", pvt->cd.call_source_aliases, pvt->cd.sourceIp);
02250 oh323_destroy(pvt);
02251 return NULL;
02252 }
02253 ast_copy_string(pvt->context, default_context, sizeof(pvt->context));
02254 if (!ast_strlen_zero(pvt->cd.call_dest_e164)) {
02255 ast_copy_string(pvt->exten, cd->call_dest_e164, sizeof(pvt->exten));
02256 } else {
02257 ast_copy_string(pvt->exten, cd->call_dest_alias, sizeof(pvt->exten));
02258 }
02259 if (h323debug)
02260 ast_debug(1, "Sending %s@%s to context [%s] extension %s\n", cd->call_source_aliases, cd->sourceIp, pvt->context, pvt->exten);
02261 } else {
02262 if (user->host) {
02263 if (strcasecmp(cd->sourceIp, ast_inet_ntoa(user->addr.sin_addr))) {
02264 if (ast_strlen_zero(user->context)) {
02265 if (ast_strlen_zero(default_context)) {
02266 ast_log(LOG_ERROR, "Call from '%s' rejected due to non-matching IP address (%s) and no default context\n", user->name, cd->sourceIp);
02267 oh323_destroy(pvt);
02268 ASTOBJ_UNREF(user, oh323_destroy_user);
02269 return NULL;
02270 }
02271 ast_copy_string(pvt->context, default_context, sizeof(pvt->context));
02272 } else {
02273 ast_copy_string(pvt->context, user->context, sizeof(pvt->context));
02274 }
02275 pvt->exten[0] = 'i';
02276 pvt->exten[1] = '\0';
02277 ast_log(LOG_ERROR, "Call from '%s' rejected due to non-matching IP address (%s)s\n", user->name, cd->sourceIp);
02278 oh323_destroy(pvt);
02279 ASTOBJ_UNREF(user, oh323_destroy_user);
02280 return NULL;
02281 }
02282 }
02283 ast_copy_string(pvt->context, user->context, sizeof(pvt->context));
02284 memcpy(&pvt->options, &user->options, sizeof(pvt->options));
02285 pvt->jointcapability = pvt->options.capability;
02286 if (!ast_strlen_zero(pvt->cd.call_dest_e164)) {
02287 ast_copy_string(pvt->exten, cd->call_dest_e164, sizeof(pvt->exten));
02288 } else {
02289 ast_copy_string(pvt->exten, cd->call_dest_alias, sizeof(pvt->exten));
02290 }
02291 if (!ast_strlen_zero(user->accountcode)) {
02292 ast_copy_string(pvt->accountcode, user->accountcode, sizeof(pvt->accountcode));
02293 }
02294 if (user->amaflags) {
02295 pvt->amaflags = user->amaflags;
02296 }
02297 ASTOBJ_UNREF(user, oh323_destroy_user);
02298 }
02299 }
02300 return &pvt->options;
02301 }
02302
02303
02304
02305
02306
02307
02308 static int answer_call(unsigned call_reference, const char *token)
02309 {
02310 struct oh323_pvt *pvt;
02311 struct ast_channel *c = NULL;
02312 enum {ext_original, ext_s, ext_i, ext_notexists} try_exten;
02313 char tmp_exten[sizeof(pvt->exten)];
02314
02315 if (h323debug)
02316 ast_debug(1, "Preparing Asterisk to answer for %s\n", token);
02317
02318
02319 pvt = find_call_locked(call_reference, token);
02320 if (!pvt) {
02321 ast_log(LOG_ERROR, "Something is wrong: answer_call\n");
02322 return 0;
02323 }
02324
02325 ast_copy_string(tmp_exten, pvt->exten, sizeof(tmp_exten));
02326
02327
02328 if ((tmp_exten[0] != '\0') && (tmp_exten[1] == '\0')) {
02329 if (tmp_exten[0] == 's')
02330 try_exten = ext_s;
02331 else if (tmp_exten[0] == 'i')
02332 try_exten = ext_i;
02333 else
02334 try_exten = ext_original;
02335 } else
02336 try_exten = ext_original;
02337 do {
02338 if (ast_exists_extension(NULL, pvt->context, tmp_exten, 1, NULL))
02339 break;
02340 switch (try_exten) {
02341 case ext_original:
02342 tmp_exten[0] = 's';
02343 tmp_exten[1] = '\0';
02344 try_exten = ext_s;
02345 break;
02346 case ext_s:
02347 tmp_exten[0] = 'i';
02348 try_exten = ext_i;
02349 break;
02350 case ext_i:
02351 try_exten = ext_notexists;
02352 break;
02353 default:
02354 break;
02355 }
02356 } while (try_exten != ext_notexists);
02357
02358
02359 if (try_exten == ext_notexists) {
02360 ast_log(LOG_NOTICE, "Dropping call because extensions '%s', 's' and 'i' doesn't exists in context [%s]\n", pvt->exten, pvt->context);
02361 ast_mutex_unlock(&pvt->lock);
02362 h323_clear_call(token, AST_CAUSE_UNALLOCATED);
02363 return 0;
02364 } else if ((try_exten != ext_original) && (strcmp(pvt->exten, tmp_exten) != 0)) {
02365 if (h323debug)
02366 ast_debug(1, "Going to extension %s@%s because %s@%s isn't exists\n", tmp_exten, pvt->context, pvt->exten, pvt->context);
02367 ast_copy_string(pvt->exten, tmp_exten, sizeof(pvt->exten));
02368 }
02369
02370
02371 c = __oh323_new(pvt, AST_STATE_RINGING, pvt->cd.call_token, NULL);
02372
02373
02374 ast_mutex_unlock(&pvt->lock);
02375 if (!c) {
02376 ast_log(LOG_ERROR, "Couldn't create channel. This is bad\n");
02377 return 0;
02378 }
02379 return 1;
02380 }
02381
02382
02383
02384
02385
02386
02387 static int setup_outgoing_call(call_details_t *cd)
02388 {
02389
02390 cleanup_call_details(cd);
02391
02392 return 1;
02393 }
02394
02395
02396
02397
02398
02399 static void chan_ringing(unsigned call_reference, const char *token)
02400 {
02401 struct oh323_pvt *pvt;
02402
02403 if (h323debug)
02404 ast_debug(1, "Ringing on %s\n", token);
02405
02406 pvt = find_call_locked(call_reference, token);
02407 if (!pvt) {
02408 ast_log(LOG_ERROR, "Something is wrong: ringing\n");
02409 return;
02410 }
02411 if (!pvt->owner) {
02412 ast_mutex_unlock(&pvt->lock);
02413 ast_log(LOG_ERROR, "Channel has no owner\n");
02414 return;
02415 }
02416 update_state(pvt, AST_STATE_RINGING, AST_CONTROL_RINGING);
02417 ast_mutex_unlock(&pvt->lock);
02418 return;
02419 }
02420
02421
02422
02423
02424
02425 static void cleanup_connection(unsigned call_reference, const char *call_token)
02426 {
02427 struct oh323_pvt *pvt;
02428
02429 if (h323debug)
02430 ast_debug(1, "Cleaning connection to %s\n", call_token);
02431
02432 while (1) {
02433 pvt = find_call_locked(call_reference, call_token);
02434 if (!pvt) {
02435 if (h323debug)
02436 ast_debug(1, "No connection for %s\n", call_token);
02437 return;
02438 }
02439 if (!pvt->owner || !ast_channel_trylock(pvt->owner))
02440 break;
02441 #if 1
02442 ast_log(LOG_NOTICE, "Avoiding H.323 destory deadlock on %s\n", call_token);
02443 #ifdef DEBUG_THREADS
02444
02445
02446
02447
02448
02449 #endif
02450 #endif
02451 ast_mutex_unlock(&pvt->lock);
02452 usleep(1);
02453 }
02454 if (pvt->rtp) {
02455
02456 ast_rtp_instance_destroy(pvt->rtp);
02457 pvt->rtp = NULL;
02458 }
02459
02460 if (pvt->vad) {
02461 ast_dsp_free(pvt->vad);
02462 pvt->vad = NULL;
02463 }
02464 cleanup_call_details(&pvt->cd);
02465 pvt->alreadygone = 1;
02466
02467 if (pvt->owner) {
02468 ast_channel_softhangup_internal_flag_add(pvt->owner, AST_SOFTHANGUP_DEV);
02469 ast_queue_hangup(pvt->owner);
02470 ast_channel_unlock(pvt->owner);
02471 }
02472 ast_mutex_unlock(&pvt->lock);
02473 if (h323debug)
02474 ast_debug(1, "Connection to %s cleaned\n", call_token);
02475 return;
02476 }
02477
02478 static void hangup_connection(unsigned int call_reference, const char *token, int cause)
02479 {
02480 struct oh323_pvt *pvt;
02481
02482 if (h323debug)
02483 ast_debug(1, "Hanging up connection to %s with cause %d\n", token, cause);
02484
02485 pvt = find_call_locked(call_reference, token);
02486 if (!pvt) {
02487 if (h323debug)
02488 ast_debug(1, "Connection to %s already cleared\n", token);
02489 return;
02490 }
02491 if (pvt->owner && !ast_channel_trylock(pvt->owner)) {
02492 ast_channel_softhangup_internal_flag_add(pvt->owner, AST_SOFTHANGUP_DEV);
02493 ast_channel_hangupcause_set(pvt->owner, pvt->hangupcause = cause);
02494 ast_queue_hangup_with_cause(pvt->owner, cause);
02495 ast_channel_unlock(pvt->owner);
02496 }
02497 else {
02498 pvt->needhangup = 1;
02499 pvt->hangupcause = cause;
02500 if (h323debug)
02501 ast_debug(1, "Hangup for %s is pending\n", token);
02502 }
02503 ast_mutex_unlock(&pvt->lock);
02504 }
02505
02506 static void set_dtmf_payload(unsigned call_reference, const char *token, int payload, int is_cisco)
02507 {
02508 struct oh323_pvt *pvt;
02509
02510 if (h323debug)
02511 ast_debug(1, "Setting %s DTMF payload to %d on %s\n", (is_cisco ? "Cisco" : "RFC2833"), payload, token);
02512
02513 pvt = find_call_locked(call_reference, token);
02514 if (!pvt) {
02515 return;
02516 }
02517 if (pvt->rtp) {
02518 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);
02519 }
02520 pvt->dtmf_pt[is_cisco ? 1 : 0] = payload;
02521 ast_mutex_unlock(&pvt->lock);
02522 if (h323debug)
02523 ast_debug(1, "DTMF payload on %s set to %d\n", token, payload);
02524 }
02525
02526 static void set_peer_capabilities(unsigned call_reference, const char *token, int capabilities, struct ast_codec_pref *prefs)
02527 {
02528 struct oh323_pvt *pvt;
02529
02530 if (h323debug)
02531 ast_debug(1, "Got remote capabilities from connection %s\n", token);
02532
02533 pvt = find_call_locked(call_reference, token);
02534 if (!pvt)
02535 return;
02536 pvt->peercapability = capabilities;
02537 pvt->jointcapability = pvt->options.capability & capabilities;
02538 if (prefs) {
02539 memcpy(&pvt->peer_prefs, prefs, sizeof(pvt->peer_prefs));
02540 if (h323debug) {
02541 int i;
02542 for (i = 0; i < 32; ++i) {
02543 if (!prefs->order[i])
02544 break;
02545 ast_debug(1, "prefs[%d]=%s:%d\n", i, (prefs->order[i] ? ast_getformatname(&prefs->formats[i]) : "<none>"), prefs->framing[i]);
02546 }
02547 }
02548 if (pvt->rtp) {
02549 if (pvt->options.autoframing) {
02550 ast_debug(2, "Autoframing option set, using peer's packetization settings\n");
02551 ast_rtp_codecs_packetization_set(ast_rtp_instance_get_codecs(pvt->rtp), pvt->rtp, &pvt->peer_prefs);
02552 } else {
02553 ast_debug(2, "Autoframing option not set, ignoring peer's packetization settings\n");
02554 ast_rtp_codecs_packetization_set(ast_rtp_instance_get_codecs(pvt->rtp), pvt->rtp, &pvt->options.prefs);
02555 }
02556 }
02557 }
02558 ast_mutex_unlock(&pvt->lock);
02559 }
02560
02561 static void set_local_capabilities(unsigned call_reference, const char *token)
02562 {
02563 struct oh323_pvt *pvt;
02564 int capability, dtmfmode, pref_codec;
02565 struct ast_codec_pref prefs;
02566
02567 if (h323debug)
02568 ast_debug(1, "Setting capabilities for connection %s\n", token);
02569
02570 pvt = find_call_locked(call_reference, token);
02571 if (!pvt)
02572 return;
02573 capability = (pvt->jointcapability) ? pvt->jointcapability : pvt->options.capability;
02574 dtmfmode = pvt->options.dtmfmode;
02575 prefs = pvt->options.prefs;
02576 pref_codec = pvt->pref_codec;
02577 ast_mutex_unlock(&pvt->lock);
02578 h323_set_capabilities(token, capability, dtmfmode, &prefs, pref_codec);
02579
02580 if (h323debug) {
02581 int i;
02582 for (i = 0; i < 32; i++) {
02583 if (!prefs.order[i])
02584 break;
02585 ast_debug(1, "local prefs[%d]=%s:%d\n", i, (prefs.order[i] ? ast_getformatname(&prefs.formats[i]) : "<none>"), prefs.framing[i]);
02586 }
02587 ast_debug(1, "Capabilities for connection %s is set\n", token);
02588 }
02589 }
02590
02591 static void remote_hold(unsigned call_reference, const char *token, int is_hold)
02592 {
02593 struct oh323_pvt *pvt;
02594
02595 if (h323debug)
02596 ast_debug(1, "Setting %shold status for connection %s\n", (is_hold ? "" : "un"), token);
02597
02598 pvt = find_call_locked(call_reference, token);
02599 if (!pvt)
02600 return;
02601 if (pvt->owner && !ast_channel_trylock(pvt->owner)) {
02602 if (is_hold)
02603 ast_queue_control(pvt->owner, AST_CONTROL_HOLD);
02604 else
02605 ast_queue_control(pvt->owner, AST_CONTROL_UNHOLD);
02606 ast_channel_unlock(pvt->owner);
02607 }
02608 else {
02609 if (is_hold)
02610 pvt->newcontrol = AST_CONTROL_HOLD;
02611 else
02612 pvt->newcontrol = AST_CONTROL_UNHOLD;
02613 }
02614 ast_mutex_unlock(&pvt->lock);
02615 }
02616
02617 static void *do_monitor(void *data)
02618 {
02619 int res;
02620 int reloading;
02621 struct oh323_pvt *oh323 = NULL;
02622
02623 for(;;) {
02624
02625 ast_mutex_lock(&h323_reload_lock);
02626 reloading = h323_reloading;
02627 h323_reloading = 0;
02628 ast_mutex_unlock(&h323_reload_lock);
02629 if (reloading) {
02630 ast_verb(1, "Reloading H.323\n");
02631 h323_do_reload();
02632 }
02633
02634 if (!ast_mutex_trylock(&iflock)) {
02635 #if 1
02636 do {
02637 for (oh323 = iflist; oh323; oh323 = oh323->next) {
02638 if (!ast_mutex_trylock(&oh323->lock)) {
02639 if (oh323->needdestroy) {
02640 __oh323_destroy(oh323);
02641 break;
02642 }
02643 ast_mutex_unlock(&oh323->lock);
02644 }
02645 }
02646 } while ( 0);
02647 #else
02648 restartsearch:
02649 oh323 = iflist;
02650 while(oh323) {
02651 if (!ast_mutex_trylock(&oh323->lock)) {
02652 if (oh323->needdestroy) {
02653 __oh323_destroy(oh323);
02654 goto restartsearch;
02655 }
02656 ast_mutex_unlock(&oh323->lock);
02657 oh323 = oh323->next;
02658 }
02659 }
02660 #endif
02661 ast_mutex_unlock(&iflock);
02662 } else
02663 oh323 = (struct oh323_pvt *)1;
02664 pthread_testcancel();
02665
02666 res = ast_sched_wait(sched);
02667 if ((res < 0) || (res > 1000)) {
02668 res = 1000;
02669 }
02670
02671 if (oh323)
02672 res = 1;
02673 res = ast_io_wait(io, res);
02674 pthread_testcancel();
02675 ast_mutex_lock(&monlock);
02676 if (res >= 0) {
02677 ast_sched_runq(sched);
02678 }
02679 ast_mutex_unlock(&monlock);
02680 }
02681
02682 return NULL;
02683 }
02684
02685 static int restart_monitor(void)
02686 {
02687
02688 if (ast_mutex_lock(&monlock)) {
02689 ast_log(LOG_WARNING, "Unable to lock monitor\n");
02690 return -1;
02691 }
02692 if (monitor_thread == AST_PTHREADT_STOP) {
02693 ast_mutex_unlock(&monlock);
02694 return 0;
02695 }
02696 if (monitor_thread == pthread_self()) {
02697 ast_mutex_unlock(&monlock);
02698 ast_log(LOG_WARNING, "Cannot kill myself\n");
02699 return -1;
02700 }
02701 if (monitor_thread && (monitor_thread != AST_PTHREADT_NULL)) {
02702
02703 pthread_kill(monitor_thread, SIGURG);
02704 } else {
02705
02706 if (ast_pthread_create_background(&monitor_thread, NULL, do_monitor, NULL) < 0) {
02707 monitor_thread = AST_PTHREADT_NULL;
02708 ast_mutex_unlock(&monlock);
02709 ast_log(LOG_ERROR, "Unable to start monitor thread.\n");
02710 return -1;
02711 }
02712 }
02713 ast_mutex_unlock(&monlock);
02714 return 0;
02715 }
02716
02717 static char *handle_cli_h323_set_trace(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
02718 {
02719 switch (cmd) {
02720 case CLI_INIT:
02721 e->command = "h323 set trace [on|off]";
02722 e->usage =
02723 "Usage: h323 set trace (on|off|<trace level>)\n"
02724 " Enable/Disable H.323 stack tracing for debugging purposes\n";
02725 return NULL;
02726 case CLI_GENERATE:
02727 return NULL;
02728 }
02729
02730 if (a->argc != e->args)
02731 return CLI_SHOWUSAGE;
02732 if (!strcasecmp(a->argv[3], "off")) {
02733 h323_debug(0, 0);
02734 ast_cli(a->fd, "H.323 Trace Disabled\n");
02735 } else if (!strcasecmp(a->argv[3], "on")) {
02736 h323_debug(1, 1);
02737 ast_cli(a->fd, "H.323 Trace Enabled\n");
02738 } else {
02739 int tracelevel = atoi(a->argv[3]);
02740 h323_debug(1, tracelevel);
02741 ast_cli(a->fd, "H.323 Trace Enabled (Trace Level: %d)\n", tracelevel);
02742 }
02743 return CLI_SUCCESS;
02744 }
02745
02746 static char *handle_cli_h323_set_debug(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
02747 {
02748 switch (cmd) {
02749 case CLI_INIT:
02750 e->command = "h323 set debug [on|off]";
02751 e->usage =
02752 "Usage: h323 set debug [on|off]\n"
02753 " Enable/Disable H.323 debugging output\n";
02754 return NULL;
02755 case CLI_GENERATE:
02756 return NULL;
02757 }
02758
02759 if (a->argc != e->args)
02760 return CLI_SHOWUSAGE;
02761 if (strcasecmp(a->argv[3], "on") && strcasecmp(a->argv[3], "off"))
02762 return CLI_SHOWUSAGE;
02763
02764 h323debug = (strcasecmp(a->argv[3], "on")) ? 0 : 1;
02765 ast_cli(a->fd, "H.323 Debugging %s\n", h323debug ? "Enabled" : "Disabled");
02766 return CLI_SUCCESS;
02767 }
02768
02769 static char *handle_cli_h323_cycle_gk(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
02770 {
02771 switch (cmd) {
02772 case CLI_INIT:
02773 e->command = "h323 cycle gk";
02774 e->usage =
02775 "Usage: h323 cycle gk\n"
02776 " Manually re-register with the Gatekeper (Currently Disabled)\n";
02777 return NULL;
02778 case CLI_GENERATE:
02779 return NULL;
02780 }
02781
02782 if (a->argc != 3)
02783 return CLI_SHOWUSAGE;
02784
02785 h323_gk_urq();
02786
02787
02788 if (!gatekeeper_disable) {
02789 if (h323_set_gk(gatekeeper_discover, gatekeeper, secret)) {
02790 ast_log(LOG_ERROR, "Gatekeeper registration failed.\n");
02791 }
02792 }
02793 return CLI_SUCCESS;
02794 }
02795
02796 static char *handle_cli_h323_hangup(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
02797 {
02798 switch (cmd) {
02799 case CLI_INIT:
02800 e->command = "h323 hangup";
02801 e->usage =
02802 "Usage: h323 hangup <token>\n"
02803 " Manually try to hang up the call identified by <token>\n";
02804 return NULL;
02805 case CLI_GENERATE:
02806 return NULL;
02807 }
02808
02809 if (a->argc != 3)
02810 return CLI_SHOWUSAGE;
02811 if (h323_soft_hangup(a->argv[2])) {
02812 ast_verb(3, "Hangup succeeded on %s\n", a->argv[2]);
02813 } else {
02814 ast_verb(3, "Hangup failed for %s\n", a->argv[2]);
02815 }
02816 return CLI_SUCCESS;
02817 }
02818
02819 static char *handle_cli_h323_show_tokens(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
02820 {
02821 switch (cmd) {
02822 case CLI_INIT:
02823 e->command = "h323 show tokens";
02824 e->usage =
02825 "Usage: h323 show tokens\n"
02826 " Print out all active call tokens\n";
02827 return NULL;
02828 case CLI_GENERATE:
02829 return NULL;
02830 }
02831
02832 if (a->argc != 3)
02833 return CLI_SHOWUSAGE;
02834
02835 h323_show_tokens();
02836
02837 return CLI_SUCCESS;
02838 }
02839
02840 static char *handle_cli_h323_show_version(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
02841 {
02842 switch (cmd) {
02843 case CLI_INIT:
02844 e->command = "h323 show version";
02845 e->usage =
02846 "Usage: h323 show version\n"
02847 " Show the version of the H.323 library in use\n";
02848 return NULL;
02849 case CLI_GENERATE:
02850 return NULL;
02851 }
02852
02853 if (a->argc != 3)
02854 return CLI_SHOWUSAGE;
02855
02856 h323_show_version();
02857
02858 return CLI_SUCCESS;
02859 }
02860
02861 static struct ast_cli_entry cli_h323[] = {
02862 AST_CLI_DEFINE(handle_cli_h323_set_trace, "Enable/Disable H.323 Stack Tracing"),
02863 AST_CLI_DEFINE(handle_cli_h323_set_debug, "Enable/Disable H.323 Debugging"),
02864 AST_CLI_DEFINE(handle_cli_h323_cycle_gk, "Manually re-register with the Gatekeper"),
02865 AST_CLI_DEFINE(handle_cli_h323_hangup, "Manually try to hang up a call"),
02866 AST_CLI_DEFINE(handle_cli_h323_show_tokens, "Show all active call tokens"),
02867 AST_CLI_DEFINE(handle_cli_h323_show_version, "Show the version of the H.323 library in use"),
02868 };
02869
02870 static void delete_users(void)
02871 {
02872 int pruned = 0;
02873
02874
02875 ASTOBJ_CONTAINER_WRLOCK(&userl);
02876 ASTOBJ_CONTAINER_TRAVERSE(&userl, 1, do {
02877 ASTOBJ_RDLOCK(iterator);
02878 ASTOBJ_MARK(iterator);
02879 ++pruned;
02880 ASTOBJ_UNLOCK(iterator);
02881 } while (0) );
02882 if (pruned) {
02883 ASTOBJ_CONTAINER_PRUNE_MARKED(&userl, oh323_destroy_user);
02884 }
02885 ASTOBJ_CONTAINER_UNLOCK(&userl);
02886
02887 ASTOBJ_CONTAINER_WRLOCK(&peerl);
02888 ASTOBJ_CONTAINER_TRAVERSE(&peerl, 1, do {
02889 ASTOBJ_RDLOCK(iterator);
02890 ASTOBJ_MARK(iterator);
02891 ASTOBJ_UNLOCK(iterator);
02892 } while (0) );
02893 ASTOBJ_CONTAINER_UNLOCK(&peerl);
02894 }
02895
02896 static void delete_aliases(void)
02897 {
02898 int pruned = 0;
02899
02900
02901 ASTOBJ_CONTAINER_WRLOCK(&aliasl);
02902 ASTOBJ_CONTAINER_TRAVERSE(&aliasl, 1, do {
02903 ASTOBJ_RDLOCK(iterator);
02904 ASTOBJ_MARK(iterator);
02905 ++pruned;
02906 ASTOBJ_UNLOCK(iterator);
02907 } while (0) );
02908 if (pruned) {
02909 ASTOBJ_CONTAINER_PRUNE_MARKED(&aliasl, oh323_destroy_alias);
02910 }
02911 ASTOBJ_CONTAINER_UNLOCK(&aliasl);
02912 }
02913
02914 static void prune_peers(void)
02915 {
02916
02917 ASTOBJ_CONTAINER_PRUNE_MARKED(&peerl, oh323_destroy_peer);
02918 }
02919
02920 static int reload_config(int is_reload)
02921 {
02922 struct ast_config *cfg, *ucfg;
02923 struct ast_variable *v;
02924 struct oh323_peer *peer = NULL;
02925 struct oh323_user *user = NULL;
02926 struct oh323_alias *alias = NULL;
02927 struct ast_hostent ahp; struct hostent *hp;
02928 char *cat;
02929 const char *utype;
02930 int is_user, is_peer, is_alias;
02931 char _gatekeeper[100];
02932 int gk_discover, gk_disable, gk_changed;
02933 struct ast_flags config_flags = { is_reload ? CONFIG_FLAG_FILEUNCHANGED : 0 };
02934
02935 cfg = ast_config_load(config, config_flags);
02936
02937
02938 if (!cfg) {
02939 ast_log(LOG_NOTICE, "Unable to load config %s, H.323 disabled\n", config);
02940 return 1;
02941 } else if (cfg == CONFIG_STATUS_FILEUNCHANGED) {
02942 ucfg = ast_config_load("users.conf", config_flags);
02943 if (ucfg == CONFIG_STATUS_FILEUNCHANGED) {
02944 return 0;
02945 } else if (ucfg == CONFIG_STATUS_FILEINVALID) {
02946 ast_log(LOG_ERROR, "Config file users.conf is in an invalid format. Aborting.\n");
02947 return 0;
02948 }
02949 ast_clear_flag(&config_flags, CONFIG_FLAG_FILEUNCHANGED);
02950 if ((cfg = ast_config_load(config, config_flags)) == CONFIG_STATUS_FILEINVALID) {
02951 ast_log(LOG_ERROR, "Config file %s is in an invalid format. Aborting.\n", config);
02952 ast_config_destroy(ucfg);
02953 return 0;
02954 }
02955 } else if (cfg == CONFIG_STATUS_FILEINVALID) {
02956 ast_log(LOG_ERROR, "Config file %s is in an invalid format. Aborting.\n", config);
02957 return 0;
02958 } else {
02959 ast_clear_flag(&config_flags, CONFIG_FLAG_FILEUNCHANGED);
02960 if ((ucfg = ast_config_load("users.conf", config_flags)) == CONFIG_STATUS_FILEINVALID) {
02961 ast_log(LOG_ERROR, "Config file users.conf is in an invalid format. Aborting.\n");
02962 ast_config_destroy(cfg);
02963 return 0;
02964 }
02965 }
02966
02967 if (is_reload) {
02968 delete_users();
02969 delete_aliases();
02970 prune_peers();
02971 }
02972
02973
02974 if (!h323_end_point_exist()) {
02975 h323_end_point_create();
02976 }
02977 ast_copy_string(_gatekeeper, gatekeeper, sizeof(_gatekeeper));
02978 gk_discover = gatekeeper_discover;
02979 gk_disable = gatekeeper_disable;
02980 memset(&bindaddr, 0, sizeof(bindaddr));
02981 memset(&global_options, 0, sizeof(global_options));
02982 global_options.fastStart = 1;
02983 global_options.h245Tunneling = 1;
02984 global_options.dtmfcodec[0] = H323_DTMF_RFC2833_PT;
02985 global_options.dtmfcodec[1] = H323_DTMF_CISCO_PT;
02986 global_options.dtmfmode = 0;
02987 global_options.holdHandling = 0;
02988 global_options.capability = GLOBAL_CAPABILITY;
02989 global_options.bridge = 1;
02990 global_options.autoframing = 0;
02991 strcpy(default_context, "default");
02992 h323_signalling_port = 1720;
02993 gatekeeper_disable = 1;
02994 gatekeeper_discover = 0;
02995 gkroute = 0;
02996 userbyalias = 1;
02997 acceptAnonymous = 1;
02998 tos = 0;
02999 cos = 0;
03000
03001
03002 memcpy(&global_jbconf, &default_jbconf, sizeof(struct ast_jb_conf));
03003
03004 if (ucfg) {
03005 struct ast_variable *gen;
03006 int genhas_h323;
03007 const char *has_h323;
03008
03009 genhas_h323 = ast_true(ast_variable_retrieve(ucfg, "general", "hash323"));
03010 gen = ast_variable_browse(ucfg, "general");
03011 for (cat = ast_category_browse(ucfg, NULL); cat; cat = ast_category_browse(ucfg, cat)) {
03012 if (strcasecmp(cat, "general")) {
03013 has_h323 = ast_variable_retrieve(ucfg, cat, "hash323");
03014 if (ast_true(has_h323) || (!has_h323 && genhas_h323)) {
03015 user = build_user(cat, gen, ast_variable_browse(ucfg, cat), 0);
03016 if (user) {
03017 ASTOBJ_CONTAINER_LINK(&userl, user);
03018 ASTOBJ_UNREF(user, oh323_destroy_user);
03019 }
03020 peer = build_peer(cat, gen, ast_variable_browse(ucfg, cat), 0);
03021 if (peer) {
03022 ASTOBJ_CONTAINER_LINK(&peerl, peer);
03023 ASTOBJ_UNREF(peer, oh323_destroy_peer);
03024 }
03025 }
03026 }
03027 }
03028 ast_config_destroy(ucfg);
03029 }
03030
03031 for (v = ast_variable_browse(cfg, "general"); v; v = v->next) {
03032
03033 if (!ast_jb_read_conf(&global_jbconf, v->name, v->value))
03034 continue;
03035
03036 if (!strcasecmp(v->name, "port")) {
03037 h323_signalling_port = (int)strtol(v->value, NULL, 10);
03038 } else if (!strcasecmp(v->name, "bindaddr")) {
03039 if (!(hp = ast_gethostbyname(v->value, &ahp))) {
03040 ast_log(LOG_WARNING, "Invalid address: %s\n", v->value);
03041 } else {
03042 memcpy(&bindaddr.sin_addr, hp->h_addr, sizeof(bindaddr.sin_addr));
03043 }
03044 } else if (!strcasecmp(v->name, "tos")) {
03045 ast_log(LOG_WARNING, "The \"tos\" setting is deprecated in this version of Asterisk. Please change to \"tos_audio\".\n");
03046 if (ast_str2tos(v->value, &tos)) {
03047 ast_log(LOG_WARNING, "Invalid tos_audio value at line %d, refer to QoS documentation\n", v->lineno);
03048 }
03049 } else if (!strcasecmp(v->name, "tos_audio")) {
03050 if (ast_str2tos(v->value, &tos)) {
03051 ast_log(LOG_WARNING, "Invalid tos_audio value at line %d, refer to QoS documentation\n", v->lineno);
03052 }
03053 } else if (!strcasecmp(v->name, "cos")) {
03054 ast_log(LOG_WARNING, "The \"cos\" setting is deprecated in this version of Asterisk. Please change to \"cos_audio\".\n");
03055 if (ast_str2cos(v->value, &cos)) {
03056 ast_log(LOG_WARNING, "Invalid cos_audio value at line %d, refer to QoS documentation\n", v->lineno);
03057 }
03058 } else if (!strcasecmp(v->name, "cos_audio")) {
03059 if (ast_str2cos(v->value, &cos)) {
03060 ast_log(LOG_WARNING, "Invalid cos_audio value at line %d, refer to QoS documentation\n", v->lineno);
03061 }
03062 } else if (!strcasecmp(v->name, "gatekeeper")) {
03063 if (!strcasecmp(v->value, "DISABLE")) {
03064 gatekeeper_disable = 1;
03065 } else if (!strcasecmp(v->value, "DISCOVER")) {
03066 gatekeeper_disable = 0;
03067 gatekeeper_discover = 1;
03068 } else {
03069 gatekeeper_disable = 0;
03070 ast_copy_string(gatekeeper, v->value, sizeof(gatekeeper));
03071 }
03072 } else if (!strcasecmp(v->name, "secret")) {
03073 ast_copy_string(secret, v->value, sizeof(secret));
03074 } else if (!strcasecmp(v->name, "AllowGKRouted")) {
03075 gkroute = ast_true(v->value);
03076 } else if (!strcasecmp(v->name, "context")) {
03077 ast_copy_string(default_context, v->value, sizeof(default_context));
03078 ast_verb(2, "Setting default context to %s\n", default_context);
03079 } else if (!strcasecmp(v->name, "UserByAlias")) {
03080 userbyalias = ast_true(v->value);
03081 } else if (!strcasecmp(v->name, "AcceptAnonymous")) {
03082 acceptAnonymous = ast_true(v->value);
03083 } else if (!update_common_options(v, &global_options)) {
03084
03085 }
03086 }
03087 if (!global_options.dtmfmode)
03088 global_options.dtmfmode = H323_DTMF_RFC2833;
03089 if (global_options.holdHandling == ~0)
03090 global_options.holdHandling = 0;
03091 else if (!global_options.holdHandling)
03092 global_options.holdHandling = H323_HOLD_H450;
03093
03094 for (cat = ast_category_browse(cfg, NULL); cat; cat = ast_category_browse(cfg, cat)) {
03095 if (strcasecmp(cat, "general")) {
03096 utype = ast_variable_retrieve(cfg, cat, "type");
03097 if (utype) {
03098 is_user = is_peer = is_alias = 0;
03099 if (!strcasecmp(utype, "user"))
03100 is_user = 1;
03101 else if (!strcasecmp(utype, "peer"))
03102 is_peer = 1;
03103 else if (!strcasecmp(utype, "friend"))
03104 is_user = is_peer = 1;
03105 else if (!strcasecmp(utype, "h323") || !strcasecmp(utype, "alias"))
03106 is_alias = 1;
03107 else {
03108 ast_log(LOG_WARNING, "Unknown type '%s' for '%s' in %s\n", utype, cat, config);
03109 continue;
03110 }
03111 if (is_user) {
03112 user = build_user(cat, ast_variable_browse(cfg, cat), NULL, 0);
03113 if (user) {
03114 ASTOBJ_CONTAINER_LINK(&userl, user);
03115 ASTOBJ_UNREF(user, oh323_destroy_user);
03116 }
03117 }
03118 if (is_peer) {
03119 peer = build_peer(cat, ast_variable_browse(cfg, cat), NULL, 0);
03120 if (peer) {
03121 ASTOBJ_CONTAINER_LINK(&peerl, peer);
03122 ASTOBJ_UNREF(peer, oh323_destroy_peer);
03123 }
03124 }
03125 if (is_alias) {
03126 alias = build_alias(cat, ast_variable_browse(cfg, cat), NULL, 0);
03127 if (alias) {
03128 ASTOBJ_CONTAINER_LINK(&aliasl, alias);
03129 ASTOBJ_UNREF(alias, oh323_destroy_alias);
03130 }
03131 }
03132 } else {
03133 ast_log(LOG_WARNING, "Section '%s' lacks type\n", cat);
03134 }
03135 }
03136 }
03137 ast_config_destroy(cfg);
03138
03139
03140 ASTOBJ_CONTAINER_WRLOCK(&aliasl);
03141 ASTOBJ_CONTAINER_TRAVERSE(&aliasl, 1, do {
03142 ASTOBJ_RDLOCK(iterator);
03143 if (h323_set_alias(iterator)) {
03144 ast_log(LOG_ERROR, "Alias %s rejected by endpoint\n", alias->name);
03145 ASTOBJ_UNLOCK(iterator);
03146 continue;
03147 }
03148 ASTOBJ_UNLOCK(iterator);
03149 } while (0) );
03150 ASTOBJ_CONTAINER_UNLOCK(&aliasl);
03151
03152
03153 gk_changed = 0;
03154 if (gatekeeper_disable != gk_disable)
03155 gk_changed = is_reload;
03156 else if(!gatekeeper_disable && (gatekeeper_discover != gk_discover))
03157 gk_changed = is_reload;
03158 else if(!gatekeeper_disable && (strncmp(_gatekeeper, gatekeeper, sizeof(_gatekeeper)) != 0))
03159 gk_changed = is_reload;
03160 if (gk_changed) {
03161 if(!gk_disable)
03162 h323_gk_urq();
03163 if (!gatekeeper_disable) {
03164 if (h323_set_gk(gatekeeper_discover, gatekeeper, secret)) {
03165 ast_log(LOG_ERROR, "Gatekeeper registration failed.\n");
03166 gatekeeper_disable = 1;
03167 }
03168 }
03169 }
03170 return 0;
03171 }
03172
03173 static int h323_reload(void)
03174 {
03175 ast_mutex_lock(&h323_reload_lock);
03176 if (h323_reloading) {
03177 ast_verbose("Previous H.323 reload not yet done\n");
03178 } else {
03179 h323_reloading = 1;
03180 }
03181 ast_mutex_unlock(&h323_reload_lock);
03182 restart_monitor();
03183 return 0;
03184 }
03185
03186 static char *handle_cli_h323_reload(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
03187 {
03188 switch (cmd) {
03189 case CLI_INIT:
03190 e->command = "h323 reload";
03191 e->usage =
03192 "Usage: h323 reload\n"
03193 " Reloads H.323 configuration from h323.conf\n";
03194 return NULL;
03195 case CLI_GENERATE:
03196 return NULL;
03197 }
03198
03199 if (a->argc != 2)
03200 return CLI_SHOWUSAGE;
03201
03202 h323_reload();
03203
03204 return CLI_SUCCESS;
03205 }
03206
03207 static int h323_do_reload(void)
03208 {
03209 reload_config(1);
03210 return 0;
03211 }
03212
03213 static int reload(void)
03214 {
03215 if (!sched || !io) {
03216 ast_log(LOG_NOTICE, "Unload and load chan_h323.so again in order to receive configuration changes.\n");
03217 return 0;
03218 }
03219 return h323_reload();
03220 }
03221
03222 static struct ast_cli_entry cli_h323_reload =
03223 AST_CLI_DEFINE(handle_cli_h323_reload, "Reload H.323 configuration");
03224
03225 static enum ast_rtp_glue_result oh323_get_rtp_peer(struct ast_channel *chan, struct ast_rtp_instance **instance)
03226 {
03227 struct oh323_pvt *pvt;
03228 enum ast_rtp_glue_result res = AST_RTP_GLUE_RESULT_LOCAL;
03229
03230 if (!(pvt = (struct oh323_pvt *)ast_channel_tech_pvt(chan)))
03231 return AST_RTP_GLUE_RESULT_FORBID;
03232
03233 ast_mutex_lock(&pvt->lock);
03234 *instance = pvt->rtp ? ao2_ref(pvt->rtp, +1), pvt->rtp : NULL;
03235 #if 0
03236 if (pvt->options.bridge) {
03237 res = AST_RTP_GLUE_RESULT_REMOTE;
03238 }
03239 #endif
03240 ast_mutex_unlock(&pvt->lock);
03241
03242 return res;
03243 }
03244
03245 #if 0
03246 static char *convertcap(struct ast_format *format)
03247 {
03248 switch (format->id) {
03249 case AST_FORMAT_G723_1:
03250 return "G.723";
03251 case AST_FORMAT_GSM:
03252 return "GSM";
03253 case AST_FORMAT_ULAW:
03254 return "ULAW";
03255 case AST_FORMAT_ALAW:
03256 return "ALAW";
03257 case AST_FORMAT_G722:
03258 return "G.722";
03259 case AST_FORMAT_ADPCM:
03260 return "G.728";
03261 case AST_FORMAT_G729A:
03262 return "G.729";
03263 case AST_FORMAT_SPEEX:
03264 return "SPEEX";
03265 case AST_FORMAT_ILBC:
03266 return "ILBC";
03267 default:
03268 ast_log(LOG_NOTICE, "Don't know how to deal with mode %s\n", ast_getformatname(format));
03269 return NULL;
03270 }
03271 }
03272 #endif
03273
03274 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)
03275 {
03276
03277 struct oh323_pvt *pvt;
03278 struct sockaddr_in them = { 0, };
03279 struct sockaddr_in us = { 0, };
03280 #if 0
03281 char *mode;
03282 #endif
03283
03284 if (!rtp) {
03285 return 0;
03286 }
03287
03288 #if 0
03289 mode = convertcap(&chan->writeformat);
03290 #endif
03291
03292 pvt = (struct oh323_pvt *) ast_channel_tech_pvt(chan);
03293 if (!pvt) {
03294 ast_log(LOG_ERROR, "No Private Structure, this is bad\n");
03295 return -1;
03296 }
03297 {
03298 struct ast_sockaddr tmp;
03299
03300 ast_rtp_instance_get_remote_address(rtp, &tmp);
03301 ast_sockaddr_to_sin(&tmp, &them);
03302 ast_rtp_instance_get_local_address(rtp, &tmp);
03303 ast_sockaddr_to_sin(&tmp, &us);
03304 }
03305 #if 0
03306 h323_native_bridge(pvt->cd.call_token, ast_inet_ntoa(them.sin_addr), mode);
03307 #endif
03308 return 0;
03309 }
03310
03311 static struct ast_rtp_glue oh323_rtp_glue = {
03312 .type = "H323",
03313 .get_rtp_info = oh323_get_rtp_peer,
03314 .update_peer = oh323_set_rtp_peer,
03315 };
03316
03317 static enum ast_module_load_result load_module(void)
03318 {
03319 int res;
03320
03321 if (!(oh323_tech.capabilities = ast_format_cap_alloc())) {
03322 return AST_MODULE_LOAD_FAILURE;
03323 }
03324 ast_format_cap_add_all_by_type(oh323_tech.capabilities, AST_FORMAT_TYPE_AUDIO);
03325
03326 h323debug = 0;
03327 sched = ast_sched_context_create();
03328 if (!sched) {
03329 ast_log(LOG_WARNING, "Unable to create schedule context\n");
03330 return AST_MODULE_LOAD_FAILURE;
03331 }
03332 io = io_context_create();
03333 if (!io) {
03334 ast_log(LOG_WARNING, "Unable to create I/O context\n");
03335 return AST_MODULE_LOAD_FAILURE;
03336 }
03337 ast_cli_register(&cli_h323_reload);
03338 ASTOBJ_CONTAINER_INIT(&userl);
03339 ASTOBJ_CONTAINER_INIT(&peerl);
03340 ASTOBJ_CONTAINER_INIT(&aliasl);
03341 res = reload_config(0);
03342 if (res) {
03343
03344 ast_log(LOG_NOTICE, "Unload and load chan_h323.so again in order to receive configuration changes.\n");
03345 ast_cli_unregister(&cli_h323_reload);
03346 io_context_destroy(io);
03347 io = NULL;
03348 ast_sched_context_destroy(sched);
03349 sched = NULL;
03350 ASTOBJ_CONTAINER_DESTROY(&userl);
03351 ASTOBJ_CONTAINER_DESTROY(&peerl);
03352 ASTOBJ_CONTAINER_DESTROY(&aliasl);
03353 return AST_MODULE_LOAD_DECLINE;
03354 } else {
03355
03356 if (ast_channel_register(&oh323_tech)) {
03357 ast_log(LOG_ERROR, "Unable to register channel class 'H323'\n");
03358 ast_cli_unregister(&cli_h323_reload);
03359 h323_end_process();
03360 io_context_destroy(io);
03361 ast_sched_context_destroy(sched);
03362
03363 ASTOBJ_CONTAINER_DESTROYALL(&userl, oh323_destroy_user);
03364 ASTOBJ_CONTAINER_DESTROY(&userl);
03365 ASTOBJ_CONTAINER_DESTROYALL(&peerl, oh323_destroy_peer);
03366 ASTOBJ_CONTAINER_DESTROY(&peerl);
03367 ASTOBJ_CONTAINER_DESTROYALL(&aliasl, oh323_destroy_alias);
03368 ASTOBJ_CONTAINER_DESTROY(&aliasl);
03369
03370 return AST_MODULE_LOAD_FAILURE;
03371 }
03372 ast_cli_register_multiple(cli_h323, sizeof(cli_h323) / sizeof(struct ast_cli_entry));
03373
03374 ast_rtp_glue_register(&oh323_rtp_glue);
03375
03376
03377 h323_callback_register(setup_incoming_call,
03378 setup_outgoing_call,
03379 external_rtp_create,
03380 setup_rtp_connection,
03381 cleanup_connection,
03382 chan_ringing,
03383 connection_made,
03384 receive_digit,
03385 answer_call,
03386 progress,
03387 set_dtmf_payload,
03388 hangup_connection,
03389 set_local_capabilities,
03390 set_peer_capabilities,
03391 remote_hold);
03392
03393 if (h323_start_listener(h323_signalling_port, bindaddr)) {
03394 ast_log(LOG_ERROR, "Unable to create H323 listener.\n");
03395 ast_rtp_glue_unregister(&oh323_rtp_glue);
03396 ast_cli_unregister_multiple(cli_h323, sizeof(cli_h323) / sizeof(struct ast_cli_entry));
03397 ast_cli_unregister(&cli_h323_reload);
03398 h323_end_process();
03399 io_context_destroy(io);
03400 ast_sched_context_destroy(sched);
03401
03402 ASTOBJ_CONTAINER_DESTROYALL(&userl, oh323_destroy_user);
03403 ASTOBJ_CONTAINER_DESTROY(&userl);
03404 ASTOBJ_CONTAINER_DESTROYALL(&peerl, oh323_destroy_peer);
03405 ASTOBJ_CONTAINER_DESTROY(&peerl);
03406 ASTOBJ_CONTAINER_DESTROYALL(&aliasl, oh323_destroy_alias);
03407 ASTOBJ_CONTAINER_DESTROY(&aliasl);
03408
03409 return AST_MODULE_LOAD_DECLINE;
03410 }
03411
03412 if (!gatekeeper_disable) {
03413 if (h323_set_gk(gatekeeper_discover, gatekeeper, secret)) {
03414 ast_log(LOG_ERROR, "Gatekeeper registration failed.\n");
03415 gatekeeper_disable = 1;
03416 res = AST_MODULE_LOAD_SUCCESS;
03417 }
03418 }
03419
03420 restart_monitor();
03421 }
03422 return res;
03423 }
03424
03425 static int unload_module(void)
03426 {
03427 struct oh323_pvt *p, *pl;
03428
03429
03430 ast_cli_unregister_multiple(cli_h323, sizeof(cli_h323) / sizeof(struct ast_cli_entry));
03431 ast_cli_unregister(&cli_h323_reload);
03432
03433 ast_channel_unregister(&oh323_tech);
03434 ast_rtp_glue_unregister(&oh323_rtp_glue);
03435
03436 if (!ast_mutex_lock(&iflock)) {
03437
03438 p = iflist;
03439 while(p) {
03440 if (p->owner) {
03441 ast_softhangup(p->owner, AST_SOFTHANGUP_APPUNLOAD);
03442 }
03443 p = p->next;
03444 }
03445 iflist = NULL;
03446 ast_mutex_unlock(&iflock);
03447 } else {
03448 ast_log(LOG_WARNING, "Unable to lock the interface list\n");
03449 return -1;
03450 }
03451 if (!ast_mutex_lock(&monlock)) {
03452 if ((monitor_thread != AST_PTHREADT_STOP) && (monitor_thread != AST_PTHREADT_NULL)) {
03453 if (monitor_thread != pthread_self()) {
03454 pthread_cancel(monitor_thread);
03455 }
03456 pthread_kill(monitor_thread, SIGURG);
03457 pthread_join(monitor_thread, NULL);
03458 }
03459 monitor_thread = AST_PTHREADT_STOP;
03460 ast_mutex_unlock(&monlock);
03461 } else {
03462 ast_log(LOG_WARNING, "Unable to lock the monitor\n");
03463 return -1;
03464 }
03465 if (!ast_mutex_lock(&iflock)) {
03466
03467 p = iflist;
03468 while(p) {
03469 pl = p;
03470 p = p->next;
03471
03472 ast_mutex_destroy(&pl->lock);
03473 ast_free(pl);
03474 }
03475 iflist = NULL;
03476 ast_mutex_unlock(&iflock);
03477 } else {
03478 ast_log(LOG_WARNING, "Unable to lock the interface list\n");
03479 return -1;
03480 }
03481 if (!gatekeeper_disable)
03482 h323_gk_urq();
03483 h323_end_process();
03484 if (io)
03485 io_context_destroy(io);
03486 if (sched)
03487 ast_sched_context_destroy(sched);
03488
03489 ASTOBJ_CONTAINER_DESTROYALL(&userl, oh323_destroy_user);
03490 ASTOBJ_CONTAINER_DESTROY(&userl);
03491 ASTOBJ_CONTAINER_DESTROYALL(&peerl, oh323_destroy_peer);
03492 ASTOBJ_CONTAINER_DESTROY(&peerl);
03493 ASTOBJ_CONTAINER_DESTROYALL(&aliasl, oh323_destroy_alias);
03494 ASTOBJ_CONTAINER_DESTROY(&aliasl);
03495
03496 oh323_tech.capabilities = ast_format_cap_destroy(oh323_tech.capabilities);
03497 return 0;
03498 }
03499
03500 AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_LOAD_ORDER, "The NuFone Network's OpenH323 Channel Driver",
03501 .load = load_module,
03502 .unload = unload_module,
03503 .reload = reload,
03504 .load_pri = AST_MODPRI_CHANNEL_DRIVER,
03505 );