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