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 #ifdef __cplusplus
00042 extern "C" {
00043 #endif
00044
00045 #include "asterisk.h"
00046
00047 ASTERISK_FILE_VERSION(__FILE__, "$Revision: 152958 $")
00048
00049 #ifdef __cplusplus
00050 }
00051 #endif
00052
00053 #include <sys/types.h>
00054 #include <sys/socket.h>
00055 #include <sys/signal.h>
00056 #include <sys/param.h>
00057 #if defined(BSD) || defined(SOLARIS)
00058 #ifndef IPTOS_MINCOST
00059 #define IPTOS_MINCOST 0x02
00060 #endif
00061 #endif
00062 #include <arpa/inet.h>
00063 #include <net/if.h>
00064 #include <netinet/in.h>
00065 #include <netinet/in_systm.h>
00066 #include <netinet/ip.h>
00067 #include <unistd.h>
00068 #include <stdlib.h>
00069 #include <netdb.h>
00070 #include <stdio.h>
00071 #include <string.h>
00072 #include <errno.h>
00073 #include <fcntl.h>
00074
00075 #ifdef __cplusplus
00076 extern "C" {
00077 #endif
00078
00079 #include "asterisk/lock.h"
00080 #include "asterisk/logger.h"
00081 #include "asterisk/channel.h"
00082 #include "asterisk/config.h"
00083 #include "asterisk/module.h"
00084 #include "asterisk/musiconhold.h"
00085 #include "asterisk/pbx.h"
00086 #include "asterisk/options.h"
00087 #include "asterisk/utils.h"
00088 #include "asterisk/lock.h"
00089 #include "asterisk/sched.h"
00090 #include "asterisk/io.h"
00091 #include "asterisk/rtp.h"
00092 #include "asterisk/acl.h"
00093 #include "asterisk/callerid.h"
00094 #include "asterisk/cli.h"
00095 #include "asterisk/dsp.h"
00096 #include "asterisk/causes.h"
00097 #include "asterisk/stringfields.h"
00098 #include "asterisk/abstract_jb.h"
00099 #include "asterisk/astobj.h"
00100
00101 #ifdef __cplusplus
00102 }
00103 #endif
00104
00105 #include "h323/chan_h323.h"
00106
00107 receive_digit_cb on_receive_digit;
00108 on_rtp_cb on_external_rtp_create;
00109 start_rtp_cb on_start_rtp_channel;
00110 setup_incoming_cb on_incoming_call;
00111 setup_outbound_cb on_outgoing_call;
00112 chan_ringing_cb on_chan_ringing;
00113 con_established_cb on_connection_established;
00114 clear_con_cb on_connection_cleared;
00115 answer_call_cb on_answer_call;
00116 progress_cb on_progress;
00117 rfc2833_cb on_set_rfc2833_payload;
00118 hangup_cb on_hangup;
00119 setcapabilities_cb on_setcapabilities;
00120 setpeercapabilities_cb on_setpeercapabilities;
00121
00122
00123 int h323debug;
00124
00125
00126 static struct ast_jb_conf default_jbconf =
00127 {
00128 .flags = 0,
00129 .max_size = -1,
00130 .resync_threshold = -1,
00131 .impl = ""
00132 };
00133 static struct ast_jb_conf global_jbconf;
00134
00135
00136 static const char tdesc[] = "The NuFone Network's Open H.323 Channel Driver";
00137 static const char config[] = "h323.conf";
00138 static char default_context[AST_MAX_CONTEXT] = "default";
00139 static struct sockaddr_in bindaddr;
00140
00141 #define GLOBAL_CAPABILITY (AST_FORMAT_G723_1 | AST_FORMAT_GSM | AST_FORMAT_ULAW | AST_FORMAT_ALAW | AST_FORMAT_G729A | AST_FORMAT_H261)
00142
00143
00144 static int h323_signalling_port = 1720;
00145 static char gatekeeper[100];
00146 static int gatekeeper_disable = 1;
00147 static int gatekeeper_discover = 0;
00148 static int gkroute = 0;
00149
00150 static int userbyalias = 1;
00151 static int acceptAnonymous = 1;
00152 static int tos = 0;
00153 static char secret[50];
00154 static unsigned int unique = 0;
00155
00156 static call_options_t global_options;
00157
00158
00159 struct oh323_pvt {
00160 ast_mutex_t lock;
00161 call_options_t options;
00162 int alreadygone;
00163 int needdestroy;
00164 call_details_t cd;
00165 struct ast_channel *owner;
00166 struct sockaddr_in sa;
00167 struct sockaddr_in redirip;
00168 int nonCodecCapability;
00169 int outgoing;
00170 char exten[AST_MAX_EXTENSION];
00171 char context[AST_MAX_CONTEXT];
00172 char accountcode[256];
00173 char rdnis[80];
00174 int amaflags;
00175 struct ast_rtp *rtp;
00176 struct ast_dsp *vad;
00177 int nativeformats;
00178 int needhangup;
00179 int hangupcause;
00180 int newstate;
00181 int newcontrol;
00182 int newdigit;
00183 int newduration;
00184 int pref_codec;
00185 int peercapability;
00186 int jointcapability;
00187 struct ast_codec_pref peer_prefs;
00188 int dtmf_pt;
00189 int curDTMF;
00190 int DTMFsched;
00191 int update_rtp_info;
00192 int recvonly;
00193 int txDtmfDigit;
00194 int noInbandDtmf;
00195 int connection_established;
00196 int got_progress;
00197 struct oh323_pvt *next;
00198 } *iflist = NULL;
00199
00200 static struct ast_user_list {
00201 ASTOBJ_CONTAINER_COMPONENTS(struct oh323_user);
00202 } userl;
00203
00204 static struct ast_peer_list {
00205 ASTOBJ_CONTAINER_COMPONENTS(struct oh323_peer);
00206 } peerl;
00207
00208 static struct ast_alias_list {
00209 ASTOBJ_CONTAINER_COMPONENTS(struct oh323_alias);
00210 } aliasl;
00211
00212
00213 static struct sched_context *sched;
00214 static struct io_context *io;
00215
00216
00217 AST_MUTEX_DEFINE_STATIC(iflock);
00218
00219
00220
00221 AST_MUTEX_DEFINE_STATIC(monlock);
00222
00223
00224 AST_MUTEX_DEFINE_STATIC(caplock);
00225
00226
00227 AST_MUTEX_DEFINE_STATIC(h323_reload_lock);
00228 static int h323_reloading = 0;
00229
00230
00231
00232 static pthread_t monitor_thread = AST_PTHREADT_NULL;
00233 static int restart_monitor(void);
00234 static int h323_do_reload(void);
00235
00236 static struct ast_channel *oh323_request(const char *type, int format, void *data, int *cause);
00237 static int oh323_digit_begin(struct ast_channel *c, char digit);
00238 static int oh323_digit_end(struct ast_channel *c, char digit, unsigned int duration);
00239 static int oh323_call(struct ast_channel *c, char *dest, int timeout);
00240 static int oh323_hangup(struct ast_channel *c);
00241 static int oh323_answer(struct ast_channel *c);
00242 static struct ast_frame *oh323_read(struct ast_channel *c);
00243 static int oh323_write(struct ast_channel *c, struct ast_frame *frame);
00244 static int oh323_indicate(struct ast_channel *c, int condition, const void *data, size_t datalen);
00245 static int oh323_fixup(struct ast_channel *oldchan, struct ast_channel *newchan);
00246
00247 static const struct ast_channel_tech oh323_tech = {
00248 .type = "H323",
00249 .description = tdesc,
00250 .capabilities = ((AST_FORMAT_MAX_AUDIO << 1) - 1),
00251 .properties = AST_CHAN_TP_WANTSJITTER | AST_CHAN_TP_CREATESJITTER,
00252 .requester = oh323_request,
00253 .send_digit_begin = oh323_digit_begin,
00254 .send_digit_end = oh323_digit_end,
00255 .call = oh323_call,
00256 .hangup = oh323_hangup,
00257 .answer = oh323_answer,
00258 .read = oh323_read,
00259 .write = oh323_write,
00260 .indicate = oh323_indicate,
00261 .fixup = oh323_fixup,
00262
00263 #if 0
00264 .bridge = ast_rtp_bridge,
00265 #endif
00266 };
00267
00268 static const char* redirectingreason2str(int redirectingreason)
00269 {
00270 switch (redirectingreason) {
00271 case 0:
00272 return "UNKNOWN";
00273 case 1:
00274 return "BUSY";
00275 case 2:
00276 return "NO_REPLY";
00277 case 0xF:
00278 return "UNCONDITIONAL";
00279 default:
00280 return "NOREDIRECT";
00281 }
00282 }
00283
00284 static void oh323_destroy_alias(struct oh323_alias *alias)
00285 {
00286 if (h323debug)
00287 ast_log(LOG_DEBUG, "Destroying alias '%s'\n", alias->name);
00288 free(alias);
00289 }
00290
00291 static void oh323_destroy_user(struct oh323_user *user)
00292 {
00293 if (h323debug)
00294 ast_log(LOG_DEBUG, "Destroying user '%s'\n", user->name);
00295 ast_free_ha(user->ha);
00296 free(user);
00297 }
00298
00299 static void oh323_destroy_peer(struct oh323_peer *peer)
00300 {
00301 if (h323debug)
00302 ast_log(LOG_DEBUG, "Destroying peer '%s'\n", peer->name);
00303 ast_free_ha(peer->ha);
00304 free(peer);
00305 }
00306
00307 static int oh323_simulate_dtmf_end(const void *data)
00308 {
00309 struct oh323_pvt *pvt = (struct oh323_pvt *)data;
00310
00311 if (pvt) {
00312 ast_mutex_lock(&pvt->lock);
00313
00314 while(pvt->owner && ast_channel_trylock(pvt->owner)) {
00315 ast_mutex_unlock(&pvt->lock);
00316 usleep(1);
00317 ast_mutex_lock(&pvt->lock);
00318 }
00319
00320 if (pvt->owner) {
00321 struct ast_frame f = {
00322 .frametype = AST_FRAME_DTMF_END,
00323 .subclass = pvt->curDTMF,
00324 .samples = 0,
00325 .src = "SIMULATE_DTMF_END",
00326 };
00327 ast_queue_frame(pvt->owner, &f);
00328 ast_channel_unlock(pvt->owner);
00329 }
00330
00331 pvt->DTMFsched = -1;
00332 ast_mutex_unlock(&pvt->lock);
00333 }
00334
00335 return 0;
00336 }
00337
00338
00339 static void __oh323_update_info(struct ast_channel *c, struct oh323_pvt *pvt)
00340 {
00341 if (c->nativeformats != pvt->nativeformats) {
00342 if (h323debug)
00343 ast_log(LOG_DEBUG, "Preparing %s for new native format\n", c->name);
00344 c->nativeformats = pvt->nativeformats;
00345 ast_set_read_format(c, c->readformat);
00346 ast_set_write_format(c, c->writeformat);
00347 }
00348 if (pvt->needhangup) {
00349 if (h323debug)
00350 ast_log(LOG_DEBUG, "Process pending hangup for %s\n", c->name);
00351 c->_softhangup |= AST_SOFTHANGUP_DEV;
00352 c->hangupcause = pvt->hangupcause;
00353 ast_queue_hangup(c);
00354 pvt->needhangup = 0;
00355 pvt->newstate = pvt->newcontrol = pvt->newdigit = pvt->DTMFsched = -1;
00356 }
00357 if (pvt->newstate >= 0) {
00358 ast_setstate(c, pvt->newstate);
00359 pvt->newstate = -1;
00360 }
00361 if (pvt->newcontrol >= 0) {
00362 ast_queue_control(c, pvt->newcontrol);
00363 pvt->newcontrol = -1;
00364 }
00365 if (pvt->newdigit >= 0) {
00366 struct ast_frame f = {
00367 .frametype = AST_FRAME_DTMF_END,
00368 .subclass = pvt->newdigit,
00369 .samples = pvt->newduration * 8,
00370 .len = pvt->newduration,
00371 .src = "UPDATE_INFO",
00372 };
00373 if (pvt->newdigit == ' ') {
00374 f.subclass = pvt->curDTMF;
00375 if (pvt->DTMFsched >= 0) {
00376 AST_SCHED_DEL(sched, pvt->DTMFsched);
00377 }
00378 } else {
00379 if (pvt->newduration) {
00380 f.frametype = AST_FRAME_DTMF_BEGIN;
00381 AST_SCHED_DEL(sched, pvt->DTMFsched);
00382 pvt->DTMFsched = ast_sched_add(sched, pvt->newduration, oh323_simulate_dtmf_end, pvt);
00383 if (h323debug)
00384 ast_log(LOG_DTMF, "Scheduled DTMF END simulation for %d ms, id=%d\n", pvt->newduration, pvt->DTMFsched);
00385 }
00386 pvt->curDTMF = pvt->newdigit;
00387 }
00388 ast_queue_frame(c, &f);
00389 pvt->newdigit = -1;
00390 }
00391 if (pvt->update_rtp_info > 0) {
00392 if (pvt->rtp) {
00393 ast_jb_configure(c, &global_jbconf);
00394 c->fds[0] = ast_rtp_fd(pvt->rtp);
00395 c->fds[1] = ast_rtcp_fd(pvt->rtp);
00396 ast_queue_frame(pvt->owner, &ast_null_frame);
00397 }
00398 pvt->update_rtp_info = -1;
00399 }
00400 }
00401
00402
00403 static void oh323_update_info(struct ast_channel *c)
00404 {
00405 struct oh323_pvt *pvt = c->tech_pvt;
00406
00407 if (pvt) {
00408 ast_mutex_lock(&pvt->lock);
00409 __oh323_update_info(c, pvt);
00410 ast_mutex_unlock(&pvt->lock);
00411 }
00412 }
00413
00414 static void cleanup_call_details(call_details_t *cd)
00415 {
00416 if (cd->call_token) {
00417 free(cd->call_token);
00418 cd->call_token = NULL;
00419 }
00420 if (cd->call_source_aliases) {
00421 free(cd->call_source_aliases);
00422 cd->call_source_aliases = NULL;
00423 }
00424 if (cd->call_dest_alias) {
00425 free(cd->call_dest_alias);
00426 cd->call_dest_alias = NULL;
00427 }
00428 if (cd->call_source_name) {
00429 free(cd->call_source_name);
00430 cd->call_source_name = NULL;
00431 }
00432 if (cd->call_source_e164) {
00433 free(cd->call_source_e164);
00434 cd->call_source_e164 = NULL;
00435 }
00436 if (cd->call_dest_e164) {
00437 free(cd->call_dest_e164);
00438 cd->call_dest_e164 = NULL;
00439 }
00440 if (cd->sourceIp) {
00441 free(cd->sourceIp);
00442 cd->sourceIp = NULL;
00443 }
00444 if (cd->redirect_number) {
00445 free(cd->redirect_number);
00446 cd->redirect_number = NULL;
00447 }
00448 }
00449
00450 static void __oh323_destroy(struct oh323_pvt *pvt)
00451 {
00452 struct oh323_pvt *cur, *prev = NULL;
00453
00454 AST_SCHED_DEL(sched, pvt->DTMFsched);
00455
00456 if (pvt->rtp) {
00457 ast_rtp_destroy(pvt->rtp);
00458 }
00459
00460
00461 if (pvt->vad) {
00462 ast_dsp_free(pvt->vad);
00463 }
00464 cleanup_call_details(&pvt->cd);
00465
00466
00467 if (pvt->owner) {
00468 ast_channel_lock(pvt->owner);
00469 if (h323debug)
00470 ast_log(LOG_DEBUG, "Detaching from %s\n", pvt->owner->name);
00471 pvt->owner->tech_pvt = NULL;
00472 ast_channel_unlock(pvt->owner);
00473 }
00474 cur = iflist;
00475 while(cur) {
00476 if (cur == pvt) {
00477 if (prev)
00478 prev->next = cur->next;
00479 else
00480 iflist = cur->next;
00481 break;
00482 }
00483 prev = cur;
00484 cur = cur->next;
00485 }
00486 if (!cur) {
00487 ast_log(LOG_WARNING, "%p is not in list?!?! \n", cur);
00488 } else {
00489 ast_mutex_unlock(&pvt->lock);
00490 ast_mutex_destroy(&pvt->lock);
00491 free(pvt);
00492 }
00493 }
00494
00495 static void oh323_destroy(struct oh323_pvt *pvt)
00496 {
00497 if (h323debug) {
00498 ast_log(LOG_DEBUG, "Destroying channel %s\n", (pvt->owner ? pvt->owner->name : "<unknown>"));
00499 }
00500 ast_mutex_lock(&iflock);
00501 ast_mutex_lock(&pvt->lock);
00502 __oh323_destroy(pvt);
00503 ast_mutex_unlock(&iflock);
00504 }
00505
00506 static int oh323_digit_begin(struct ast_channel *c, char digit)
00507 {
00508 struct oh323_pvt *pvt = (struct oh323_pvt *) c->tech_pvt;
00509 char *token;
00510
00511 if (!pvt) {
00512 ast_log(LOG_ERROR, "No private structure?! This is bad\n");
00513 return -1;
00514 }
00515 ast_mutex_lock(&pvt->lock);
00516 if (pvt->rtp && (pvt->options.dtmfmode & H323_DTMF_RFC2833) && (pvt->dtmf_pt > 0)) {
00517
00518 if (h323debug) {
00519 ast_log(LOG_DTMF, "Begin sending out-of-band digit %c on %s\n", digit, c->name);
00520 }
00521 ast_rtp_senddigit_begin(pvt->rtp, digit);
00522 ast_mutex_unlock(&pvt->lock);
00523 } else if (pvt->txDtmfDigit != digit) {
00524
00525 if (h323debug) {
00526 ast_log(LOG_DTMF, "Begin sending inband digit %c on %s\n", digit, c->name);
00527 }
00528 pvt->txDtmfDigit = digit;
00529 token = pvt->cd.call_token ? strdup(pvt->cd.call_token) : NULL;
00530 ast_mutex_unlock(&pvt->lock);
00531 h323_send_tone(token, digit);
00532 if (token) {
00533 free(token);
00534 }
00535 } else
00536 ast_mutex_unlock(&pvt->lock);
00537 oh323_update_info(c);
00538 return 0;
00539 }
00540
00541
00542
00543
00544
00545 static int oh323_digit_end(struct ast_channel *c, char digit, unsigned int duration)
00546 {
00547 struct oh323_pvt *pvt = (struct oh323_pvt *) c->tech_pvt;
00548 char *token;
00549
00550 if (!pvt) {
00551 ast_log(LOG_ERROR, "No private structure?! This is bad\n");
00552 return -1;
00553 }
00554 ast_mutex_lock(&pvt->lock);
00555 if (pvt->rtp && (pvt->options.dtmfmode & H323_DTMF_RFC2833) && (pvt->dtmf_pt > 0)) {
00556
00557 if (h323debug) {
00558 ast_log(LOG_DTMF, "End sending out-of-band digit %c on %s, duration %d\n", digit, c->name, duration);
00559 }
00560 ast_rtp_senddigit_end(pvt->rtp, digit);
00561 ast_mutex_unlock(&pvt->lock);
00562 } else {
00563
00564 if (h323debug) {
00565 ast_log(LOG_DTMF, "End sending inband digit %c on %s, duration %d\n", digit, c->name, duration);
00566 }
00567 pvt->txDtmfDigit = ' ';
00568 token = pvt->cd.call_token ? strdup(pvt->cd.call_token) : NULL;
00569 ast_mutex_unlock(&pvt->lock);
00570 h323_send_tone(token, ' ');
00571 if (token) {
00572 free(token);
00573 }
00574 }
00575 oh323_update_info(c);
00576 return 0;
00577 }
00578
00579
00580
00581
00582
00583
00584 static int oh323_call(struct ast_channel *c, char *dest, int timeout)
00585 {
00586 int res = 0;
00587 struct oh323_pvt *pvt = (struct oh323_pvt *)c->tech_pvt;
00588 const char *addr;
00589 char called_addr[1024];
00590
00591 if (h323debug) {
00592 ast_log(LOG_DEBUG, "Calling to %s on %s\n", dest, c->name);
00593 }
00594 if ((c->_state != AST_STATE_DOWN) && (c->_state != AST_STATE_RESERVED)) {
00595 ast_log(LOG_WARNING, "Line is already in use (%s)\n", c->name);
00596 return -1;
00597 }
00598 ast_mutex_lock(&pvt->lock);
00599 if (!gatekeeper_disable) {
00600 if (ast_strlen_zero(pvt->exten)) {
00601 ast_copy_string(called_addr, dest, sizeof(called_addr));
00602 } else {
00603 snprintf(called_addr, sizeof(called_addr), "%s@%s", pvt->exten, dest);
00604 }
00605 } else {
00606 res = htons(pvt->sa.sin_port);
00607 addr = ast_inet_ntoa(pvt->sa.sin_addr);
00608 if (ast_strlen_zero(pvt->exten)) {
00609 snprintf(called_addr, sizeof(called_addr), "%s:%d", addr, res);
00610 } else {
00611 snprintf(called_addr, sizeof(called_addr), "%s@%s:%d", pvt->exten, addr, res);
00612 }
00613 }
00614
00615 called_addr[sizeof(called_addr) - 1] = '\0';
00616
00617 if (c->cid.cid_num)
00618 ast_copy_string(pvt->options.cid_num, c->cid.cid_num, sizeof(pvt->options.cid_num));
00619
00620 if (c->cid.cid_name)
00621 ast_copy_string(pvt->options.cid_name, c->cid.cid_name, sizeof(pvt->options.cid_name));
00622
00623 if (c->cid.cid_rdnis) {
00624 ast_copy_string(pvt->options.cid_rdnis, c->cid.cid_rdnis, sizeof(pvt->options.cid_rdnis));
00625 }
00626
00627 pvt->options.presentation = c->cid.cid_pres;
00628 pvt->options.type_of_number = c->cid.cid_ton;
00629
00630 if ((addr = pbx_builtin_getvar_helper(c, "PRIREDIRECTREASON"))) {
00631 if (!strcasecmp(addr, "UNKNOWN"))
00632 pvt->options.redirect_reason = 0;
00633 else if (!strcasecmp(addr, "BUSY"))
00634 pvt->options.redirect_reason = 1;
00635 else if (!strcasecmp(addr, "NO_REPLY"))
00636 pvt->options.redirect_reason = 2;
00637 else if (!strcasecmp(addr, "UNCONDITIONAL"))
00638 pvt->options.redirect_reason = 15;
00639 else
00640 pvt->options.redirect_reason = -1;
00641 } else
00642 pvt->options.redirect_reason = -1;
00643
00644 pvt->options.transfer_capability = c->transfercapability;
00645
00646
00647 pvt->outgoing = 1;
00648
00649 if (option_verbose > 2)
00650 ast_verbose(VERBOSE_PREFIX_3 "Requested transfer capability: 0x%.2x - %s\n", c->transfercapability, ast_transfercapability2str(c->transfercapability));
00651 if (h323debug)
00652 ast_log(LOG_DEBUG, "Placing outgoing call to %s, %d\n", called_addr, pvt->options.dtmfcodec);
00653 ast_mutex_unlock(&pvt->lock);
00654 res = h323_make_call(called_addr, &(pvt->cd), &pvt->options);
00655 if (res) {
00656 ast_log(LOG_NOTICE, "h323_make_call failed(%s)\n", c->name);
00657 return -1;
00658 }
00659 oh323_update_info(c);
00660 return 0;
00661 }
00662
00663 static int oh323_answer(struct ast_channel *c)
00664 {
00665 int res;
00666 struct oh323_pvt *pvt = (struct oh323_pvt *) c->tech_pvt;
00667 char *token;
00668
00669 if (h323debug)
00670 ast_log(LOG_DEBUG, "Answering on %s\n", c->name);
00671
00672 ast_mutex_lock(&pvt->lock);
00673 token = pvt->cd.call_token ? strdup(pvt->cd.call_token) : NULL;
00674 ast_mutex_unlock(&pvt->lock);
00675 res = h323_answering_call(token, 0);
00676 if (token)
00677 free(token);
00678
00679 oh323_update_info(c);
00680 if (c->_state != AST_STATE_UP) {
00681 ast_setstate(c, AST_STATE_UP);
00682 }
00683 return res;
00684 }
00685
00686 static int oh323_hangup(struct ast_channel *c)
00687 {
00688 struct oh323_pvt *pvt = (struct oh323_pvt *) c->tech_pvt;
00689 int q931cause = AST_CAUSE_NORMAL_CLEARING;
00690 char *call_token;
00691
00692
00693 if (h323debug)
00694 ast_log(LOG_DEBUG, "Hanging up and scheduling destroy of call %s\n", c->name);
00695
00696 if (!c->tech_pvt) {
00697 ast_log(LOG_WARNING, "Asked to hangup channel not connected\n");
00698 return 0;
00699 }
00700 ast_mutex_lock(&pvt->lock);
00701
00702 if (pvt->owner != c) {
00703 ast_log(LOG_WARNING, "Huh? We aren't the owner?\n");
00704 ast_mutex_unlock(&pvt->lock);
00705 return 0;
00706 }
00707
00708 pvt->owner = NULL;
00709 c->tech_pvt = NULL;
00710
00711 if (c->hangupcause) {
00712 q931cause = c->hangupcause;
00713 } else {
00714 const char *cause = pbx_builtin_getvar_helper(c, "DIALSTATUS");
00715 if (cause) {
00716 if (!strcmp(cause, "CONGESTION")) {
00717 q931cause = AST_CAUSE_NORMAL_CIRCUIT_CONGESTION;
00718 } else if (!strcmp(cause, "BUSY")) {
00719 q931cause = AST_CAUSE_USER_BUSY;
00720 } else if (!strcmp(cause, "CHANISUNVAIL")) {
00721 q931cause = AST_CAUSE_REQUESTED_CHAN_UNAVAIL;
00722 } else if (!strcmp(cause, "NOANSWER")) {
00723 q931cause = AST_CAUSE_NO_ANSWER;
00724 } else if (!strcmp(cause, "CANCEL")) {
00725 q931cause = AST_CAUSE_CALL_REJECTED;
00726 }
00727 }
00728 }
00729
00730
00731 if (!pvt->alreadygone && !pvt->hangupcause) {
00732 call_token = pvt->cd.call_token ? strdup(pvt->cd.call_token) : NULL;
00733 if (call_token) {
00734
00735 ast_mutex_unlock(&pvt->lock);
00736 if (h323_clear_call(call_token, q931cause)) {
00737 ast_log(LOG_WARNING, "ClearCall failed.\n");
00738 }
00739 free(call_token);
00740 ast_mutex_lock(&pvt->lock);
00741 }
00742 }
00743 pvt->needdestroy = 1;
00744 ast_mutex_unlock(&pvt->lock);
00745
00746
00747 ast_module_unref(ast_module_info->self);
00748
00749 return 0;
00750 }
00751
00752 static struct ast_frame *oh323_rtp_read(struct oh323_pvt *pvt)
00753 {
00754
00755 struct ast_frame *f;
00756
00757
00758 if (pvt->options.nat) {
00759 ast_rtp_setnat(pvt->rtp, pvt->options.nat);
00760 pvt->options.nat = 0;
00761 }
00762
00763 f = ast_rtp_read(pvt->rtp);
00764
00765 if (f && (f->frametype == AST_FRAME_DTMF) && !(pvt->options.dtmfmode & H323_DTMF_RFC2833)) {
00766 return &ast_null_frame;
00767 }
00768 if (pvt->owner) {
00769
00770 if (f->frametype == AST_FRAME_VOICE) {
00771 if (f->subclass != pvt->owner->nativeformats) {
00772
00773 if (ast_channel_trylock(pvt->owner)) {
00774 ast_log(LOG_NOTICE, "Format changed but channel is locked. Ignoring frame...\n");
00775 return &ast_null_frame;
00776 }
00777 if (h323debug)
00778 ast_log(LOG_DEBUG, "Oooh, format changed to %d\n", f->subclass);
00779 pvt->owner->nativeformats = f->subclass;
00780 pvt->nativeformats = f->subclass;
00781 ast_set_read_format(pvt->owner, pvt->owner->readformat);
00782 ast_set_write_format(pvt->owner, pvt->owner->writeformat);
00783 ast_channel_unlock(pvt->owner);
00784 }
00785
00786 if ((pvt->options.dtmfmode & H323_DTMF_INBAND) && pvt->vad) {
00787 if ((pvt->nativeformats & (AST_FORMAT_SLINEAR | AST_FORMAT_ALAW | AST_FORMAT_ULAW))) {
00788 if (!ast_channel_trylock(pvt->owner)) {
00789 f = ast_dsp_process(pvt->owner, pvt->vad, f);
00790 ast_channel_unlock(pvt->owner);
00791 }
00792 else
00793 ast_log(LOG_NOTICE, "Unable to process inband DTMF while channel is locked\n");
00794 } else if (pvt->nativeformats && !pvt->noInbandDtmf) {
00795 ast_log(LOG_NOTICE, "Inband DTMF is not supported on codec %s. Use RFC2833\n", ast_getformatname(f->subclass));
00796 pvt->noInbandDtmf = 1;
00797 }
00798 if (f &&(f->frametype == AST_FRAME_DTMF)) {
00799 if (h323debug)
00800 ast_log(LOG_DTMF, "Received in-band digit %c.\n", f->subclass);
00801 }
00802 }
00803 }
00804 }
00805 return f;
00806 }
00807
00808 static struct ast_frame *oh323_read(struct ast_channel *c)
00809 {
00810 struct ast_frame *fr;
00811 struct oh323_pvt *pvt = (struct oh323_pvt *)c->tech_pvt;
00812 ast_mutex_lock(&pvt->lock);
00813 __oh323_update_info(c, pvt);
00814 switch(c->fdno) {
00815 case 0:
00816 fr = oh323_rtp_read(pvt);
00817 break;
00818 case 1:
00819 if (pvt->rtp)
00820 fr = ast_rtcp_read(pvt->rtp);
00821 else
00822 fr = &ast_null_frame;
00823 break;
00824 default:
00825 ast_log(LOG_ERROR, "Unable to handle fd %d on channel %s\n", c->fdno, c->name);
00826 fr = &ast_null_frame;
00827 break;
00828 }
00829 ast_mutex_unlock(&pvt->lock);
00830 return fr;
00831 }
00832
00833 static int oh323_write(struct ast_channel *c, struct ast_frame *frame)
00834 {
00835 struct oh323_pvt *pvt = (struct oh323_pvt *) c->tech_pvt;
00836 int res = 0;
00837 if (frame->frametype != AST_FRAME_VOICE) {
00838 if (frame->frametype == AST_FRAME_IMAGE) {
00839 return 0;
00840 } else {
00841 ast_log(LOG_WARNING, "Can't send %d type frames with H323 write\n"<