From 6d24d82f63425210f28b104b68324475163fd542 Mon Sep 17 00:00:00 2001 From: kpfleming Date: Fri, 11 Jul 2008 22:12:26 +0000 Subject: a whole pile of Zaptel/DAHDI compatibility work, with lots more to come... this tree is not yet ready for users to be easily upgrading or switching, but it needs to be :-) git-svn-id: http://svn.digium.com/svn/asterisk/branches/1.4@130298 f38db490-d61c-443f-a65b-d21fe96a405b --- channels/chan_dahdi.c | 181 ++++++++++++++++++++++++++++++-------------------- channels/chan_iax2.c | 6 +- 2 files changed, 112 insertions(+), 75 deletions(-) (limited to 'channels') diff --git a/channels/chan_dahdi.c b/channels/chan_dahdi.c index f74cd3169..73d528c2a 100644 --- a/channels/chan_dahdi.c +++ b/channels/chan_dahdi.c @@ -116,10 +116,6 @@ static struct ast_jb_conf default_jbconf = }; static struct ast_jb_conf global_jbconf; -#if !defined(DAHDI_SIG_EM_E1) || (defined(HAVE_PRI) && !defined(DAHDI_SIG_HARDHDLC)) -#error "Your DAHDI is too old. Please update" -#endif - #ifndef DAHDI_TONEDETECT /* Work around older code with no tone detect */ #define DAHDI_EVENT_DTMFDOWN 0 @@ -707,6 +703,29 @@ static const struct ast_channel_tech dahdi_tech = { .func_channel_read = dahdi_func_read, }; +static const struct ast_channel_tech zap_tech = { + .type = "Zap", + .description = tdesc, + .capabilities = AST_FORMAT_SLINEAR | AST_FORMAT_ULAW | AST_FORMAT_ALAW, + .requester = dahdi_request, + .send_digit_begin = dahdi_digit_begin, + .send_digit_end = dahdi_digit_end, + .send_text = dahdi_sendtext, + .call = dahdi_call, + .hangup = dahdi_hangup, + .answer = dahdi_answer, + .read = dahdi_read, + .write = dahdi_write, + .bridge = dahdi_bridge, + .exception = dahdi_exception, + .indicate = dahdi_indicate, + .fixup = dahdi_fixup, + .setoption = dahdi_setoption, + .func_channel_read = dahdi_func_read, +}; + +static const struct ast_channel_tech *chan_tech; + #ifdef HAVE_PRI #define GET_CHANNEL(p) ((p)->bearer ? (p)->bearer->channel : p->channel) #else @@ -3813,7 +3832,7 @@ static struct ast_frame *dahdi_handle_event(struct ast_channel *ast) do { const char *alarm_str = alarm2str(res); - /* hack alert! DAHDI 1.4 now exposes FXO battery as an alarm, but asterisk 1.4 + /* hack alert! Zaptel 1.4 and DAHDI expose FXO battery as an alarm, but Asterisk 1.4 * doesn't know what to do with it. Don't confuse users with log messages. */ if (!strcasecmp(alarm_str, "No Alarm") || !strcasecmp(alarm_str, "Unknown Alarm")) { p->unknown_alarm = 1; @@ -5212,6 +5231,8 @@ static struct ast_channel *dahdi_new(struct dahdi_pvt *i, int state, int startpb int features; char *b2 = NULL; DAHDI_PARAMS ps; + char chanprefix[strlen(dahdi_chan_name) + 4]; + if (i->subs[index].owner) { ast_log(LOG_WARNING, "Channel %d already has a %s call\n", i->channel,subnames[index]); return NULL; @@ -5235,12 +5256,14 @@ static struct ast_channel *dahdi_new(struct dahdi_pvt *i, int state, int startpb } y++; } while (x < 3); - tmp = ast_channel_alloc(0, state, i->cid_num, i->cid_name, i->accountcode, i->exten, i->context, i->amaflags, "DAHDI/%s", b2); + strcpy(chanprefix, dahdi_chan_name); + strcat(chanprefix, "/%s"); + tmp = ast_channel_alloc(0, state, i->cid_num, i->cid_name, i->accountcode, i->exten, i->context, i->amaflags, chanprefix, b2); if (b2) /*!> b2 can be freed now, it's been copied into the channel structure */ free(b2); if (!tmp) return NULL; - tmp->tech = &dahdi_tech; + tmp->tech = chan_tech; ps.channo = i->channel; res = ioctl(i->subs[SUB_REAL].dfd, DAHDI_GET_PARAMS, &ps); if (res) { @@ -5950,8 +5973,8 @@ static void *ss_thread(void *data) if (option_verbose > 2) ast_verbose(VERBOSE_PREFIX_3 "Enabled DND on channel %d\n", p->channel); manager_event(EVENT_FLAG_SYSTEM, "DNDState", - "Channel: DAHDI/%d\r\n" - "Status: enabled\r\n", p->channel); + "Channel: %s/%d\r\n" + "Status: enabled\r\n", dahdi_chan_name, p->channel); res = tone_zone_play_tone(p->subs[index].dfd, DAHDI_TONE_DIALRECALL); p->dnd = 1; getforward = 0; @@ -5962,8 +5985,8 @@ static void *ss_thread(void *data) if (option_verbose > 2) ast_verbose(VERBOSE_PREFIX_3 "Disabled DND on channel %d\n", p->channel); manager_event(EVENT_FLAG_SYSTEM, "DNDState", - "Channel: DAHDI/%d\r\n" - "Status: disabled\r\n", p->channel); + "Channel: %s/%d\r\n" + "Status: disabled\r\n", dahdi_chan_name, p->channel); res = tone_zone_play_tone(p->subs[index].dfd, DAHDI_TONE_DIALRECALL); p->dnd = 0; getforward = 0; @@ -6028,8 +6051,8 @@ static void *ss_thread(void *data) if (nbridge && ast_bridged_channel(nbridge)) pbridge = ast_bridged_channel(nbridge)->tech_pvt; if (nbridge && pbridge && - (nbridge->tech == &dahdi_tech) && - (ast_bridged_channel(nbridge)->tech == &dahdi_tech) && + (nbridge->tech == chan_tech) && + (ast_bridged_channel(nbridge)->tech == chan_tech) && ISTRUNK(pbridge)) { int func = DAHDI_FLASH; /* Clear out the dial buffer */ @@ -6704,7 +6727,7 @@ static int handle_init_event(struct dahdi_pvt *i, int event) if (!i->unknown_alarm) { ast_log(LOG_NOTICE, "Alarm cleared on channel %d\n", i->channel); manager_event(EVENT_FLAG_SYSTEM, "AlarmClear", - "Channel: %d\r\n", i->channel); + "Channel: %d\r\n", i->channel); } else { i->unknown_alarm = 0; } @@ -8105,15 +8128,13 @@ static int pri_fixup_principle(struct dahdi_pri *pri, int principle, q931_call * new->owner = old->owner; old->owner = NULL; if (new->owner) { - ast_string_field_build(new->owner, name, - "DAHDI/%d:%d-%d", pri->trunkgroup, - new->channel, 1); + ast_string_field_build(new->owner, name, "%s/%d:%d-%d", dahdi_chan_name, pri->trunkgroup, new->channel, 1); new->owner->tech_pvt = new; new->owner->fds[0] = new->subs[SUB_REAL].dfd; new->subs[SUB_REAL].owner = old->subs[SUB_REAL].owner; old->subs[SUB_REAL].owner = NULL; } else - ast_log(LOG_WARNING, "Whoa, there's no owner, and we're having to fix up channel %d to channel %d\n", old->channel, new->channel); + ast_log(LOG_WARNING, "Whoa, there's no owner, and we're having to fix up channel %d to channel %d\n", old->channel, new->channel); new->call = old->call; old->call = NULL; @@ -8471,7 +8492,7 @@ static void *pri_dchannel(void *vpri) if (ast_tvdiff_ms(ast_tvnow(), lastidle) > 1000) { /* Don't create a new idle call more than once per second */ snprintf(idlen, sizeof(idlen), "%d/%s", pri->pvts[nextidle]->channel, pri->idledial); - idle = dahdi_request("DAHDI", AST_FORMAT_ULAW, idlen, &cause); + idle = dahdi_request(dahdi_chan_name, AST_FORMAT_ULAW, idlen, &cause); if (idle) { pri->pvts[nextidle]->isidlecall = 1; if (ast_pthread_create_background(&p, NULL, do_idle_thread, idle)) { @@ -9894,6 +9915,13 @@ static struct ast_cli_entry dahdi_pri_cli[] = { #endif /* HAVE_PRI */ +/* Wrappers for astman operations to use proper channel name prefix */ + +#define local_astman_ack(s, m, msg) do { if (chan_tech == &dahdi_tech) astman_send_ack(s, m, "DAHDI" msg); else astman_send_ack(s, m, "Zap" msg); } while (0) +#define local_astman_header(m, hdr) astman_get_header(m, (chan_tech == &dahdi_tech) ? "DAHDI" hdr : "Zap" hdr) +#define local_astman_register(a, b, c, d) do { if (chan_tech == &dahdi_tech) ast_manager_register("DAHDI" a, b, c, d); else ast_manager_register("Zap" a, b, c, d); } while (0) +#define local_astman_unregister(a) do { if (chan_tech == &dahdi_tech) ast_manager_unregister("DAHDI" a); else ast_manager_unregister("Zap" a); } while (0) + static int dahdi_destroy_channel(int fd, int argc, char **argv) { int channel; @@ -9910,17 +9938,17 @@ static int setup_dahdi(int reload); static int dahdi_restart(void) { if (option_verbose > 0) - ast_verbose(VERBOSE_PREFIX_1 "Destroying channels and reloading DAHDI configuration.\n"); + ast_verbose(VERBOSE_PREFIX_1 "Destroying channels and reloading %s configuration.\n", dahdi_chan_name); while (iflist) { if (option_debug) - ast_log(LOG_DEBUG, "Destroying DAHDI channel no. %d\n", iflist->channel); + ast_log(LOG_DEBUG, "Destroying %s channel no. %d\n", dahdi_chan_name, iflist->channel); /* Also updates iflist: */ destroy_channel(NULL, iflist, 1); } if (option_debug) ast_log(LOG_DEBUG, "Channels destroyed. Now re-reading config.\n"); if (setup_dahdi(0) != 0) { - ast_log(LOG_WARNING, "Reload channels from dahdi config failed!\n"); + ast_log(LOG_WARNING, "Reload channels from %s config failed!\n", dahdi_chan_name); return 1; } return 0; @@ -9940,10 +9968,10 @@ static int dahdi_restart_cmd(int fd, int argc, char **argv) static int action_dahdirestart(struct mansession *s, const struct message *m) { if (dahdi_restart() != 0) { - astman_send_error(s, m, "Failed rereading DAHDI configuration"); + astman_send_error(s, m, "Failed to restart chan_dahdi"); return 1; } - astman_send_ack(s, m, "DAHDIRestart: Success"); + local_astman_ack(s, m, "Restart: Success"); return 0; } @@ -10181,15 +10209,18 @@ static int dahdi_show_status(int fd, int argc, char *argv[]) { DAHDI_SPANINFO s; #ifdef HAVE_ZAPTEL - ctl = open("/dev/zap/ctl", O_RDWR); + if ((ctl = open("/dev/zap/ctl", O_RDWR)) < 0) { + ast_log(LOG_WARNING, "Unable to open /dev/zap/ctl: %s\n", strerror(errno)); + ast_cli(fd, "No Zaptel interface found.\n"); + return RESULT_FAILURE; + } #else - ctl = open("/dev/dahdi/ctl", O_RDWR); -#endif - if (ctl < 0) { + if ((ctl = open("/dev/dahdi/ctl", O_RDWR)) < 0) { ast_log(LOG_WARNING, "Unable to open /dev/dahdi/ctl: %s\n", strerror(errno)); ast_cli(fd, "No DAHDI interface found.\n"); return RESULT_FAILURE; } +#endif ast_cli(fd, FORMAT2, "Description", "Alarms", "IRQ", "bpviol", "CRC4"); for (span = 1; span < DAHDI_MAX_SPANS; ++span) { @@ -10347,7 +10378,7 @@ static struct dahdi_pvt *find_channel(int channel) static int action_dahdidndon(struct mansession *s, const struct message *m) { struct dahdi_pvt *p = NULL; - const char *channel = astman_get_header(m, "DAHDIChannel"); + const char *channel = local_astman_header(m, "Channel"); if (ast_strlen_zero(channel)) { astman_send_error(s, m, "No channel specified"); @@ -10366,7 +10397,7 @@ static int action_dahdidndon(struct mansession *s, const struct message *m) static int action_dahdidndoff(struct mansession *s, const struct message *m) { struct dahdi_pvt *p = NULL; - const char *channel = astman_get_header(m, "DAHDIChannel"); + const char *channel = local_astman_header(m, "Channel"); if (ast_strlen_zero(channel)) { astman_send_error(s, m, "No channel specified"); @@ -10385,7 +10416,7 @@ static int action_dahdidndoff(struct mansession *s, const struct message *m) static int action_transfer(struct mansession *s, const struct message *m) { struct dahdi_pvt *p = NULL; - const char *channel = astman_get_header(m, "DAHDIChannel"); + const char *channel = local_astman_header(m, "Channel"); if (ast_strlen_zero(channel)) { astman_send_error(s, m, "No channel specified"); @@ -10397,14 +10428,14 @@ static int action_transfer(struct mansession *s, const struct message *m) return 0; } dahdi_fake_event(p,TRANSFER); - astman_send_ack(s, m, "DAHDITransfer"); + local_astman_ack(s, m, "Transfer"); return 0; } static int action_transferhangup(struct mansession *s, const struct message *m) { struct dahdi_pvt *p = NULL; - const char *channel = astman_get_header(m, "DAHDIChannel"); + const char *channel = local_astman_header(m, "Channel"); if (ast_strlen_zero(channel)) { astman_send_error(s, m, "No channel specified"); @@ -10416,14 +10447,14 @@ static int action_transferhangup(struct mansession *s, const struct message *m) return 0; } dahdi_fake_event(p,HANGUP); - astman_send_ack(s, m, "DAHDIHangup"); + local_astman_ack(s, m, "Hangup"); return 0; } static int action_dahdidialoffhook(struct mansession *s, const struct message *m) { struct dahdi_pvt *p = NULL; - const char *channel = astman_get_header(m, "DAHDIChannel"); + const char *channel = local_astman_header(m, "Channel"); const char *number = astman_get_header(m, "Number"); int i; @@ -10448,7 +10479,7 @@ static int action_dahdidialoffhook(struct mansession *s, const struct message *m struct ast_frame f = { AST_FRAME_DTMF, number[i] }; dahdi_queue_frame(p, &f, NULL); } - astman_send_ack(s, m, "DAHDIDialOffhook"); + local_astman_ack(s, m, "DialOffhook"); return 0; } @@ -10458,7 +10489,7 @@ static int action_dahdishowchannels(struct mansession *s, const struct message * const char *id = astman_get_header(m, "ActionID"); char idText[256] = ""; - astman_send_ack(s, m, "DAHDI channel status will follow"); + local_astman_ack(s, m, " channel status will follow"); if (!ast_strlen_zero(id)) snprintf(idText, sizeof(idText) - 1, "ActionID: %s\r\n", id); @@ -10469,17 +10500,18 @@ static int action_dahdishowchannels(struct mansession *s, const struct message * if (tmp->channel > 0) { int alarm = get_alarms(tmp); astman_append(s, - "Event: DAHDIShowChannels\r\n" - "Channel: %d\r\n" - "Signalling: %s\r\n" - "Context: %s\r\n" - "DND: %s\r\n" - "Alarm: %s\r\n" - "%s" - "\r\n", - tmp->channel, sig2str(tmp->sig), tmp->context, - tmp->dnd ? "Enabled" : "Disabled", - alarm2str(alarm), idText); + "Event: %sShowChannels\r\n" + "Channel: %d\r\n" + "Signalling: %s\r\n" + "Context: %s\r\n" + "DND: %s\r\n" + "Alarm: %s\r\n" + "%s" + "\r\n", + dahdi_chan_name, + tmp->channel, sig2str(tmp->sig), tmp->context, + tmp->dnd ? "Enabled" : "Disabled", + alarm2str(alarm), idText); } tmp = tmp->next; @@ -10488,10 +10520,11 @@ static int action_dahdishowchannels(struct mansession *s, const struct message * ast_mutex_unlock(&iflock); astman_append(s, - "Event: DAHDIShowChannelsComplete\r\n" - "%s" - "\r\n", - idText); + "Event: %sShowChannelsComplete\r\n" + "%s" + "\r\n", + dahdi_chan_name, + idText); return 0; } @@ -10510,14 +10543,14 @@ static int __unload_module(void) ast_unregister_application(dahdi_send_keypad_facility_app); #endif ast_cli_unregister_multiple(dahdi_cli, sizeof(dahdi_cli) / sizeof(struct ast_cli_entry)); - ast_manager_unregister( "DAHDIDialOffhook" ); - ast_manager_unregister( "DAHDIHangup" ); - ast_manager_unregister( "DAHDITransfer" ); - ast_manager_unregister( "DAHDIDNDoff" ); - ast_manager_unregister( "DAHDIDNDon" ); - ast_manager_unregister("DAHDIShowChannels"); - ast_manager_unregister("DAHDIRestart"); - ast_channel_unregister(&dahdi_tech); + local_astman_unregister("DialOffhook"); + local_astman_unregister("Hangup"); + local_astman_unregister("Transfer"); + local_astman_unregister("DNDoff"); + local_astman_unregister("DNDon"); + local_astman_unregister("ShowChannels"); + local_astman_unregister("Restart"); + ast_channel_unregister(chan_tech); ast_mutex_lock(&iflock); /* Hangup all interfaces if they have an owner */ p = iflist; @@ -11506,12 +11539,16 @@ static int load_module(void) ast_register_application(dahdi_send_keypad_facility_app, dahdi_send_keypad_facility_exec, dahdi_send_keypad_facility_synopsis, dahdi_send_keypad_facility_descrip); #endif - res = setup_dahdi(0); - /* Make sure we can register our DAHDI channel type */ - if (res) + if ((res = setup_dahdi(0))) { return AST_MODULE_LOAD_DECLINE; - if (ast_channel_register(&dahdi_tech)) { - ast_log(LOG_ERROR, "Unable to register channel class 'DAHDI'\n"); + } + if (!strcmp(dahdi_chan_name, "DAHDI")) { + chan_tech = &dahdi_tech; + } else { + chan_tech = &zap_tech; + } + if (ast_channel_register(chan_tech)) { + ast_log(LOG_ERROR, "Unable to register channel class '%s'\n", chan_tech->type); __unload_module(); return -1; } @@ -11523,13 +11560,13 @@ static int load_module(void) ast_cli_register_multiple(dahdi_cli, sizeof(dahdi_cli) / sizeof(struct ast_cli_entry)); memset(round_robin, 0, sizeof(round_robin)); - ast_manager_register("DAHDITransfer", 0, action_transfer, "Transfer DAHDI Channel" ); - ast_manager_register("DAHDIHangup", 0, action_transferhangup, "Hangup DAHDI Channel" ); - ast_manager_register("DAHDIDialOffhook", 0, action_dahdidialoffhook, "Dial over DAHDI channel while offhook" ); - ast_manager_register("DAHDIDNDon", 0, action_dahdidndon, "Toggle DAHDI channel Do Not Disturb status ON" ); - ast_manager_register("DAHDIDNDoff", 0, action_dahdidndoff, "Toggle DAHDI channel Do Not Disturb status OFF" ); - ast_manager_register("DAHDIShowChannels", 0, action_dahdishowchannels, "Show status DAHDI channels"); - ast_manager_register("DAHDIRestart", 0, action_dahdirestart, "Fully Restart DAHDI channels (terminates calls)"); + local_astman_register("Transfer", 0, action_transfer, "Transfer Channel"); + local_astman_register("Hangup", 0, action_transferhangup, "Hangup Channel"); + local_astman_register("DialOffhook", 0, action_dahdidialoffhook, "Dial over channel while offhook"); + local_astman_register("DNDon", 0, action_dahdidndon, "Toggle channel Do Not Disturb status ON"); + local_astman_register("DNDoff", 0, action_dahdidndoff, "Toggle channel Do Not Disturb status OFF"); + local_astman_register("ShowChannels", 0, action_dahdishowchannels, "Show status channels"); + local_astman_register("Restart", 0, action_dahdirestart, "Fully Restart channels (terminates calls)"); return res; } diff --git a/channels/chan_iax2.c b/channels/chan_iax2.c index a6f8e9824..eaa64e419 100644 --- a/channels/chan_iax2.c +++ b/channels/chan_iax2.c @@ -6580,7 +6580,7 @@ static int timing_read(int *id, int fd, short events, void *cbdata) #ifdef DAHDI_TIMERACK /* Great, this is a timing interface, just call the ioctl */ if (ioctl(fd, DAHDI_TIMERACK, &x)) { - ast_log(LOG_WARNING, "Unable to acknowledge zap timer. IAX trunking will fail!\n"); + ast_log(LOG_WARNING, "Unable to acknowledge timer. IAX trunking will fail!\n"); usleep(1); return -1; } @@ -9408,7 +9408,7 @@ static struct iax2_peer *build_peer(const char *name, struct ast_variable *v, st } else if (!strcasecmp(v->name, "trunk")) { ast_set2_flag(peer, ast_true(v->value), IAX_TRUNK); if (ast_test_flag(peer, IAX_TRUNK) && (timingfd < 0)) { - ast_log(LOG_WARNING, "Unable to support trunking on peer '%s' without zaptel timing\n", peer->name); + ast_log(LOG_WARNING, "Unable to support trunking on peer '%s' without timing\n", peer->name); ast_clear_flag(peer, IAX_TRUNK); } } else if (!strcasecmp(v->name, "auth")) { @@ -9666,7 +9666,7 @@ static struct iax2_user *build_user(const char *name, struct ast_variable *v, st } else if (!strcasecmp(v->name, "trunk")) { ast_set2_flag(user, ast_true(v->value), IAX_TRUNK); if (ast_test_flag(user, IAX_TRUNK) && (timingfd < 0)) { - ast_log(LOG_WARNING, "Unable to support trunking on user '%s' without zaptel timing\n", user->name); + ast_log(LOG_WARNING, "Unable to support trunking on user '%s' without timing\n", user->name); ast_clear_flag(user, IAX_TRUNK); } } else if (!strcasecmp(v->name, "auth")) { -- cgit v1.2.3