diff --git a/channels/chan_dahdi.c b/channels/chan_dahdi.c index 38290b0d75..55a0090504 100644 --- a/channels/chan_dahdi.c +++ b/channels/chan_dahdi.c @@ -177,6 +177,35 @@ This application will Accept the R2 call either with charge or no charge. + + + Set or get the polarity of a DAHDI channel. + + + + The POLARITY function can be used to set the polarity of a DAHDI channel. + Applies only to FXS channels (using FXO signalling) with supporting hardware. + The polarity can be set to the following numeric or named values: + + + + + + + However, when read, the function will always return 0 or 1. + + same => n,Set(POLARITY()=0) + + + same => n,NoOp(Current Polarity: ${POLARITY()}) + same => n,Set(POLARITY()=reverse) + same => n,NoOp(New Polarity: ${POLARITY()}) + + + same => n,Set(POLARITY()=${IF($[ "${POLARITY()}" = "1" ]?0:1)}) + + + @@ -2694,6 +2723,86 @@ static void my_hangup_polarityswitch(void *pvt) } } +/*! \brief Return DAHDI pivot if channel is FXO signalled */ +static struct dahdi_pvt *fxo_pvt(struct ast_channel *chan) +{ + int res; + struct dahdi_params dahdip; + struct dahdi_pvt *pvt = NULL; + + if (strcasecmp(ast_channel_tech(chan)->type, "DAHDI")) { + ast_log(LOG_WARNING, "%s is not a DAHDI channel\n", ast_channel_name(chan)); + return NULL; + } + + memset(&dahdip, 0, sizeof(dahdip)); + res = ioctl(ast_channel_fd(chan, 0), DAHDI_GET_PARAMS, &dahdip); + + if (res) { + ast_log(LOG_WARNING, "Unable to get parameters of %s: %s\n", ast_channel_name(chan), strerror(errno)); + return NULL; + } + if (!(dahdip.sigtype & __DAHDI_SIG_FXO)) { + ast_log(LOG_WARNING, "%s is not FXO signalled\n", ast_channel_name(chan)); + return NULL; + } + + pvt = ast_channel_tech_pvt(chan); + if (!dahdi_analog_lib_handles(pvt->sig, 0, 0)) { + ast_log(LOG_WARNING, "Channel signalling is not analog"); + return NULL; + } + + return pvt; +} + +static int polarity_read(struct ast_channel *chan, const char *cmd, char *data, char *buffer, size_t buflen) +{ + struct dahdi_pvt *pvt; + + pvt = fxo_pvt(chan); + if (!pvt) { + return -1; + } + + snprintf(buffer, buflen, "%d", pvt->polarity); + + return 0; +} + +static int polarity_write(struct ast_channel *chan, const char *cmd, char *data, const char *value) +{ + struct dahdi_pvt *pvt; + int polarity; + + pvt = fxo_pvt(chan); + if (!pvt) { + return -1; + } + + if (!strcasecmp(value, "idle")) { + polarity = POLARITY_IDLE; + } else if (!strcasecmp(value, "reverse")) { + polarity = POLARITY_REV; + } else { + polarity = atoi(value); + } + + if (polarity != POLARITY_IDLE && polarity != POLARITY_REV) { + ast_log(LOG_WARNING, "Invalid polarity: '%s'\n", value); + return -1; + } + + my_set_polarity(pvt, polarity); + return 0; +} + +static struct ast_custom_function polarity_function = { + .name = "POLARITY", + .write = polarity_write, + .read = polarity_read, +}; + static int my_start(void *pvt) { struct dahdi_pvt *p = pvt; @@ -17605,6 +17714,8 @@ static int __unload_module(void) ast_unregister_application(dahdi_accept_r2_call_app); #endif + ast_custom_function_unregister(&polarity_function); + ast_cli_unregister_multiple(dahdi_cli, ARRAY_LEN(dahdi_cli)); ast_manager_unregister("DAHDIDialOffhook"); ast_manager_unregister("DAHDIHangup"); @@ -19793,6 +19904,8 @@ static int load_module(void) ast_register_application_xml(dahdi_accept_r2_call_app, dahdi_accept_r2_call_exec); #endif + ast_custom_function_register(&polarity_function); + ast_cli_register_multiple(dahdi_cli, ARRAY_LEN(dahdi_cli)); memset(round_robin, 0, sizeof(round_robin)); ast_manager_register_xml("DAHDITransfer", 0, action_transfer); diff --git a/doc/CHANGES-staging/chan_dahdi_polarity.txt b/doc/CHANGES-staging/chan_dahdi_polarity.txt new file mode 100644 index 0000000000..365ab200dd --- /dev/null +++ b/doc/CHANGES-staging/chan_dahdi_polarity.txt @@ -0,0 +1,5 @@ +Subject: chan_dahdi + +A POLARITY function is now available that allows +getting or setting the polarity on a channel +from the dialplan.