summaryrefslogtreecommitdiff
path: root/channels/chan_misdn.c
diff options
context:
space:
mode:
Diffstat (limited to 'channels/chan_misdn.c')
-rw-r--r--channels/chan_misdn.c1553
1 files changed, 1147 insertions, 406 deletions
diff --git a/channels/chan_misdn.c b/channels/chan_misdn.c
index 599bcef82..52b8f1d9f 100644
--- a/channels/chan_misdn.c
+++ b/channels/chan_misdn.c
@@ -47,6 +47,7 @@ ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
#include <signal.h>
#include <sys/file.h>
#include <semaphore.h>
+#include <ctype.h>
#include "asterisk/channel.h"
#include "asterisk/config.h"
@@ -88,8 +89,6 @@ struct misdn_jb{
ast_mutex_t mutexjb;
};
-
-
/*! \brief allocates the jb-structure and initialize the elements */
struct misdn_jb *misdn_jb_init(int size, int upper_threshold);
@@ -340,10 +339,6 @@ struct chan_list {
*/
char mohinterpret[MAX_MUSICCLASS];
-#if 0
- int zero_read_cnt; /* Not used */
-#endif
-
/*!
* \brief Number of outgoing audio frames dropped since last debug gripe message.
*/
@@ -401,18 +396,10 @@ struct chan_list {
*/
struct timeval overlap_tv;
-#if 0
- struct chan_list *peer; /* Not used */
-#endif
-
/*!
* \brief Next channel call record in the list.
*/
struct chan_list *next;
-#if 0
- struct chan_list *prev; /* Not used */
- struct chan_list *first; /* Not used */
-#endif
};
@@ -423,13 +410,14 @@ void export_ch(struct ast_channel *chan, struct misdn_bchannel *bc, struct chan_
void import_ch(struct ast_channel *chan, struct misdn_bchannel *bc, struct chan_list *ch);
static struct ast_frame *process_ast_dsp(struct chan_list *tmp, struct ast_frame *frame);
-static struct robin_list {
+struct robin_list {
char *group;
int port;
int channel;
struct robin_list *next;
struct robin_list *prev;
-} *robin = NULL;
+};
+static struct robin_list *robin = NULL;
static inline void free_robin_list_r(struct robin_list *r)
@@ -538,7 +526,7 @@ static int misdn_facility_exec(struct ast_channel *chan, void *data);
int chan_misdn_jb_empty(struct misdn_bchannel *bc, char *buf, int len);
-void debug_numplan(int port, int numplan, char *type);
+void debug_numtype(int port, int numtype, char *type);
int add_out_calls(int port);
int add_in_calls(int port);
@@ -580,6 +568,534 @@ static struct chan_list * get_chan_by_ast_name(char *name)
return NULL;
}
+/*!
+ * \internal
+ * \brief Convert the mISDN type of number code to a string
+ *
+ * \param number_type mISDN type of number code.
+ *
+ * \return The mISDN type of number code as a string
+ */
+static const char *misdn_to_str_ton(enum mISDN_NUMBER_TYPE number_type)
+{
+ const char *str;
+
+ switch (number_type) {
+ default:
+ case NUMTYPE_UNKNOWN:
+ str = "Unknown";
+ break;
+
+ case NUMTYPE_INTERNATIONAL:
+ str = "International";
+ break;
+
+ case NUMTYPE_NATIONAL:
+ str = "National";
+ break;
+
+ case NUMTYPE_NETWORK_SPECIFIC:
+ str = "Network Specific";
+ break;
+
+ case NUMTYPE_SUBSCRIBER:
+ str = "Subscriber";
+ break;
+
+ case NUMTYPE_ABBREVIATED:
+ str = "Abbreviated";
+ break;
+ }
+
+ return str;
+}
+
+/*!
+ * \internal
+ * \brief Convert the mISDN type of number code to Asterisk type of number code
+ *
+ * \param number_type mISDN type of number code.
+ *
+ * \return Asterisk type of number code
+ */
+static int misdn_to_ast_ton(enum mISDN_NUMBER_TYPE number_type)
+{
+ int ast_number_type;
+
+ switch (number_type) {
+ default:
+ case NUMTYPE_UNKNOWN:
+ ast_number_type = NUMTYPE_UNKNOWN << 4;
+ break;
+
+ case NUMTYPE_INTERNATIONAL:
+ ast_number_type = NUMTYPE_INTERNATIONAL << 4;
+ break;
+
+ case NUMTYPE_NATIONAL:
+ ast_number_type = NUMTYPE_NATIONAL << 4;
+ break;
+
+ case NUMTYPE_NETWORK_SPECIFIC:
+ ast_number_type = NUMTYPE_NETWORK_SPECIFIC << 4;
+ break;
+
+ case NUMTYPE_SUBSCRIBER:
+ ast_number_type = NUMTYPE_SUBSCRIBER << 4;
+ break;
+
+ case NUMTYPE_ABBREVIATED:
+ ast_number_type = NUMTYPE_ABBREVIATED << 4;
+ break;
+ }
+
+ return ast_number_type;
+}
+
+/*!
+ * \internal
+ * \brief Convert the Asterisk type of number code to mISDN type of number code
+ *
+ * \param ast_number_type Asterisk type of number code.
+ *
+ * \return mISDN type of number code
+ */
+static enum mISDN_NUMBER_TYPE ast_to_misdn_ton(unsigned ast_number_type)
+{
+ enum mISDN_NUMBER_TYPE number_type;
+
+ switch ((ast_number_type >> 4) & 0x07) {
+ default:
+ case NUMTYPE_UNKNOWN:
+ number_type = NUMTYPE_UNKNOWN;
+ break;
+
+ case NUMTYPE_INTERNATIONAL:
+ number_type = NUMTYPE_INTERNATIONAL;
+ break;
+
+ case NUMTYPE_NATIONAL:
+ number_type = NUMTYPE_NATIONAL;
+ break;
+
+ case NUMTYPE_NETWORK_SPECIFIC:
+ number_type = NUMTYPE_NETWORK_SPECIFIC;
+ break;
+
+ case NUMTYPE_SUBSCRIBER:
+ number_type = NUMTYPE_SUBSCRIBER;
+ break;
+
+ case NUMTYPE_ABBREVIATED:
+ number_type = NUMTYPE_ABBREVIATED;
+ break;
+ }
+
+ return number_type;
+}
+
+/*!
+ * \internal
+ * \brief Convert the mISDN numbering plan code to a string
+ *
+ * \param number_plan mISDN numbering plan code.
+ *
+ * \return The mISDN numbering plan code as a string
+ */
+static const char *misdn_to_str_plan(enum mISDN_NUMBER_PLAN number_plan)
+{
+ const char *str;
+
+ switch (number_plan) {
+ default:
+ case NUMPLAN_UNKNOWN:
+ str = "Unknown";
+ break;
+
+ case NUMPLAN_ISDN:
+ str = "ISDN";
+ break;
+
+ case NUMPLAN_DATA:
+ str = "Data";
+ break;
+
+ case NUMPLAN_TELEX:
+ str = "Telex";
+ break;
+
+ case NUMPLAN_NATIONAL:
+ str = "National";
+ break;
+
+ case NUMPLAN_PRIVATE:
+ str = "Private";
+ break;
+ }
+
+ return str;
+}
+
+/*!
+ * \internal
+ * \brief Convert the mISDN numbering plan code to Asterisk numbering plan code
+ *
+ * \param number_plan mISDN numbering plan code.
+ *
+ * \return Asterisk numbering plan code
+ */
+static int misdn_to_ast_plan(enum mISDN_NUMBER_PLAN number_plan)
+{
+ int ast_number_plan;
+
+ switch (number_plan) {
+ default:
+ case NUMPLAN_UNKNOWN:
+ ast_number_plan = NUMPLAN_UNKNOWN;
+ break;
+
+ case NUMPLAN_ISDN:
+ ast_number_plan = NUMPLAN_ISDN;
+ break;
+
+ case NUMPLAN_DATA:
+ ast_number_plan = NUMPLAN_DATA;
+ break;
+
+ case NUMPLAN_TELEX:
+ ast_number_plan = NUMPLAN_TELEX;
+ break;
+
+ case NUMPLAN_NATIONAL:
+ ast_number_plan = NUMPLAN_NATIONAL;
+ break;
+
+ case NUMPLAN_PRIVATE:
+ ast_number_plan = NUMPLAN_PRIVATE;
+ break;
+ }
+
+ return ast_number_plan;
+}
+
+/*!
+ * \internal
+ * \brief Convert the Asterisk numbering plan code to mISDN numbering plan code
+ *
+ * \param ast_number_plan Asterisk numbering plan code.
+ *
+ * \return mISDN numbering plan code
+ */
+static enum mISDN_NUMBER_PLAN ast_to_misdn_plan(unsigned ast_number_plan)
+{
+ enum mISDN_NUMBER_PLAN number_plan;
+
+ switch (ast_number_plan & 0x0F) {
+ default:
+ case NUMPLAN_UNKNOWN:
+ number_plan = NUMPLAN_UNKNOWN;
+ break;
+
+ case NUMPLAN_ISDN:
+ number_plan = NUMPLAN_ISDN;
+ break;
+
+ case NUMPLAN_DATA:
+ number_plan = NUMPLAN_DATA;
+ break;
+
+ case NUMPLAN_TELEX:
+ number_plan = NUMPLAN_TELEX;
+ break;
+
+ case NUMPLAN_NATIONAL:
+ number_plan = NUMPLAN_NATIONAL;
+ break;
+
+ case NUMPLAN_PRIVATE:
+ number_plan = NUMPLAN_PRIVATE;
+ break;
+ }
+
+ return number_plan;
+}
+
+/*!
+ * \internal
+ * \brief Convert the mISDN presentation code to a string
+ *
+ * \param presentation mISDN number presentation restriction code.
+ *
+ * \return The mISDN presentation code as a string
+ */
+static const char *misdn_to_str_pres(int presentation)
+{
+ const char *str;
+
+ switch (presentation) {
+ case 0:
+ str = "Allowed";
+ break;
+
+ case 1:
+ str = "Restricted";
+ break;
+
+ case 2:
+ str = "Unavailable";
+ break;
+
+ default:
+ str = "Unknown";
+ break;
+ }
+
+ return str;
+}
+
+/*!
+ * \internal
+ * \brief Convert the mISDN presentation code to Asterisk presentation code
+ *
+ * \param presentation mISDN number presentation restriction code.
+ *
+ * \return Asterisk presentation code
+ */
+static int misdn_to_ast_pres(int presentation)
+{
+ switch (presentation) {
+ default:
+ case 0:
+ presentation = AST_PRES_ALLOWED;
+ break;
+
+ case 1:
+ presentation = AST_PRES_RESTRICTED;
+ break;
+
+ case 2:
+ presentation = AST_PRES_UNAVAILABLE;
+ break;
+ }
+
+ return presentation;
+}
+
+/*!
+ * \internal
+ * \brief Convert the Asterisk presentation code to mISDN presentation code
+ *
+ * \param presentation Asterisk number presentation restriction code.
+ *
+ * \return mISDN presentation code
+ */
+static int ast_to_misdn_pres(int presentation)
+{
+ switch (presentation & AST_PRES_RESTRICTION) {
+ default:
+ case AST_PRES_ALLOWED:
+ presentation = 0;
+ break;
+
+ case AST_PRES_RESTRICTED:
+ presentation = 1;
+ break;
+
+ case AST_PRES_UNAVAILABLE:
+ presentation = 2;
+ break;
+ }
+
+ return presentation;
+}
+
+/*!
+ * \internal
+ * \brief Convert the mISDN screening code to a string
+ *
+ * \param screening mISDN number screening code.
+ *
+ * \return The mISDN screening code as a string
+ */
+static const char *misdn_to_str_screen(int screening)
+{
+ const char *str;
+
+ switch (screening) {
+ case 0:
+ str = "Unscreened";
+ break;
+
+ case 1:
+ str = "Passed Screen";
+ break;
+
+ case 2:
+ str = "Failed Screen";
+ break;
+
+ case 3:
+ str = "Network Number";
+ break;
+
+ default:
+ str = "Unknown";
+ break;
+ }
+
+ return str;
+}
+
+/*!
+ * \internal
+ * \brief Convert the mISDN screening code to Asterisk screening code
+ *
+ * \param screening mISDN number screening code.
+ *
+ * \return Asterisk screening code
+ */
+static int misdn_to_ast_screen(int screening)
+{
+ switch (screening) {
+ default:
+ case 0:
+ screening = AST_PRES_USER_NUMBER_UNSCREENED;
+ break;
+
+ case 1:
+ screening = AST_PRES_USER_NUMBER_PASSED_SCREEN;
+ break;
+
+ case 2:
+ screening = AST_PRES_USER_NUMBER_FAILED_SCREEN;
+ break;
+
+ case 3:
+ screening = AST_PRES_NETWORK_NUMBER;
+ break;
+ }
+
+ return screening;
+}
+
+/*!
+ * \internal
+ * \brief Convert the Asterisk screening code to mISDN screening code
+ *
+ * \param screening Asterisk number screening code.
+ *
+ * \return mISDN screening code
+ */
+static int ast_to_misdn_screen(int screening)
+{
+ switch (screening & AST_PRES_NUMBER_TYPE) {
+ default:
+ case AST_PRES_USER_NUMBER_UNSCREENED:
+ screening = 0;
+ break;
+
+ case AST_PRES_USER_NUMBER_PASSED_SCREEN:
+ screening = 1;
+ break;
+
+ case AST_PRES_USER_NUMBER_FAILED_SCREEN:
+ screening = 2;
+ break;
+
+ case AST_PRES_NETWORK_NUMBER:
+ screening = 3;
+ break;
+ }
+
+ return screening;
+}
+
+/*!
+ * \internal
+ * \brief Convert Asterisk redirecting reason to mISDN redirecting reason code.
+ *
+ * \param ast Asterisk redirecting reason code.
+ *
+ * \return mISDN reason code
+ */
+static enum mISDN_REDIRECTING_REASON ast_to_misdn_reason(const enum AST_REDIRECTING_REASON ast)
+{
+ unsigned index;
+
+ static const struct misdn_reasons {
+ enum AST_REDIRECTING_REASON ast;
+ enum mISDN_REDIRECTING_REASON q931;
+ } misdn_reason_table[] = {
+ /* *INDENT-OFF* */
+ { AST_REDIRECTING_REASON_UNKNOWN, mISDN_REDIRECTING_REASON_UNKNOWN },
+ { AST_REDIRECTING_REASON_USER_BUSY, mISDN_REDIRECTING_REASON_CALL_FWD_BUSY },
+ { AST_REDIRECTING_REASON_NO_ANSWER, mISDN_REDIRECTING_REASON_NO_REPLY },
+ { AST_REDIRECTING_REASON_UNAVAILABLE, mISDN_REDIRECTING_REASON_NO_REPLY },
+ { AST_REDIRECTING_REASON_UNCONDITIONAL, mISDN_REDIRECTING_REASON_CALL_FWD },
+ { AST_REDIRECTING_REASON_TIME_OF_DAY, mISDN_REDIRECTING_REASON_UNKNOWN },
+ { AST_REDIRECTING_REASON_DO_NOT_DISTURB, mISDN_REDIRECTING_REASON_UNKNOWN },
+ { AST_REDIRECTING_REASON_DEFLECTION, mISDN_REDIRECTING_REASON_DEFLECTION },
+ { AST_REDIRECTING_REASON_FOLLOW_ME, mISDN_REDIRECTING_REASON_UNKNOWN },
+ { AST_REDIRECTING_REASON_OUT_OF_ORDER, mISDN_REDIRECTING_REASON_OUT_OF_ORDER },
+ { AST_REDIRECTING_REASON_AWAY, mISDN_REDIRECTING_REASON_UNKNOWN },
+ { AST_REDIRECTING_REASON_CALL_FWD_DTE, mISDN_REDIRECTING_REASON_CALL_FWD_DTE }
+ /* *INDENT-ON* */
+ };
+
+ for (index = 0; index < ARRAY_LEN(misdn_reason_table); ++index) {
+ if (misdn_reason_table[index].ast == ast) {
+ return misdn_reason_table[index].q931;
+ }
+ }
+ return mISDN_REDIRECTING_REASON_UNKNOWN;
+}
+
+/*!
+ * \internal
+ * \brief Convert the mISDN redirecting reason to Asterisk redirecting reason code
+ *
+ * \param q931 mISDN redirecting reason code.
+ *
+ * \return Asterisk redirecting reason code
+ */
+static enum AST_REDIRECTING_REASON misdn_to_ast_reason(const enum mISDN_REDIRECTING_REASON q931)
+{
+ enum AST_REDIRECTING_REASON ast;
+
+ switch (q931) {
+ default:
+ case mISDN_REDIRECTING_REASON_UNKNOWN:
+ ast = AST_REDIRECTING_REASON_UNKNOWN;
+ break;
+
+ case mISDN_REDIRECTING_REASON_CALL_FWD_BUSY:
+ ast = AST_REDIRECTING_REASON_USER_BUSY;
+ break;
+
+ case mISDN_REDIRECTING_REASON_NO_REPLY:
+ ast = AST_REDIRECTING_REASON_NO_ANSWER;
+ break;
+
+ case mISDN_REDIRECTING_REASON_DEFLECTION:
+ ast = AST_REDIRECTING_REASON_DEFLECTION;
+ break;
+
+ case mISDN_REDIRECTING_REASON_OUT_OF_ORDER:
+ ast = AST_REDIRECTING_REASON_OUT_OF_ORDER;
+ break;
+
+ case mISDN_REDIRECTING_REASON_CALL_FWD_DTE:
+ ast = AST_REDIRECTING_REASON_CALL_FWD_DTE;
+ break;
+
+ case mISDN_REDIRECTING_REASON_CALL_FWD:
+ ast = AST_REDIRECTING_REASON_UNCONDITIONAL;
+ break;
+ }
+
+ return ast;
+}
+
struct allowed_bearers {
@@ -590,7 +1106,7 @@ struct allowed_bearers {
};
/* *INDENT-OFF* */
-static const struct allowed_bearers allowed_bearers_array[]= {
+static const struct allowed_bearers allowed_bearers_array[] = {
/* Name, Displayable Name Bearer Capability, Deprecated */
{ "speech", "Speech", INFO_CAPABILITY_SPEECH, 0 },
{ "3_1khz", "3.1KHz Audio", INFO_CAPABILITY_AUDIO_3_1K, 0 },
@@ -609,7 +1125,7 @@ static const char *bearer2str(int cap)
if (allowed_bearers_array[index].cap == cap) {
return allowed_bearers_array[index].display;
}
- } /* end for */
+ }
return "Unknown Bearer";
}
@@ -682,6 +1198,95 @@ static void print_bearer(struct misdn_bchannel *bc)
}
}
+/*!
+ * \internal
+ * \brief Prefix a string to another string in place.
+ *
+ * \param str_prefix String to prefix to the main string.
+ * \param str_main String to get the prefix added to it.
+ * \param size Buffer size of the main string (Includes null terminator).
+ *
+ * \note The str_main buffer size must be greater than one.
+ *
+ * \return Nothing
+ */
+static void misdn_prefix_string(const char *str_prefix, char *str_main, size_t size)
+{
+ size_t len_over;
+ size_t len_total;
+ size_t len_main;
+ size_t len_prefix;
+
+ len_prefix = strlen(str_prefix);
+ if (!len_prefix) {
+ /* There is no prefix to prepend. */
+ return;
+ }
+ len_main = strlen(str_main);
+ len_total = len_prefix + len_main;
+ if (size <= len_total) {
+ /* We need to truncate since the buffer is too small. */
+ len_over = len_total + 1 - size;
+ if (len_over <= len_main) {
+ len_main -= len_over;
+ } else {
+ len_over -= len_main;
+ len_main = 0;
+ len_prefix -= len_over;
+ }
+ }
+ if (len_main) {
+ memmove(str_main + len_prefix, str_main, len_main);
+ }
+ memcpy(str_main, str_prefix, len_prefix);
+ str_main[len_prefix + len_main] = '\0';
+}
+
+/*!
+ * \internal
+ * \brief Add a configured prefix to the given number.
+ *
+ * \param port Logical port number
+ * \param number_type Type-of-number passed in.
+ * \param number Given number string to add prefix
+ * \param size Buffer size number string occupies.
+ *
+ * \return Nothing
+ */
+static void misdn_add_number_prefix(int port, enum mISDN_NUMBER_TYPE number_type, char *number, size_t size)
+{
+ enum misdn_cfg_elements type_prefix;
+ char num_prefix[MISDN_MAX_NUMBER_LEN];
+
+ /* Get prefix string. */
+ switch (number_type) {
+ case NUMTYPE_UNKNOWN:
+ type_prefix = MISDN_CFG_TON_PREFIX_UNKNOWN;
+ break;
+ case NUMTYPE_INTERNATIONAL:
+ type_prefix = MISDN_CFG_TON_PREFIX_INTERNATIONAL;
+ break;
+ case NUMTYPE_NATIONAL:
+ type_prefix = MISDN_CFG_TON_PREFIX_NATIONAL;
+ break;
+ case NUMTYPE_NETWORK_SPECIFIC:
+ type_prefix = MISDN_CFG_TON_PREFIX_NETWORK_SPECIFIC;
+ break;
+ case NUMTYPE_SUBSCRIBER:
+ type_prefix = MISDN_CFG_TON_PREFIX_SUBSCRIBER;
+ break;
+ case NUMTYPE_ABBREVIATED:
+ type_prefix = MISDN_CFG_TON_PREFIX_ABBREVIATED;
+ break;
+ default:
+ /* Type-of-number does not have a prefix that can be added. */
+ return;
+ }
+ misdn_cfg_get(port, type_prefix, num_prefix, sizeof(num_prefix));
+
+ misdn_prefix_string(num_prefix, number, size);
+}
+
static void export_aoc_vars(int originator, struct ast_channel *ast, struct misdn_bchannel *bc)
{
char buf[128];
@@ -691,7 +1296,8 @@ static void export_aoc_vars(int originator, struct ast_channel *ast, struct misd
}
if (originator == ORG_AST) {
- if (!(ast = ast_bridged_channel(ast))) {
+ ast = ast_bridged_channel(ast);
+ if (!ast) {
return;
}
}
@@ -745,7 +1351,8 @@ static void export_aoc_vars(int originator, struct ast_channel *ast, struct misd
/*************** Helpers END *************/
static void sighandler(int sig)
-{}
+{
+}
static void *misdn_tasks_thread_func(void *data)
{
@@ -840,6 +1447,7 @@ static void misdn_tasks_remove(int task_id)
static int misdn_l1_task(const void *vdata)
{
const int *data = vdata;
+
misdn_lib_isdn_l1watcher(*data);
chan_misdn_log(5, *data, "L1watcher timeout\n");
return 1;
@@ -866,21 +1474,22 @@ static int misdn_overlap_dial_task(const void *data)
tv_end.tv_sec += ch->overlap_dial;
tv_now = ast_tvnow();
- if ((diff = ast_tvdiff_ms(tv_end, tv_now)) > 100) {
+ diff = ast_tvdiff_ms(tv_end, tv_now);
+ if (100 < diff) {
return diff;
}
/* if we are 100ms near the timeout, we are satisfied.. */
stop_indicate(ch);
- if (ast_strlen_zero(ch->bc->dad)) {
+ if (ast_strlen_zero(ch->bc->dialed.number)) {
dad = "s";
- ast_copy_string(ch->ast->exten, "s", sizeof(ch->ast->exten));
+ strcpy(ch->ast->exten, dad);
} else {
- dad = ch->bc->dad;
+ dad = ch->bc->dialed.number;
}
- if (ast_exists_extension(ch->ast, ch->context, dad, 1, ch->bc->oad)) {
+ if (ast_exists_extension(ch->ast, ch->context, dad, 1, ch->bc->caller.number)) {
ch->state = MISDN_DIALING;
if (pbx_start_chan(ch) < 0) {
chan_misdn_log(-1, ch->bc->port, "ast_pbx_start returned < 0 in misdn_overlap_dial_task\n");
@@ -957,8 +1566,10 @@ static char *handle_cli_misdn_set_debug(struct ast_cli_entry *e, int cmd, struct
level = 1;
} else if (!strcasecmp(a->argv[3], "off")) {
level = 0;
- } else {
+ } else if (isdigit(a->argv[3][0])) {
level = atoi(a->argv[3]);
+ } else {
+ return CLI_SHOWUSAGE;
}
switch (a->argc) {
@@ -1293,27 +1904,29 @@ struct state_struct {
};
static struct state_struct state_array[] = {
+/* *INDENT-OFF* */
{ MISDN_NOTHING, "NOTHING" }, /* at beginning */
- { MISDN_WAITING4DIGS, "WAITING4DIGS" }, /* when waiting for infos */
- { MISDN_EXTCANTMATCH, "EXTCANTMATCH" }, /* when asterisk couldn't match our ext */
- { MISDN_INCOMING_SETUP, "INCOMING SETUP" }, /* when pbx_start */
- { MISDN_DIALING, "DIALING" }, /* when pbx_start */
- { MISDN_PROGRESS, "PROGRESS" }, /* when pbx_start */
- { MISDN_PROCEEDING, "PROCEEDING" }, /* when pbx_start */
- { MISDN_CALLING, "CALLING" }, /* when misdn_call is called */
- { MISDN_CALLING_ACKNOWLEDGE, "CALLING_ACKNOWLEDGE" }, /* when misdn_call is called */
- { MISDN_ALERTING, "ALERTING" }, /* when Alerting */
- { MISDN_BUSY, "BUSY" }, /* when BUSY */
- { MISDN_CONNECTED, "CONNECTED" }, /* when connected */
- { MISDN_PRECONNECTED, "PRECONNECTED" }, /* when connected */
- { MISDN_DISCONNECTED, "DISCONNECTED" }, /* when connected */
- { MISDN_RELEASED, "RELEASED" }, /* when connected */
- { MISDN_BRIDGED, "BRIDGED" }, /* when bridged */
+ { MISDN_WAITING4DIGS, "WAITING4DIGS" }, /* when waiting for infos */
+ { MISDN_EXTCANTMATCH, "EXTCANTMATCH" }, /* when asterisk couldn't match our ext */
+ { MISDN_INCOMING_SETUP, "INCOMING SETUP" }, /* when pbx_start */
+ { MISDN_DIALING, "DIALING" }, /* when pbx_start */
+ { MISDN_PROGRESS, "PROGRESS" }, /* when pbx_start */
+ { MISDN_PROCEEDING, "PROCEEDING" }, /* when pbx_start */
+ { MISDN_CALLING, "CALLING" }, /* when misdn_call is called */
+ { MISDN_CALLING_ACKNOWLEDGE, "CALLING_ACKNOWLEDGE" }, /* when misdn_call is called */
+ { MISDN_ALERTING, "ALERTING" }, /* when Alerting */
+ { MISDN_BUSY, "BUSY" }, /* when BUSY */
+ { MISDN_CONNECTED, "CONNECTED" }, /* when connected */
+ { MISDN_PRECONNECTED, "PRECONNECTED" }, /* when connected */
+ { MISDN_DISCONNECTED, "DISCONNECTED" }, /* when connected */
+ { MISDN_RELEASED, "RELEASED" }, /* when connected */
+ { MISDN_BRIDGED, "BRIDGED" }, /* when bridged */
{ MISDN_CLEANING, "CLEANING" }, /* when hangup from * but we were connected before */
- { MISDN_HUNGUP_FROM_MISDN, "HUNGUP_FROM_MISDN" }, /* when DISCONNECT/RELEASE/REL_COMP came from misdn */
- { MISDN_HOLDED, "HOLDED" }, /* when DISCONNECT/RELEASE/REL_COMP came from misdn */
- { MISDN_HOLD_DISCONNECT, "HOLD_DISCONNECT" }, /* when DISCONNECT/RELEASE/REL_COMP came from misdn */
+ { MISDN_HUNGUP_FROM_MISDN, "HUNGUP_FROM_MISDN" }, /* when DISCONNECT/RELEASE/REL_COMP came from misdn */
+ { MISDN_HOLDED, "HOLDED" }, /* when DISCONNECT/RELEASE/REL_COMP came from misdn */
+ { MISDN_HOLD_DISCONNECT, "HOLD_DISCONNECT" }, /* when DISCONNECT/RELEASE/REL_COMP came from misdn */
{ MISDN_HUNGUP_FROM_AST, "HUNGUP_FROM_AST" }, /* when DISCONNECT/RELEASE/REL_COMP came out of misdn_hangup */
+/* *INDENT-ON* */
};
static const char *misdn_get_ch_state(struct chan_list *p)
@@ -1384,18 +1997,24 @@ static char *handle_cli_misdn_reload(struct ast_cli_entry *e, int cmd, struct as
static void print_bc_info (int fd, struct chan_list *help, struct misdn_bchannel *bc)
{
struct ast_channel *ast = help->ast;
- ast_cli(fd,
- "* Pid:%d Prt:%d Ch:%d Mode:%s Org:%s dad:%s oad:%s rad:%s ctx:%s state:%s\n",
- bc->pid, bc->port, bc->channel,
+ ast_cli(fd,
+ "* Pid:%d Port:%d Ch:%d Mode:%s Orig:%s dialed:%s\n"
+ " --> caller:\"%s\" <%s>\n"
+ " --> redirecting:\"%s\" <%s>\n"
+ " --> context:%s state:%s\n",
+ bc->pid,
+ bc->port,
+ bc->channel,
bc->nt ? "NT" : "TE",
help->originator == ORG_AST ? "*" : "I",
- ast ? ast->exten : NULL,
- ast ? ast->cid.cid_num : NULL,
- bc->rad,
- ast ? ast->context : NULL,
- misdn_get_ch_state(help)
- );
+ ast ? ast->exten : "",
+ (ast && ast->cid.cid_name) ? ast->cid.cid_name : "",
+ (ast && ast->cid.cid_num) ? ast->cid.cid_num : "",
+ bc->redirecting.from.name,
+ bc->redirecting.from.number,
+ ast ? ast->context : "",
+ misdn_get_ch_state(help));
if (misdn_debug[bc->port] > 0) {
ast_cli(fd,
" --> astname: %s\n"
@@ -1418,21 +2037,18 @@ static void print_bc_info (int fd, struct chan_list *help, struct misdn_bchannel
help->l3id,
help->addr,
bc->addr,
- bc ? bc->l3_id : -1,
+ bc->l3_id,
bc->display,
-
bc->active,
bc_state2str(bc->bc_state),
bearer2str(bc->capability),
#ifdef MISDN_1_2
bc->pipeline,
#else
- bc->ec_enable,
+ bc->ec_enable,
#endif
-
help->norxtone, help->notxtone,
- bc->holded
- );
+ bc->holded);
}
}
@@ -1480,15 +2096,17 @@ static char *handle_cli_misdn_show_channels(struct ast_cli_entry *e, int cmd, st
if (help->state == MISDN_HOLDED) {
ast_cli(a->fd, "ITS A HOLDED BC:\n");
ast_cli(a->fd, " --> l3_id: %x\n"
- " --> dad:%s oad:%s\n"
- " --> hold_port: %d\n"
- " --> hold_channel: %d\n",
- help->l3id,
- ast->exten,
- ast->cid.cid_num,
- help->hold_info.port,
- help->hold_info.channel
- );
+ " --> dialed:%s\n"
+ " --> caller:\"%s\" <%s>\n"
+ " --> hold_port: %d\n"
+ " --> hold_channel: %d\n",
+ help->l3id,
+ ast->exten,
+ ast->cid.cid_name ? ast->cid.cid_name : "",
+ ast->cid.cid_num ? ast->cid.cid_num : "",
+ help->hold_info.port,
+ help->hold_info.channel
+ );
} else {
ast_cli(a->fd, "* Channel in unknown STATE !!! Exten:%s, Callerid:%s\n", ast->exten, ast->cid.cid_num);
}
@@ -1693,7 +2311,7 @@ static char *handle_cli_misdn_send_facility(struct ast_cli_entry *e, int cmd, st
return 0;
}
tmp->bc->fac_out.Function = Fac_CD;
- ast_copy_string((char *)tmp->bc->fac_out.u.CDeflection.DeflectedToNumber, nr, sizeof(tmp->bc->fac_out.u.CDeflection.DeflectedToNumber));
+ ast_copy_string((char *) tmp->bc->fac_out.u.CDeflection.DeflectedToNumber, nr, sizeof(tmp->bc->fac_out.u.CDeflection.DeflectedToNumber));
misdn_lib_send_event(tmp->bc, EVENT_FACILITY);
} else if (strstr(a->argv[3], "CFActivate")) {
if (a->argc < 7) {
@@ -1718,7 +2336,7 @@ static char *handle_cli_misdn_send_facility(struct ast_cli_entry *e, int cmd, st
} else if (strstr(a->argv[3], "CFDeactivate")) {
if (a->argc < 6) {
- ast_verbose("CFActivate requires 1 arg: FromNumber\n\n");
+ ast_verbose("CFDeactivate requires 1 arg: FromNumber\n\n");
return 0;
}
port = atoi(a->argv[4]);
@@ -1728,10 +2346,10 @@ static char *handle_cli_misdn_send_facility(struct ast_cli_entry *e, int cmd, st
ast_verbose("Sending CFDeactivate Port:(%d) FromNr. (%s)\n", port, served_nr);
bc->fac_out.Function = Fac_CFDeactivate;
- bc->fac_out.u.CFDeactivate.BasicService = 0; //All Services
- bc->fac_out.u.CFDeactivate.Procedure = 0; //Unconditional
+ bc->fac_out.u.CFDeactivate.BasicService = 0; /* All Services */
+ bc->fac_out.u.CFDeactivate.Procedure = 0; /* Unconditional */
+ ast_copy_string((char *) bc->fac_out.u.CFActivate.ServedUserNumber, served_nr, sizeof(bc->fac_out.u.CFActivate.ServedUserNumber));
- ast_copy_string((char *)bc->fac_out.u.CFActivate.ServedUserNumber, served_nr, sizeof(bc->fac_out.u.CFActivate.ServedUserNumber));
misdn_lib_send_event(bc, EVENT_FACILITY);
}
@@ -2009,23 +2627,25 @@ static struct ast_cli_entry chan_misdn_clis[] = {
};
/*! \brief Updates caller ID information from config */
-static int update_config(struct chan_list *ch, int orig)
+static void update_config(struct chan_list *ch)
{
struct ast_channel *ast;
struct misdn_bchannel *bc;
- int port, hdlc = 0;
- int pres, screen;
+ int port;
+ int hdlc = 0;
+ int pres;
+ int screen;
if (!ch) {
ast_log(LOG_WARNING, "Cannot configure without chanlist\n");
- return -1;
+ return;
}
ast = ch->ast;
bc = ch->bc;
if (! ast || ! bc) {
ast_log(LOG_WARNING, "Cannot configure without ast || bc\n");
- return -1;
+ return;
}
port = bc->port;
@@ -2033,7 +2653,6 @@ static int update_config(struct chan_list *ch, int orig)
chan_misdn_log(7, port, "update_config: Getting Config\n");
misdn_cfg_get(port, MISDN_CFG_HDLC, &hdlc, sizeof(int));
-
if (hdlc) {
switch (bc->capability) {
case INFO_CAPABILITY_DIGITAL_UNRESTRICTED:
@@ -2050,48 +2669,17 @@ static int update_config(struct chan_list *ch, int orig)
chan_misdn_log(2, port, " --> pres: %d screen: %d\n", pres, screen);
if (pres < 0 || screen < 0) {
- chan_misdn_log(2, port, " --> pres: %x\n", ast->cid.cid_pres);
+ chan_misdn_log(2, port, " --> pres: %x\n", ast->connected.id.number_presentation);
- switch (ast->cid.cid_pres & 0x60) {
- case AST_PRES_RESTRICTED:
- bc->pres = 1;
- chan_misdn_log(2, port, " --> PRES: Restricted (1)\n");
- break;
- case AST_PRES_UNAVAILABLE:
- bc->pres = 2;
- chan_misdn_log(2, port, " --> PRES: Unavailable (2)\n");
- break;
- default:
- bc->pres = 0;
- chan_misdn_log(2, port, " --> PRES: Allowed (0)\n");
- break;
- }
+ bc->caller.presentation = ast_to_misdn_pres(ast->connected.id.number_presentation);
+ chan_misdn_log(2, port, " --> PRES: %s(%d)\n", misdn_to_str_pres(bc->caller.presentation), bc->caller.presentation);
- switch (ast->cid.cid_pres & 0x3) {
- default:
- case AST_PRES_USER_NUMBER_UNSCREENED:
- bc->screen = 0;
- chan_misdn_log(2, port, " --> SCREEN: Unscreened (0)\n");
- break;
- case AST_PRES_USER_NUMBER_PASSED_SCREEN:
- bc->screen = 1;
- chan_misdn_log(2, port, " --> SCREEN: Passed Screen (1)\n");
- break;
- case AST_PRES_USER_NUMBER_FAILED_SCREEN:
- bc->screen = 2;
- chan_misdn_log(2, port, " --> SCREEN: Failed Screen (2)\n");
- break;
- case AST_PRES_NETWORK_NUMBER:
- bc->screen = 3;
- chan_misdn_log(2, port, " --> SCREEN: Network Nr. (3)\n");
- break;
- }
+ bc->caller.screening = ast_to_misdn_screen(ast->connected.id.number_presentation);
+ chan_misdn_log(2, port, " --> SCREEN: %s(%d)\n", misdn_to_str_screen(bc->caller.screening), bc->caller.screening);
} else {
- bc->screen = screen;
- bc->pres = pres;
+ bc->caller.screening = screen;
+ bc->caller.presentation = pres;
}
-
- return 0;
}
@@ -2130,20 +2718,26 @@ static void config_jitterbuffer(struct chan_list *ch)
}
-void debug_numplan(int port, int numplan, char *type)
+void debug_numtype(int port, int numtype, char *type)
{
- switch (numplan) {
- case NUMPLAN_INTERNATIONAL:
+ switch (numtype) {
+ case NUMTYPE_UNKNOWN:
+ chan_misdn_log(2, port, " --> %s: Unknown\n", type);
+ break;
+ case NUMTYPE_INTERNATIONAL:
chan_misdn_log(2, port, " --> %s: International\n", type);
break;
- case NUMPLAN_NATIONAL:
+ case NUMTYPE_NATIONAL:
chan_misdn_log(2, port, " --> %s: National\n", type);
break;
- case NUMPLAN_SUBSCRIBER:
+ case NUMTYPE_NETWORK_SPECIFIC:
+ chan_misdn_log(2, port, " --> %s: Network Specific\n", type);
+ break;
+ case NUMTYPE_SUBSCRIBER:
chan_misdn_log(2, port, " --> %s: Subscriber\n", type);
break;
- case NUMPLAN_UNKNOWN:
- chan_misdn_log(2, port, " --> %s: Unknown\n", type);
+ case NUMTYPE_ABBREVIATED:
+ chan_misdn_log(2, port, " --> %s: Abbreviated\n", type);
break;
/* Maybe we should cut off the prefix if present ? */
default:
@@ -2193,7 +2787,7 @@ static int update_ec_config(struct misdn_bchannel *bc)
#endif
-static int read_config(struct chan_list *ch, int orig)
+static int read_config(struct chan_list *ch)
{
struct ast_channel *ast;
struct misdn_bchannel *bc;
@@ -2234,7 +2828,6 @@ static int read_config(struct chan_list *ch, int orig)
misdn_cfg_get(port, MISDN_CFG_SENDDTMF, &bc->send_dtmf, sizeof(bc->send_dtmf));
misdn_cfg_get(port, MISDN_CFG_ASTDTMF, &ch->ast_dsp, sizeof(int));
-
if (ch->ast_dsp) {
ch->ignore_dtmf = 1;
}
@@ -2251,7 +2844,6 @@ static int read_config(struct chan_list *ch, int orig)
misdn_cfg_get(port, MISDN_CFG_FAXDETECT, faxdetect, sizeof(faxdetect));
misdn_cfg_get(port, MISDN_CFG_HDLC, &hdlc, sizeof(hdlc));
-
if (hdlc) {
switch (bc->capability) {
case INFO_CAPABILITY_DIGITAL_UNRESTRICTED:
@@ -2280,14 +2872,16 @@ static int read_config(struct chan_list *ch, int orig)
misdn_cfg_get(bc->port, MISDN_CFG_EARLY_BCONNECT, &bc->early_bconnect, sizeof(bc->early_bconnect));
+ misdn_cfg_get(port, MISDN_CFG_DISPLAY_CONNECTED, &bc->display_connected, sizeof(bc->display_connected));
+ misdn_cfg_get(port, MISDN_CFG_DISPLAY_SETUP, &bc->display_setup, sizeof(bc->display_setup));
+
misdn_cfg_get(port, MISDN_CFG_PICKUPGROUP, &pg, sizeof(pg));
misdn_cfg_get(port, MISDN_CFG_CALLGROUP, &cg, sizeof(cg));
-
chan_misdn_log(5, port, " --> * CallGrp:%s PickupGrp:%s\n", ast_print_group(buf, sizeof(buf), cg), ast_print_group(buf2, sizeof(buf2), pg));
ast->pickupgroup = pg;
ast->callgroup = cg;
- if (orig == ORG_AST) {
+ if (ch->originator == ORG_AST) {
char callerid[BUFFERSIZE + 1];
/* ORIGINATOR Asterisk (outgoing call) */
@@ -2300,80 +2894,46 @@ static int read_config(struct chan_list *ch, int orig)
misdn_cfg_get(port, MISDN_CFG_CALLERID, callerid, sizeof(callerid));
if (!ast_strlen_zero(callerid)) {
- chan_misdn_log(1, port, " --> * Setting Cid to %s\n", callerid);
- ast_copy_string(bc->oad, callerid, sizeof(bc->oad));
+ char *cid_name = NULL;
+ char *cid_num = NULL;
+
+ ast_callerid_parse(callerid, &cid_name, &cid_num);
+ if (cid_name) {
+ ast_copy_string(bc->caller.name, cid_name, sizeof(bc->caller.name));
+ } else {
+ bc->caller.name[0] = '\0';
+ }
+ if (cid_num) {
+ ast_copy_string(bc->caller.number, cid_num, sizeof(bc->caller.number));
+ } else {
+ bc->caller.number[0] = '\0';
+ }
+ chan_misdn_log(1, port, " --> * Setting caller to \"%s\" <%s>\n", bc->caller.name, bc->caller.number);
}
- misdn_cfg_get(port, MISDN_CFG_DIALPLAN, &bc->dnumplan, sizeof(bc->dnumplan));
- misdn_cfg_get(port, MISDN_CFG_LOCALDIALPLAN, &bc->onumplan, sizeof(bc->onumplan));
- misdn_cfg_get(port, MISDN_CFG_CPNDIALPLAN, &bc->cpnnumplan, sizeof(bc->cpnnumplan));
- debug_numplan(port, bc->dnumplan, "TON");
- debug_numplan(port, bc->onumplan, "LTON");
- debug_numplan(port, bc->cpnnumplan, "CTON");
+ misdn_cfg_get(port, MISDN_CFG_DIALPLAN, &bc->dialed.number_type, sizeof(bc->dialed.number_type));
+ bc->dialed.number_plan = NUMPLAN_ISDN;
+ debug_numtype(port, bc->dialed.number_type, "TON");
ch->overlap_dial = 0;
} else {
/* ORIGINATOR MISDN (incoming call) */
- char prefix[BUFFERSIZE + 1] = "";
if (strstr(faxdetect, "incoming") || strstr(faxdetect, "both")) {
ch->faxdetect = (strstr(faxdetect, "nojump")) ? 2 : 1;
}
- misdn_cfg_get(port, MISDN_CFG_CPNDIALPLAN, &bc->cpnnumplan, sizeof(bc->cpnnumplan));
- debug_numplan(port, bc->cpnnumplan, "CTON");
-
- switch (bc->onumplan) {
- case NUMPLAN_INTERNATIONAL:
- misdn_cfg_get(bc->port, MISDN_CFG_INTERNATPREFIX, prefix, sizeof(prefix));
- break;
+ /* Add configured prefix to caller.number */
+ misdn_add_number_prefix(bc->port, bc->caller.number_type, bc->caller.number, sizeof(bc->caller.number));
- case NUMPLAN_NATIONAL:
- misdn_cfg_get(bc->port, MISDN_CFG_NATPREFIX, prefix, sizeof(prefix));
- break;
- default:
- break;
- }
-
- ast_copy_string(buf, bc->oad, sizeof(buf));
- snprintf(bc->oad, sizeof(bc->oad), "%s%s", prefix, buf);
-
- if (!ast_strlen_zero(bc->dad)) {
- ast_copy_string(bc->orig_dad, bc->dad, sizeof(bc->orig_dad));
+ if (ast_strlen_zero(bc->dialed.number) && !ast_strlen_zero(bc->keypad)) {
+ ast_copy_string(bc->dialed.number, bc->keypad, sizeof(bc->dialed.number));
}
- if (ast_strlen_zero(bc->dad) && !ast_strlen_zero(bc->keypad)) {
- ast_copy_string(bc->dad, bc->keypad, sizeof(bc->dad));
- }
+ /* Add configured prefix to dialed.number */
+ misdn_add_number_prefix(bc->port, bc->dialed.number_type, bc->dialed.number, sizeof(bc->dialed.number));
- prefix[0] = 0;
-
- switch (bc->dnumplan) {
- case NUMPLAN_INTERNATIONAL:
- misdn_cfg_get(bc->port, MISDN_CFG_INTERNATPREFIX, prefix, sizeof(prefix));
- break;
- case NUMPLAN_NATIONAL:
- misdn_cfg_get(bc->port, MISDN_CFG_NATPREFIX, prefix, sizeof(prefix));
- break;
- default:
- break;
- }
-
- ast_copy_string(buf, bc->dad, sizeof(buf));
- snprintf(bc->dad, sizeof(bc->dad), "%s%s", prefix, buf);
-
- if (strcmp(bc->dad, ast->exten)) {
- ast_copy_string(ast->exten, bc->dad, sizeof(ast->exten));
- }
-
- ast_set_callerid(ast, bc->oad, NULL, bc->oad);
-
- if ( !ast_strlen_zero(bc->rad) ) {
- if (ast->cid.cid_rdnis) {
- ast_free(ast->cid.cid_rdnis);
- }
- ast->cid.cid_rdnis = ast_strdup(bc->rad);
- }
+ ast_copy_string(ast->exten, bc->dialed.number, sizeof(ast->exten));
misdn_cfg_get(bc->port, MISDN_CFG_OVERLAP_DIAL, &ch->overlap_dial, sizeof(ch->overlap_dial));
ast_mutex_init(&ch->overlap_tv_lock);
@@ -2400,6 +2960,79 @@ static int read_config(struct chan_list *ch, int orig)
return 0;
}
+/*!
+ * \internal
+ * \brief Notify peer that the connected line has changed.
+ *
+ * \param ast Current Asterisk channel
+ * \param bc Associated B channel
+ * \param originator Who originally created this channel. ORG_AST or ORG_MISDN
+ *
+ * \return Nothing
+ */
+static void misdn_update_connected_line(struct ast_channel *ast, struct misdn_bchannel *bc, int originator)
+{
+ int number_type;
+
+ if (originator == ORG_MISDN) {
+ /* ORIGINATOR MISDN (incoming call) */
+
+ ast_copy_string(bc->connected.name, S_OR(ast->connected.id.name, ""), sizeof(bc->connected.name));
+ ast_copy_string(bc->connected.number, S_OR(ast->connected.id.number, ""), sizeof(bc->connected.number));
+ bc->connected.presentation = ast_to_misdn_pres(ast->connected.id.number_presentation);
+ bc->connected.screening = ast_to_misdn_screen(ast->connected.id.number_presentation);
+
+ misdn_cfg_get(bc->port, MISDN_CFG_CPNDIALPLAN, &number_type, sizeof(number_type));
+ if (number_type < 0) {
+ bc->connected.number_type = ast_to_misdn_ton(ast->connected.id.number_type);
+ bc->connected.number_plan = ast_to_misdn_plan(ast->connected.id.number_type);
+ } else {
+ /* Force us to send in CONNECT message */
+ bc->connected.number_type = number_type;
+ bc->connected.number_plan = NUMPLAN_ISDN;
+ }
+ debug_numtype(bc->port, bc->connected.number_type, "CTON");
+ } else {
+ /* ORIGINATOR Asterisk (outgoing call) */
+
+ ast_copy_string(bc->caller.name, S_OR(ast->connected.id.name, ""), sizeof(bc->caller.name));
+ ast_copy_string(bc->caller.number, S_OR(ast->connected.id.number, ""), sizeof(bc->caller.number));
+ bc->caller.presentation = ast_to_misdn_pres(ast->connected.id.number_presentation);
+ bc->caller.screening = ast_to_misdn_screen(ast->connected.id.number_presentation);
+
+ misdn_cfg_get(bc->port, MISDN_CFG_LOCALDIALPLAN, &number_type, sizeof(number_type));
+ if (number_type < 0) {
+ bc->caller.number_type = ast_to_misdn_ton(ast->connected.id.number_type);
+ bc->caller.number_plan = ast_to_misdn_plan(ast->connected.id.number_type);
+ } else {
+ /* Force us to send in SETUP message */
+ bc->caller.number_type = number_type;
+ bc->caller.number_plan = NUMPLAN_ISDN;
+ }
+ debug_numtype(bc->port, bc->caller.number_type, "LTON");
+ }
+}
+
+/*!
+ * \internal
+ * \brief Copy the redirecting info out of the Asterisk channel
+ *
+ * \param bc Associated B channel
+ * \param ast Current Asterisk channel
+ *
+ * \return Nothing
+ */
+static void misdn_copy_redirecting_from_ast(struct misdn_bchannel *bc, struct ast_channel *ast)
+{
+ ast_copy_string(bc->redirecting.from.name, S_OR(ast->redirecting.from.name, ""), sizeof(bc->redirecting.from.name));
+ ast_copy_string(bc->redirecting.from.number, S_OR(ast->cid.cid_rdnis, ""), sizeof(bc->redirecting.from.number));
+ bc->redirecting.from.presentation = ast_to_misdn_pres(ast->redirecting.from.number_presentation);
+ bc->redirecting.from.screening = ast_to_misdn_screen(ast->redirecting.from.number_presentation);
+ bc->redirecting.from.number_type = ast_to_misdn_ton(ast->redirecting.from.number_type);
+ bc->redirecting.from.number_plan = ast_to_misdn_plan(ast->redirecting.from.number_type);
+ bc->redirecting.reason = ast_to_misdn_reason(ast->redirecting.reason);
+}
+
/*****************************/
/*** AST Indications Start ***/
@@ -2411,22 +3044,17 @@ static int misdn_call(struct ast_channel *ast, char *dest, int timeout)
int r;
int exceed;
int bridging;
- struct chan_list *ch = MISDN_ASTERISK_TECH_PVT(ast);
+ int number_type;
+ struct chan_list *ch;
struct misdn_bchannel *newbc;
- char *dest_cp = ast_strdupa(dest);
+ char *dest_cp;
+
AST_DECLARE_APP_ARGS(args,
- AST_APP_ARG(type);
- AST_APP_ARG(ext);
- AST_APP_ARG(opts);
+ AST_APP_ARG(intf); /* The interface token is discarded. */
+ AST_APP_ARG(ext); /* extension token */
+ AST_APP_ARG(opts); /* options token */
);
- AST_NONSTANDARD_APP_ARGS(args, dest_cp, '/');
-
- if (ast_strlen_zero(args.ext)) {
- chan_misdn_log(0, 0, "misdn_call: No Extension given!\n");
- return -1;
- }
-
if (!ast) {
ast_log(LOG_WARNING, " --> ! misdn_call called on ast_channel *ast where ast == NULL\n");
return -1;
@@ -2439,47 +3067,74 @@ static int misdn_call(struct ast_channel *ast, char *dest, int timeout)
return -1;
}
+ ch = MISDN_ASTERISK_TECH_PVT(ast);
if (!ch) {
- ast_log(LOG_WARNING, " --> ! misdn_call called on %s, neither down nor reserved (or dest==NULL)\n", ast->name);
+ ast_log(LOG_WARNING, " --> ! misdn_call called on %s, chan_list *ch==NULL\n", ast->name);
ast->hangupcause = AST_CAUSE_NORMAL_TEMPORARY_FAILURE;
ast_setstate(ast, AST_STATE_DOWN);
return -1;
}
newbc = ch->bc;
-
if (!newbc) {
- ast_log(LOG_WARNING, " --> ! misdn_call called on %s, neither down nor reserved (or dest==NULL)\n", ast->name);
+ ast_log(LOG_WARNING, " --> ! misdn_call called on %s, newbc==NULL\n", ast->name);
ast->hangupcause = AST_CAUSE_NORMAL_TEMPORARY_FAILURE;
ast_setstate(ast, AST_STATE_DOWN);
return -1;
}
+ /*
+ * dest is ---v
+ * Dial(mISDN/g:group_name[/extension[/options]])
+ * Dial(mISDN/port[:preselected_channel][/extension[/options]])
+ *
+ * The dial extension could be empty if you are using MISDN_KEYPAD
+ * to control ISDN provider features.
+ */
+ dest_cp = ast_strdupa(dest);
+ AST_NONSTANDARD_APP_ARGS(args, dest_cp, '/');
+ if (!args.ext) {
+ args.ext = "";
+ }
+
port = newbc->port;
- if ((exceed = add_out_calls(port))) {
+ exceed = add_out_calls(port);
+ if (exceed != 0) {
char tmp[16];
snprintf(tmp, sizeof(tmp), "%d", exceed);
pbx_builtin_setvar_helper(ast, "MAX_OVERFLOW", tmp);
+ ast->hangupcause = AST_CAUSE_NORMAL_TEMPORARY_FAILURE;
+ ast_setstate(ast, AST_STATE_DOWN);
return -1;
}
chan_misdn_log(1, port, "* CALL: %s\n", dest);
- chan_misdn_log(2, port, " --> * dad:%s tech:%s ctx:%s\n", ast->exten, ast->name, ast->context);
+ chan_misdn_log(2, port, " --> * dialed:%s tech:%s context:%s\n", args.ext, ast->name, ast->context);
- chan_misdn_log(3, port, " --> * adding2newbc ext %s\n", ast->exten);
- if (ast->exten) {
- ast_copy_string(ast->exten, args.ext, sizeof(ast->exten));
- ast_copy_string(newbc->dad, args.ext, sizeof(newbc->dad));
- }
+ ast_copy_string(ast->exten, args.ext, sizeof(ast->exten));
+ ast_copy_string(newbc->dialed.number, args.ext, sizeof(newbc->dialed.number));
- ast_copy_string(newbc->rad, S_OR(ast->cid.cid_rdnis, ""), sizeof(newbc->rad));
+ if (ast_strlen_zero(newbc->caller.name) && !ast_strlen_zero(ast->connected.id.name)) {
+ ast_copy_string(newbc->caller.name, ast->connected.id.name, sizeof(newbc->caller.name));
+ chan_misdn_log(3, port, " --> * set caller:\"%s\" <%s>\n", newbc->caller.name, newbc->caller.number);
+ }
+ if (ast_strlen_zero(newbc->caller.number) && !ast_strlen_zero(ast->connected.id.number)) {
+ ast_copy_string(newbc->caller.number, ast->connected.id.number, sizeof(newbc->caller.number));
+ chan_misdn_log(3, port, " --> * set caller:\"%s\" <%s>\n", newbc->caller.name, newbc->caller.number);
+ }
- chan_misdn_log(3, port, " --> * adding2newbc callerid %s\n", ast->cid.cid_num);
- if (ast_strlen_zero(newbc->oad) && !ast_strlen_zero(ast->cid.cid_num)) {
- ast_copy_string(newbc->oad, ast->cid.cid_num, sizeof(newbc->oad));
+ misdn_cfg_get(port, MISDN_CFG_LOCALDIALPLAN, &number_type, sizeof(number_type));
+ if (number_type < 0) {
+ newbc->caller.number_type = ast_to_misdn_ton(ast->connected.id.number_type);
+ newbc->caller.number_plan = ast_to_misdn_plan(ast->connected.id.number_type);
+ } else {
+ /* Force us to send in SETUP message */
+ newbc->caller.number_type = number_type;
+ newbc->caller.number_plan = NUMPLAN_ISDN;
}
+ debug_numtype(port, newbc->caller.number_type, "LTON");
newbc->capability = ast->transfercapability;
pbx_builtin_setvar_helper(ast, "TRANSFERCAPABILITY", ast_transfercapability2str(newbc->capability));
@@ -2487,10 +3142,10 @@ static int misdn_call(struct ast_channel *ast, char *dest, int timeout)
chan_misdn_log(2, port, " --> * Call with flag Digital\n");
}
- /* update screening and presentation */
- update_config(ch, ORG_AST);
+ /* update caller screening and presentation */
+ update_config(ch);
- /* fill in some ies from channel vary */
+ /* fill in some ies from channel dialplan variables */
import_ch(ast, newbc, ch);
/* Finally The Options Override Everything */
@@ -2499,6 +3154,11 @@ static int misdn_call(struct ast_channel *ast, char *dest, int timeout)
} else {
chan_misdn_log(2, port, "NO OPTS GIVEN\n");
}
+ if (newbc->set_presentation) {
+ newbc->caller.presentation = newbc->presentation;
+ }
+
+ misdn_copy_redirecting_from_ast(newbc, ast);
/*check for bridging*/
misdn_cfg_get(0, MISDN_GEN_BRIDGING, &bridging, sizeof(bridging));
@@ -2519,7 +3179,7 @@ static int misdn_call(struct ast_channel *ast, char *dest, int timeout)
/** we should have l3id after sending setup **/
ch->l3id = newbc->l3_id;
- if (r == -ENOCHAN ) {
+ if (r == -ENOCHAN) {
chan_misdn_log(0, port, " --> * Theres no Channel at the moment .. !\n");
chan_misdn_log(1, port, " --> * SEND: State Down pid:%d\n", newbc ? newbc->pid : -1);
ast->hangupcause = AST_CAUSE_NORMAL_CIRCUIT_CONGESTION;
@@ -2585,9 +3245,19 @@ static int misdn_answer(struct ast_channel *ast)
p->state = MISDN_CONNECTED;
stop_indicate(p);
- if ( ast_strlen_zero(p->bc->cad) ) {
- chan_misdn_log(2, p->bc->port, " --> empty cad using dad\n");
- ast_copy_string(p->bc->cad, p->bc->dad, sizeof(p->bc->cad));
+ if (ast_strlen_zero(p->bc->connected.number)) {
+ chan_misdn_log(2,p->bc->port," --> empty connected number using dialed number\n");
+ ast_copy_string(p->bc->connected.number, p->bc->dialed.number, sizeof(p->bc->connected.number));
+
+ /*
+ * Use the misdn_set_opt() application to set the presentation
+ * before we answer or you can use the CONECTEDLINE() function
+ * to set everything before using the Answer() application.
+ */
+ p->bc->connected.presentation = p->bc->presentation;
+ p->bc->connected.screening = 0; /* unscreened */
+ p->bc->connected.number_type = p->bc->dialed.number_type;
+ p->bc->connected.number_plan = p->bc->dialed.number_plan;
}
misdn_lib_send_event(p->bc, EVENT_CONNECT);
@@ -2628,15 +3298,15 @@ static int misdn_digit_end(struct ast_channel *ast, char digit, unsigned int dur
break;
case MISDN_CALLING_ACKNOWLEDGE:
ast_copy_string(bc->info_dad, buf, sizeof(bc->info_dad));
- if (strlen(bc->dad) < sizeof(bc->dad) - 1) {
- strncat(bc->dad, buf, sizeof(bc->dad) - strlen(bc->dad) - 1);
+ if (strlen(bc->dialed.number) < sizeof(bc->dialed.number) - 1) {
+ strncat(bc->dialed.number, buf, sizeof(bc->dialed.number) - strlen(bc->dialed.number) - 1);
}
- ast_copy_string(p->ast->exten, bc->dad, sizeof(p->ast->exten));
+ ast_copy_string(p->ast->exten, bc->dialed.number, sizeof(p->ast->exten));
misdn_lib_send_event(bc, EVENT_INFORMATION);
break;
default:
/* Do not send Digits in CONNECTED State, when
- * the other side is too mISDN. */
+ * the other side is also mISDN. */
if (p->other_ch) {
return 0;
}
@@ -2687,7 +3357,7 @@ static int misdn_indication(struct ast_channel *ast, int cond, const void *data,
switch (cond) {
case AST_CONTROL_BUSY:
- chan_misdn_log(1, p->bc->port, "* IND :\tbusy pid:%d\n", p->bc ? p->bc->pid : -1);
+ chan_misdn_log(1, p->bc->port, "* IND :\tbusy pid:%d\n", p->bc->pid);
ast_setstate(ast, AST_STATE_BUSY);
p->bc->out_cause = AST_CAUSE_USER_BUSY;
@@ -2699,20 +3369,20 @@ static int misdn_indication(struct ast_channel *ast, int cond, const void *data,
}
return -1;
case AST_CONTROL_RING:
- chan_misdn_log(1, p->bc->port, "* IND :\tring pid:%d\n", p->bc ? p->bc->pid : -1);
+ chan_misdn_log(1, p->bc->port, "* IND :\tring pid:%d\n", p->bc->pid);
return -1;
case AST_CONTROL_RINGING:
- chan_misdn_log(1, p->bc->port, "* IND :\tringing pid:%d\n", p->bc ? p->bc->pid : -1);
+ chan_misdn_log(1, p->bc->port, "* IND :\tringing pid:%d\n", p->bc->pid);
switch (p->state) {
case MISDN_ALERTING:
- chan_misdn_log(2, p->bc->port, " --> * IND :\tringing pid:%d but I was Ringing before, so ignoring it\n", p->bc ? p->bc->pid : -1);
+ chan_misdn_log(2, p->bc->port, " --> * IND :\tringing pid:%d but I was Ringing before, so ignoring it\n", p->bc->pid);
break;
case MISDN_CONNECTED:
- chan_misdn_log(2, p->bc->port, " --> * IND :\tringing pid:%d but Connected, so just send TONE_ALERTING without state changes \n", p->bc ? p->bc->pid : -1);
+ chan_misdn_log(2, p->bc->port, " --> * IND :\tringing pid:%d but Connected, so just send TONE_ALERTING without state changes \n", p->bc->pid);
return -1;
default:
p->state = MISDN_ALERTING;
- chan_misdn_log(2, p->bc->port, " --> * IND :\tringing pid:%d\n", p->bc ? p->bc->pid : -1);
+ chan_misdn_log(2, p->bc->port, " --> * IND :\tringing pid:%d\n", p->bc->pid);
misdn_lib_send_event( p->bc, EVENT_ALERTING);
if (p->other_ch && p->other_ch->bc) {
@@ -2727,7 +3397,7 @@ static int misdn_indication(struct ast_channel *ast, int cond, const void *data,
}
}
- chan_misdn_log(3, p->bc->port, " --> * SEND: State Ring pid:%d\n", p->bc ? p->bc->pid : -1);
+ chan_misdn_log(3, p->bc->port, " --> * SEND: State Ring pid:%d\n", p->bc->pid);
ast_setstate(ast, AST_STATE_RING);
if (!p->bc->nt && (p->originator == ORG_MISDN) && !p->incoming_early_audio) {
@@ -2738,28 +3408,28 @@ static int misdn_indication(struct ast_channel *ast, int cond, const void *data,
}
break;
case AST_CONTROL_ANSWER:
- chan_misdn_log(1, p->bc->port, " --> * IND :\tanswer pid:%d\n", p->bc ? p->bc->pid : -1);
+ chan_misdn_log(1, p->bc->port, " --> * IND :\tanswer pid:%d\n", p->bc->pid);
start_bc_tones(p);
break;
case AST_CONTROL_TAKEOFFHOOK:
- chan_misdn_log(1, p->bc->port, " --> *\ttakeoffhook pid:%d\n", p->bc ? p->bc->pid : -1);
+ chan_misdn_log(1, p->bc->port, " --> *\ttakeoffhook pid:%d\n", p->bc->pid);
return -1;
case AST_CONTROL_OFFHOOK:
- chan_misdn_log(1, p->bc->port, " --> *\toffhook pid:%d\n", p->bc ? p->bc->pid : -1);
+ chan_misdn_log(1, p->bc->port, " --> *\toffhook pid:%d\n", p->bc->pid);
return -1;
case AST_CONTROL_FLASH:
- chan_misdn_log(1, p->bc->port, " --> *\tflash pid:%d\n", p->bc ? p->bc->pid : -1);
+ chan_misdn_log(1, p->bc->port, " --> *\tflash pid:%d\n", p->bc->pid);
break;
case AST_CONTROL_PROGRESS:
- chan_misdn_log(1, p->bc->port, " --> * IND :\tprogress pid:%d\n", p->bc ? p->bc->pid : -1);
+ chan_misdn_log(1, p->bc->port, " --> * IND :\tprogress pid:%d\n", p->bc->pid);
misdn_lib_send_event( p->bc, EVENT_PROGRESS);
break;
case AST_CONTROL_PROCEEDING:
- chan_misdn_log(1, p->bc->port, " --> * IND :\tproceeding pid:%d\n", p->bc ? p->bc->pid : -1);
+ chan_misdn_log(1, p->bc->port, " --> * IND :\tproceeding pid:%d\n", p->bc->pid);
misdn_lib_send_event( p->bc, EVENT_PROCEEDING);
break;
case AST_CONTROL_CONGESTION:
- chan_misdn_log(1, p->bc->port, " --> * IND :\tcongestion pid:%d\n", p->bc ? p->bc->pid : -1);
+ chan_misdn_log(1, p->bc->port, " --> * IND :\tcongestion pid:%d\n", p->bc->pid);
p->bc->out_cause = AST_CAUSE_SWITCH_CONGESTION;
start_bc_tones(p);
@@ -2770,7 +3440,7 @@ static int misdn_indication(struct ast_channel *ast, int cond, const void *data,
}
break;
case -1 :
- chan_misdn_log(1, p->bc->port, " --> * IND :\t-1! (stop indication) pid:%d\n", p->bc ? p->bc->pid : -1);
+ chan_misdn_log(1, p->bc->port, " --> * IND :\t-1! (stop indication) pid:%d\n", p->bc->pid);
stop_indicate(p);
@@ -2780,14 +3450,23 @@ static int misdn_indication(struct ast_channel *ast, int cond, const void *data,
break;
case AST_CONTROL_HOLD:
ast_moh_start(ast, data, p->mohinterpret);
- chan_misdn_log(1, p->bc->port, " --> *\tHOLD pid:%d\n", p->bc ? p->bc->pid : -1);
+ chan_misdn_log(1, p->bc->port, " --> *\tHOLD pid:%d\n", p->bc->pid);
break;
case AST_CONTROL_UNHOLD:
ast_moh_stop(ast);
- chan_misdn_log(1, p->bc->port, " --> *\tUNHOLD pid:%d\n", p->bc ? p->bc->pid : -1);
+ chan_misdn_log(1, p->bc->port, " --> *\tUNHOLD pid:%d\n", p->bc->pid);
+ break;
+ case AST_CONTROL_CONNECTED_LINE:
+ chan_misdn_log(1, p->bc->port, "* IND :\tconnected line update pid:%d\n", p->bc->pid);
+ misdn_update_connected_line(ast, p->bc, p->originator);
+ break;
+ case AST_CONTROL_REDIRECTING:
+ chan_misdn_log(1, p->bc->port, "* IND :\tredirecting info update pid:%d\n", p->bc->pid);
+ misdn_copy_redirecting_from_ast(p->bc, ast);
break;
default:
- chan_misdn_log(1, p->bc->port, " --> * Unknown Indication:%d pid:%d\n", cond, p->bc ? p->bc->pid : -1);
+ chan_misdn_log(1, p->bc->port, " --> * Unknown Indication:%d pid:%d\n", cond, p->bc->pid);
+ break;
}
return 0;
@@ -2814,8 +3493,10 @@ static int misdn_hangup(struct ast_channel *ast)
if (bc) {
const char *tmp;
+
ast_channel_lock(ast);
- if ((tmp = pbx_builtin_getvar_helper(ast, "MISDN_USERUSER"))) {
+ tmp = pbx_builtin_getvar_helper(ast, "MISDN_USERUSER");
+ if (tmp) {
ast_log(LOG_NOTICE, "MISDN_USERUSER: %s\n", tmp);
strcpy(bc->uu, tmp);
bc->uulen = strlen(bc->uu);
@@ -2875,11 +3556,17 @@ static int misdn_hangup(struct ast_channel *ast)
}
ast_channel_unlock(ast);
- chan_misdn_log(1, bc->port, "* IND : HANGUP\tpid:%d ctx:%s dad:%s oad:%s State:%s\n", p->bc ? p->bc->pid : -1, ast->context, ast->exten, ast->cid.cid_num, misdn_get_ch_state(p));
+ chan_misdn_log(1, bc->port,
+ "* IND : HANGUP\tpid:%d context:%s dialed:%s caller:\"%s\" <%s> State:%s\n",
+ p->bc ? p->bc->pid : -1,
+ ast->context,
+ ast->exten,
+ ast->cid.cid_name ? ast->cid.cid_name : "",
+ ast->cid.cid_num ? ast->cid.cid_num : "",
+ misdn_get_ch_state(p));
chan_misdn_log(3, bc->port, " --> l3id:%x\n", p->l3id);
chan_misdn_log(3, bc->port, " --> cause:%d\n", bc->cause);
chan_misdn_log(2, bc->port, " --> out_cause:%d\n", bc->out_cause);
- chan_misdn_log(2, bc->port, " --> state:%s\n", misdn_get_ch_state(p));
switch (p->state) {
case MISDN_INCOMING_SETUP:
@@ -3034,7 +3721,7 @@ static struct ast_frame *process_ast_dsp(struct chan_list *tmp, struct ast_frame
ast_log(LOG_WARNING, "Failed to async goto '%s' into fax of '%s'\n", ast->name, context);
}
} else {
- ast_log(LOG_NOTICE, "Fax detected, but no fax extension ctx:%s exten:%s\n", context, ast->exten);
+ ast_log(LOG_NOTICE, "Fax detected but no fax extension, context:%s exten:%s\n", context, ast->exten);
}
} else {
ast_debug(1, "Already in a fax extension, not redirecting\n");
@@ -3081,7 +3768,8 @@ static struct ast_frame *misdn_read(struct ast_channel *ast)
FD_ZERO(&rrfs);
FD_SET(tmp->pipe[0], &rrfs);
- if (!(t = select(FD_SETSIZE, &rrfs, NULL, NULL, &tv))) {
+ t = select(FD_SETSIZE, &rrfs, NULL, NULL, &tv);
+ if (!t) {
chan_misdn_log(3, tmp->bc->port, "read Select Timed out\n");
len = 160;
}
@@ -3249,15 +3937,11 @@ static int misdn_write(struct ast_channel *ast, struct ast_frame *frame)
return 0;
}
-
-
-
-static enum ast_bridge_result misdn_bridge (struct ast_channel *c0,
- struct ast_channel *c1, int flags,
- struct ast_frame **fo,
- struct ast_channel **rc,
- int timeoutms)
-
+static enum ast_bridge_result misdn_bridge(struct ast_channel *c0,
+ struct ast_channel *c1, int flags,
+ struct ast_frame **fo,
+ struct ast_channel **rc,
+ int timeoutms)
{
struct chan_list *ch1, *ch2;
struct ast_channel *carr[2], *who;
@@ -3293,7 +3977,11 @@ static enum ast_bridge_result misdn_bridge (struct ast_channel *c0,
ast_verb(3, "Native bridging %s and %s\n", c0->name, c1->name);
- chan_misdn_log(1, ch1->bc->port, "* Making Native Bridge between %s and %s\n", ch1->bc->oad, ch2->bc->oad);
+ chan_misdn_log(1, ch1->bc->port, "* Making Native Bridge between \"%s\" <%s> and \"%s\" <%s>\n",
+ ch1->bc->caller.name,
+ ch1->bc->caller.number,
+ ch2->bc->caller.name,
+ ch2->bc->caller.number);
if (! (flags & AST_BRIDGE_DTMF_CHANNEL_0) ) {
ch1->ignore_dtmf = 1;
@@ -3342,7 +4030,7 @@ static enum ast_bridge_result misdn_bridge (struct ast_channel *c0,
}
#endif
- ast_write(who == c0 ? c1 : c0, f);
+ ast_write((who == c0) ? c1 : c0, f);
}
chan_misdn_log(1, ch1->bc->port, "I SEND: Splitting conference with Number:%d\n", ch1->bc->pid + 1);
@@ -3437,7 +4125,8 @@ static struct chan_list *init_chan_list(int orig)
{
struct chan_list *cl;
- if (!(cl = ast_calloc(1, sizeof(*cl)))) {
+ cl = ast_calloc(1, sizeof(*cl));
+ if (!cl) {
chan_misdn_log(-1, 0, "misdn_request: malloc failed!");
return NULL;
}
@@ -3455,38 +4144,54 @@ static struct ast_channel *misdn_request(const char *type, int format, void *dat
{
struct ast_channel *tmp = NULL;
char group[BUFFERSIZE + 1] = "";
- char buf[128];
- char *buf2 = ast_strdupa(data), *ext = NULL, *port_str;
- char *tokb = NULL, *p = NULL;
- int channel = 0, port = 0;
+ char dial_str[128];
+ char *dest_cp;
+ char *p = NULL;
+ int channel = 0;
+ int port = 0;
struct misdn_bchannel *newbc = NULL;
int dec = 0;
+ struct chan_list *cl;
- struct chan_list *cl = init_chan_list(ORG_AST);
-
- snprintf(buf, sizeof(buf), "%s/%s", misdn_type, (char*)data);
+ AST_DECLARE_APP_ARGS(args,
+ AST_APP_ARG(intf); /* interface token */
+ AST_APP_ARG(ext); /* extension token */
+ AST_APP_ARG(opts); /* options token */
+ );
- port_str = strtok_r(buf2, "/", &tokb);
+ snprintf(dial_str, sizeof(dial_str), "%s/%s", misdn_type, (char *) data);
- ext = strtok_r(NULL, "/", &tokb);
+ /*
+ * data is ---v
+ * Dial(mISDN/g:group_name[/extension[/options]])
+ * Dial(mISDN/port[:preselected_channel][/extension[/options]])
+ *
+ * The dial extension could be empty if you are using MISDN_KEYPAD
+ * to control ISDN provider features.
+ */
+ dest_cp = ast_strdupa(data);
+ AST_NONSTANDARD_APP_ARGS(args, dest_cp, '/');
+ if (!args.ext) {
+ args.ext = "";
+ }
- if (port_str) {
- if (port_str[0] == 'g' && port_str[1] == ':' ) {
+ if (!ast_strlen_zero(args.intf)) {
+ if (args.intf[0] == 'g' && args.intf[1] == ':' ) {
/* We make a group call lets checkout which ports are in my group */
- port_str += 2;
- ast_copy_string(group, port_str, sizeof(group));
+ args.intf += 2;
+ ast_copy_string(group, args.intf, sizeof(group));
chan_misdn_log(2, 0, " --> Group Call group: %s\n", group);
- } else if ((p = strchr(port_str, ':'))) {
+ } else if ((p = strchr(args.intf, ':'))) {
/* we have a preselected channel */
- *p = 0;
- channel = atoi(++p);
- port = atoi(port_str);
+ *p++ = 0;
+ channel = atoi(p);
+ port = atoi(args.intf);
chan_misdn_log(2, port, " --> Call on preselected Channel (%d).\n", channel);
} else {
- port = atoi(port_str);
+ port = atoi(args.intf);
}
} else {
- ast_log(LOG_WARNING, " --> ! IND : CALL dad:%s WITHOUT PORT/Group, check extensions.conf\n", ext);
+ ast_log(LOG_WARNING, " --> ! IND : Dial(%s) WITHOUT Port or Group, check extensions.conf\n", dial_str);
return NULL;
}
@@ -3579,7 +4284,8 @@ static struct ast_channel *misdn_request(const char *type, int format, void *dat
chan_misdn_log(4, port, "portup:%d\n", port_up);
if (port_up > 0) {
- if ((newbc = misdn_lib_get_free_bc(port, 0, 0, dec))) {
+ newbc = misdn_lib_get_free_bc(port, 0, 0, dec);
+ if (newbc) {
break;
}
}
@@ -3602,18 +4308,22 @@ static struct ast_channel *misdn_request(const char *type, int format, void *dat
chan_misdn_log(1, port, " --> preselected_channel: %d\n", channel);
}
newbc = misdn_lib_get_free_bc(port, channel, 0, dec);
-
if (!newbc) {
- ast_log(LOG_WARNING, "Could not create channel on port:%d with extensions:%s\n", port, ext);
+ ast_log(LOG_WARNING, "Could not create channel on port:%d for Dial(%s)\n", port, dial_str);
return NULL;
}
}
/* create ast_channel and link all the objects together */
+ cl = init_chan_list(ORG_AST);
+ if (!cl) {
+ ast_log(LOG_WARNING, "Could not create Asterisk channel for Dial(%s)\n", dial_str);
+ return NULL;
+ }
cl->bc = newbc;
- tmp = misdn_new(cl, AST_STATE_RESERVED, ext, NULL, format, port, channel);
+ tmp = misdn_new(cl, AST_STATE_RESERVED, args.ext, NULL, format, port, channel);
if (!tmp) {
ast_log(LOG_ERROR, "Could not create Asterisk object\n");
return NULL;
@@ -3625,7 +4335,7 @@ static struct ast_channel *misdn_request(const char *type, int format, void *dat
cl_queue_chan(&cl_te, cl);
/* fill in the config into the objects */
- read_config(cl, ORG_AST);
+ read_config(cl);
/* important */
cl->need_hangup = 0;
@@ -3736,7 +4446,7 @@ static struct ast_channel *misdn_new(struct chan_list *chlist, int state, char
tmp = ast_channel_alloc(1, state, cid_num, cid_name, "", exten, "", 0, "%s/%s%d-u%d", misdn_type, c ? "" : "tmp", chan_offset + c, glob_channel++);
if (tmp) {
- chan_misdn_log(2, 0, " --> * NEW CHANNEL dad:%s oad:%s\n", exten, callerid);
+ chan_misdn_log(2, 0, " --> * NEW CHANNEL dialed:%s caller:%s\n", exten, callerid);
tmp->nativeformats = prefformat;
@@ -3791,7 +4501,11 @@ static struct chan_list *find_chan_by_bc(struct chan_list *list, struct misdn_bc
}
}
- chan_misdn_log(6, bc->port, "$$$ find_chan: No channel found for oad:%s dad:%s\n", bc->oad, bc->dad);
+ chan_misdn_log(6, bc->port,
+ "$$$ find_chan_by_bc: No channel found for dialed:%s caller:\"%s\" <%s>\n",
+ bc->dialed.number,
+ bc->caller.name,
+ bc->caller.number);
return NULL;
}
@@ -3805,7 +4519,7 @@ static struct chan_list *find_chan_by_pid(struct chan_list *list, int pid)
}
}
- chan_misdn_log(6, 0, "$$$ find_chan: No channel found for pid:%d\n", pid);
+ chan_misdn_log(6, 0, "$$$ find_chan_by_pid: No channel found for pid:%d\n", pid);
return NULL;
}
@@ -3818,7 +4532,11 @@ static struct chan_list *find_holded(struct chan_list *list, struct misdn_bchann
return NULL;
}
- chan_misdn_log(6, bc->port, "$$$ find_holded: channel:%d oad:%s dad:%s\n", bc->channel, bc->oad, bc->dad);
+ chan_misdn_log(6, bc->port, "$$$ find_holded: channel:%d dialed:%s caller:\"%s\" <%s>\n",
+ bc->channel,
+ bc->dialed.number,
+ bc->caller.name,
+ bc->caller.number);
for (; help; help = help->next) {
chan_misdn_log(4, bc->port, "$$$ find_holded: --> holded:%d channel:%d\n", help->state == MISDN_HOLDED, help->hold_info.channel);
if ((help->state == MISDN_HOLDED) &&
@@ -3826,7 +4544,11 @@ static struct chan_list *find_holded(struct chan_list *list, struct misdn_bchann
return help;
}
}
- chan_misdn_log(6, bc->port, "$$$ find_chan: No channel found for oad:%s dad:%s\n", bc->oad, bc->dad);
+ chan_misdn_log(6, bc->port,
+ "$$$ find_holded: No channel found for dialed:%s caller:\"%s\" <%s>\n",
+ bc->dialed.number,
+ bc->caller.name,
+ bc->caller.number);
return NULL;
}
@@ -3947,12 +4669,14 @@ static void hangup_chan(struct chan_list *ch)
}
/** Isdn asks us to release channel, pendant to misdn_hangup **/
-static void release_chan(struct misdn_bchannel *bc) {
+static void release_chan(struct misdn_bchannel *bc)
+{
struct ast_channel *ast = NULL;
struct chan_list *ch;
ast_mutex_lock(&release_lock);
- if (!(ch = find_chan_by_bc(cl_te, bc))) {
+ ch = find_chan_by_bc(cl_te, bc);
+ if (!ch) {
chan_misdn_log(1, bc->port, "release_chan: Ch not found!\n");
ast_mutex_unlock(&release_lock);
return;
@@ -3965,7 +4689,7 @@ static void release_chan(struct misdn_bchannel *bc) {
chan_misdn_log(5, bc->port, "release_chan: bc with l3id: %x\n", bc->l3_id);
/* releasing jitterbuffer */
- if (ch->jb ) {
+ if (ch->jb) {
misdn_jb_destroy(ch->jb);
ch->jb = NULL;
} else {
@@ -3993,7 +4717,14 @@ static void release_chan(struct misdn_bchannel *bc) {
close(ch->pipe[1]);
if (ast && MISDN_ASTERISK_TECH_PVT(ast)) {
- chan_misdn_log(1, bc->port, "* RELEASING CHANNEL pid:%d ctx:%s dad:%s oad:%s state: %s\n", bc ? bc->pid : -1, ast->context, ast->exten, ast->cid.cid_num, misdn_get_ch_state(ch));
+ chan_misdn_log(1, bc->port,
+ "* RELEASING CHANNEL pid:%d context:%s dialed:%s caller:\"%s\" <%s> state: %s\n",
+ bc->pid,
+ ast->context,
+ ast->exten,
+ ast->cid.cid_name ? ast->cid.cid_name : "",
+ ast->cid.cid_num ? ast->cid.cid_num : "",
+ misdn_get_ch_state(ch));
chan_misdn_log(3, bc->port, " --> * State Down\n");
MISDN_ASTERISK_TECH_PVT(ast) = NULL;
@@ -4053,9 +4784,14 @@ static void do_immediate_setup(struct misdn_bchannel *bc, struct chan_list *ch,
ch->state = MISDN_INCOMING_SETUP;
}
- chan_misdn_log(1, bc->port, "* Starting Ast ctx:%s dad:%s oad:%s with 's' extension\n", ast->context, ast->exten, ast->cid.cid_num);
+ chan_misdn_log(1, bc->port,
+ "* Starting Ast context:%s dialed:%s caller:\"%s\" <%s> with 's' extension\n",
+ ast->context,
+ ast->exten,
+ ast->cid.cid_name ? ast->cid.cid_name : "",
+ ast->cid.cid_num ? ast->cid.cid_num : "");
- strncpy(ast->exten, "s", 2);
+ strcpy(ast->exten, "s");
if (pbx_start_chan(ch) < 0) {
ast = NULL;
@@ -4183,6 +4919,7 @@ void import_ch(struct ast_channel *chan, struct misdn_bchannel *bc, struct chan_
void export_ch(struct ast_channel *chan, struct misdn_bchannel *bc, struct chan_list *ch)
{
char tmp[32];
+
chan_misdn_log(3, bc->port, " --> EXPORT_PID: pid:%d\n", bc->pid);
snprintf(tmp, sizeof(tmp), "%d", bc->pid);
pbx_builtin_setvar_helper(chan, "_MISDN_PID", tmp);
@@ -4237,7 +4974,8 @@ int add_out_calls(int port)
return 0;
}
-static void start_pbx(struct chan_list *ch, struct misdn_bchannel *bc, struct ast_channel *chan) {
+static void start_pbx(struct chan_list *ch, struct misdn_bchannel *bc, struct ast_channel *chan)
+{
if (pbx_start_chan(ch) < 0) {
hangup_chan(ch);
chan_misdn_log(-1, bc->port, "ast_pbx_start returned <0 in SETUP\n");
@@ -4250,10 +4988,11 @@ static void start_pbx(struct chan_list *ch, struct misdn_bchannel *bc, struct as
}
}
-static void wait_for_digits(struct chan_list *ch, struct misdn_bchannel *bc, struct ast_channel *chan) {
+static void wait_for_digits(struct chan_list *ch, struct misdn_bchannel *bc, struct ast_channel *chan)
+{
ch->state = MISDN_WAITING4DIGS;
misdn_lib_send_event(bc, EVENT_SETUP_ACKNOWLEDGE );
- if (bc->nt && !bc->dad[0]) {
+ if (bc->nt && !bc->dialed.number[0]) {
dialtone_indicate(ch);
}
}
@@ -4273,7 +5012,14 @@ cb_events(enum event_e event, struct misdn_bchannel *bc, void *user_data)
debuglevel = 5;
}
- chan_misdn_log(debuglevel, bc->port, "I IND :%s oad:%s dad:%s pid:%d state:%s\n", manager_isdn_get_info(event), bc->oad, bc->dad, bc->pid, ch ? misdn_get_ch_state(ch) : "none");
+ chan_misdn_log(debuglevel, bc->port,
+ "I IND :%s caller:\"%s\" <%s> dialed:%s pid:%d state:%s\n",
+ manager_isdn_get_info(event),
+ bc->caller.name,
+ bc->caller.number,
+ bc->dialed.number,
+ bc->pid,
+ ch ? misdn_get_ch_state(ch) : "none");
if (debuglevel == 1) {
misdn_lib_log_ies(bc);
chan_misdn_log(4, bc->port, " --> bc_state:%s\n", bc_state2str(bc->bc_state));
@@ -4407,25 +5153,23 @@ cb_events(enum event_e event, struct misdn_bchannel *bc, void *user_data)
ast_copy_string(bc->info_dad, bc->keypad, sizeof(bc->info_dad));
}
- strncat(bc->dad, bc->info_dad, sizeof(bc->dad) - strlen(bc->dad) - 1);
- ast_copy_string(ch->ast->exten, bc->dad, sizeof(ch->ast->exten));
+ strncat(bc->dialed.number, bc->info_dad, sizeof(bc->dialed.number) - strlen(bc->dialed.number) - 1);
+ ast_copy_string(ch->ast->exten, bc->dialed.number, sizeof(ch->ast->exten));
/* Check for Pickup Request first */
if (!strcmp(ch->ast->exten, ast_pickup_ext())) {
if (ast_pickup_call(ch->ast)) {
hangup_chan(ch);
} else {
- struct ast_channel *chan = ch->ast;
ch->state = MISDN_CALLING_ACKNOWLEDGE;
- ast_setstate(chan, AST_STATE_DOWN);
hangup_chan(ch);
ch->ast = NULL;
break;
}
}
- if (!ast_canmatch_extension(ch->ast, ch->context, bc->dad, 1, bc->oad)) {
- if (ast_exists_extension(ch->ast, ch->context, "i", 1, bc->oad)) {
+ if (!ast_canmatch_extension(ch->ast, ch->context, bc->dialed.number, 1, bc->caller.number)) {
+ if (ast_exists_extension(ch->ast, ch->context, "i", 1, bc->caller.number)) {
ast_log(LOG_WARNING, "Extension can never match, So jumping to 'i' extension. port(%d)\n", bc->port);
strcpy(ch->ast->exten, "i");
@@ -4459,7 +5203,7 @@ cb_events(enum event_e event, struct misdn_bchannel *bc, void *user_data)
break;
}
- if (ast_exists_extension(ch->ast, ch->context, bc->dad, 1, bc->oad)) {
+ if (ast_exists_extension(ch->ast, ch->context, bc->dialed.number, 1, bc->caller.number)) {
ch->state = MISDN_DIALING;
start_pbx(ch, bc, ch->ast);
}
@@ -4482,8 +5226,8 @@ cb_events(enum event_e event, struct misdn_bchannel *bc, void *user_data)
misdn_cfg_get(0, MISDN_GEN_APPEND_DIGITS2EXTEN, &digits, sizeof(digits));
if (ch->state != MISDN_CONNECTED ) {
if (digits) {
- strncat(bc->dad, bc->info_dad, sizeof(bc->dad) - strlen(bc->dad) - 1);
- ast_copy_string(ch->ast->exten, bc->dad, sizeof(ch->ast->exten));
+ strncat(bc->dialed.number, bc->info_dad, sizeof(bc->dialed.number) - strlen(bc->dialed.number) - 1);
+ ast_copy_string(ch->ast->exten, bc->dialed.number, sizeof(ch->ast->exten));
ast_cdr_update(ch->ast);
}
@@ -4494,10 +5238,9 @@ cb_events(enum event_e event, struct misdn_bchannel *bc, void *user_data)
case EVENT_SETUP:
{
struct chan_list *ch = find_chan_by_bc(cl_te, bc);
- int msn_valid = misdn_cfg_is_msn_valid(bc->port, bc->dad);
+ int msn_valid = misdn_cfg_is_msn_valid(bc->port, bc->dialed.number);
struct ast_channel *chan;
int exceed;
- int pres, screen;
int ai;
int im;
@@ -4537,10 +5280,8 @@ cb_events(enum event_e event, struct misdn_bchannel *bc, void *user_data)
ch->bc = bc;
ch->l3id = bc->l3_id;
ch->addr = bc->addr;
- ch->originator = ORG_MISDN;
-
- chan = misdn_new(ch, AST_STATE_RESERVED, bc->dad, bc->oad, AST_FORMAT_ALAW, bc->port, bc->channel);
+ chan = misdn_new(ch, AST_STATE_RESERVED, bc->dialed.number, bc->caller.number, AST_FORMAT_ALAW, bc->port, bc->channel);
if (!chan) {
misdn_lib_send_event(bc,EVENT_RELEASE_COMPLETE);
ast_log(LOG_ERROR, "cb_events: misdn_new failed !\n");
@@ -4555,49 +5296,44 @@ cb_events(enum event_e event, struct misdn_bchannel *bc, void *user_data)
pbx_builtin_setvar_helper(chan, "MAX_OVERFLOW", tmp);
}
- read_config(ch, ORG_MISDN);
+ read_config(ch);
export_ch(chan, bc, ch);
ch->ast->rings = 1;
ast_setstate(ch->ast, AST_STATE_RINGING);
- switch (bc->pres) {
- case 1:
- pres = AST_PRES_RESTRICTED;
- chan_misdn_log(2, bc->port, " --> PRES: Restricted (1)\n");
- break;
- case 2:
- pres = AST_PRES_UNAVAILABLE;
- chan_misdn_log(2, bc->port, " --> PRES: Unavailable (2)\n");
- break;
- default:
- pres = AST_PRES_ALLOWED;
- chan_misdn_log(2, bc->port, " --> PRES: Allowed (%d)\n", bc->pres);
- break;
- }
+ /* Update asterisk channel caller information */
+ chan_misdn_log(2, bc->port, " --> TON: %s(%d)\n", misdn_to_str_ton(bc->caller.number_type), bc->caller.number_type);
+ chan_misdn_log(2, bc->port, " --> PLAN: %s(%d)\n", misdn_to_str_plan(bc->caller.number_plan), bc->caller.number_plan);
+ chan->cid.cid_ton = misdn_to_ast_ton(bc->caller.number_type)
+ | misdn_to_ast_plan(bc->caller.number_plan);
- switch (bc->screen) {
- default:
- case 0:
- screen = AST_PRES_USER_NUMBER_UNSCREENED;
- chan_misdn_log(2, bc->port, " --> SCREEN: Unscreened (%d)\n", bc->screen);
- break;
- case 1:
- screen = AST_PRES_USER_NUMBER_PASSED_SCREEN;
- chan_misdn_log(2, bc->port, " --> SCREEN: Passed screen (1)\n");
- break;
- case 2:
- screen = AST_PRES_USER_NUMBER_FAILED_SCREEN;
- chan_misdn_log(2, bc->port, " --> SCREEN: failed screen (2)\n");
- break;
- case 3:
- screen = AST_PRES_NETWORK_NUMBER;
- chan_misdn_log(2, bc->port, " --> SCREEN: Network Number (3)\n");
- break;
- }
+ chan_misdn_log(2, bc->port, " --> PRES: %s(%d)\n", misdn_to_str_pres(bc->caller.presentation), bc->caller.presentation);
+ chan_misdn_log(2, bc->port, " --> SCREEN: %s(%d)\n", misdn_to_str_screen(bc->caller.screening), bc->caller.screening);
+ chan->cid.cid_pres = misdn_to_ast_pres(bc->caller.presentation)
+ | misdn_to_ast_screen(bc->caller.screening);
+
+ ast_set_callerid(chan, bc->caller.number, NULL, bc->caller.number);
+
+ if (!ast_strlen_zero(bc->redirecting.from.number)) {
+ struct ast_party_redirecting redirecting;
- chan->cid.cid_pres = pres | screen;
+ /* Add configured prefix to redirecting.from.number */
+ misdn_add_number_prefix(bc->port, bc->redirecting.from.number_type, bc->redirecting.from.number, sizeof(bc->redirecting.from.number));
+
+ /* Update asterisk channel redirecting information */
+ ast_party_redirecting_set_init(&redirecting, &chan->redirecting);
+ redirecting.from.number = bc->redirecting.from.number;
+ redirecting.from.number_type =
+ misdn_to_ast_ton(bc->redirecting.from.number_type)
+ | misdn_to_ast_plan(bc->redirecting.from.number_plan);
+ redirecting.from.number_presentation =
+ misdn_to_ast_pres(bc->redirecting.from.presentation)
+ | misdn_to_ast_screen(bc->redirecting.from.screening);
+ redirecting.reason = misdn_to_ast_reason(bc->redirecting.reason);
+ ast_channel_set_redirecting(chan, &redirecting);
+ }
pbx_builtin_setvar_helper(chan, "TRANSFERCAPABILITY", ast_transfercapability2str(bc->capability));
chan->transfercapability = bc->capability;
@@ -4627,7 +5363,7 @@ cb_events(enum event_e event, struct misdn_bchannel *bc, void *user_data)
break;
}
}
- } /* end for */
+ }
if (i == ARRAY_LEN(allowed_bearers_array)) {
/* We did not find the bearer capability */
chan_misdn_log(0, bc->port, "Bearer capability not allowed: %s(%d)\n",
@@ -4652,7 +5388,6 @@ cb_events(enum event_e event, struct misdn_bchannel *bc, void *user_data)
hangup_chan(ch);
} else {
ch->state = MISDN_CALLING_ACKNOWLEDGE;
- ast_setstate(chan, AST_STATE_DOWN);
hangup_chan(ch);
ch->ast = NULL;
break;
@@ -4669,16 +5404,16 @@ cb_events(enum event_e event, struct misdn_bchannel *bc, void *user_data)
break;
}
- /* check if we should jump into s when we have no dad */
+ /* check if we should jump into s when we have no dialed.number */
misdn_cfg_get(bc->port, MISDN_CFG_IMMEDIATE, &im, sizeof(im));
- if (im && ast_strlen_zero(bc->dad)) {
+ if (im && ast_strlen_zero(bc->dialed.number)) {
do_immediate_setup(bc, ch, chan);
break;
}
chan_misdn_log(5, bc->port, "CONTEXT:%s\n", ch->context);
- if (!ast_canmatch_extension(ch->ast, ch->context, bc->dad, 1, bc->oad)) {
- if (ast_exists_extension(ch->ast, ch->context, "i", 1, bc->oad)) {
+ if (!ast_canmatch_extension(ch->ast, ch->context, bc->dialed.number, 1, bc->caller.number)) {
+ if (ast_exists_extension(ch->ast, ch->context, "i", 1, bc->caller.number)) {
ast_log(LOG_WARNING, "Extension can never match, So jumping to 'i' extension. port(%d)\n", bc->port);
strcpy(ch->ast->exten, "i");
misdn_lib_send_event(bc, EVENT_SETUP_ACKNOWLEDGE);
@@ -4722,7 +5457,7 @@ cb_events(enum event_e event, struct misdn_bchannel *bc, void *user_data)
* the number is empty, we wait for the ISDN timeout
* instead of our own timer.
*/
- if (ch->overlap_dial && bc->nt && !bc->dad[0] ) {
+ if (ch->overlap_dial && bc->nt && !bc->dialed.number[0] ) {
wait_for_digits(ch, bc, chan);
break;
}
@@ -4747,7 +5482,7 @@ cb_events(enum event_e event, struct misdn_bchannel *bc, void *user_data)
/* If the extension does not exist and we're not TE_PTMP we wait for more digits
* without interdigit timeout.
* */
- if (!ast_exists_extension(ch->ast, ch->context, bc->dad, 1, bc->oad)) {
+ if (!ast_exists_extension(ch->ast, ch->context, bc->dialed.number, 1, bc->caller.number)) {
wait_for_digits(ch, bc, chan);
break;
}
@@ -4755,29 +5490,30 @@ cb_events(enum event_e event, struct misdn_bchannel *bc, void *user_data)
/*
* If the extension exists let's just jump into it.
* */
- if (ast_exists_extension(ch->ast, ch->context, bc->dad, 1, bc->oad)) {
+ if (ast_exists_extension(ch->ast, ch->context, bc->dialed.number, 1, bc->caller.number)) {
misdn_lib_send_event(bc, bc->need_more_infos ? EVENT_SETUP_ACKNOWLEDGE : EVENT_PROCEEDING);
ch->state = MISDN_DIALING;
start_pbx(ch, bc, chan);
break;
}
- }
break;
+ }
case EVENT_SETUP_ACKNOWLEDGE:
ch->state = MISDN_CALLING_ACKNOWLEDGE;
- if (bc->channel)
+ if (bc->channel) {
update_name(ch->ast,bc->port,bc->channel);
+ }
if (!ast_strlen_zero(bc->infos_pending)) {
/* TX Pending Infos */
- strncat(bc->dad, bc->infos_pending, sizeof(bc->dad) - strlen(bc->dad) - 1);
+ strncat(bc->dialed.number, bc->infos_pending, sizeof(bc->dialed.number) - strlen(bc->dialed.number) - 1);
if (!ch->ast) {
break;
}
- ast_copy_string(ch->ast->exten, bc->dad, sizeof(ch->ast->exten));
+ ast_copy_string(ch->ast->exten, bc->dialed.number, sizeof(ch->ast->exten));
ast_copy_string(bc->info_dad, bc->infos_pending, sizeof(bc->info_dad));
ast_copy_string(bc->infos_pending, "", sizeof(bc->infos_pending));
@@ -4842,29 +5578,31 @@ cb_events(enum event_e event, struct misdn_bchannel *bc, void *user_data)
}
break;
case EVENT_CONNECT:
- {
- struct ast_channel *bridged;
+ {
+ struct ast_party_connected_line connected;
- /*we answer when we've got our very new L3 ID from the NT stack */
- misdn_lib_send_event(bc, EVENT_CONNECT_ACKNOWLEDGE);
+ /* we answer when we've got our very new L3 ID from the NT stack */
+ misdn_lib_send_event(bc, EVENT_CONNECT_ACKNOWLEDGE);
- if (!ch->ast) {
- break;
- }
+ if (!ch->ast) {
+ break;
+ }
- bridged = ast_bridged_channel(ch->ast);
- stop_indicate(ch);
+ stop_indicate(ch);
- if (bridged && !strcasecmp(bridged->tech->type, "mISDN")) {
- struct chan_list *bridged_ch = MISDN_ASTERISK_TECH_PVT(bridged);
+ /* Add configured prefix to connected.number */
+ misdn_add_number_prefix(bc->port, bc->connected.number_type, bc->connected.number, sizeof(bc->connected.number));
+
+ /* Update the connected line information on the other channel */
+ ast_party_connected_line_init(&connected);
+ connected.id.number = bc->connected.number;
+ connected.id.number_type = misdn_to_ast_ton(bc->connected.number_type)
+ | misdn_to_ast_plan(bc->connected.number_plan);
+ connected.id.number_presentation = misdn_to_ast_pres(bc->connected.presentation)
+ | misdn_to_ast_screen(bc->connected.screening);
+ connected.source = AST_CONNECTED_LINE_UPDATE_SOURCE_ANSWER;
+ ast_channel_queue_connected_line_update(ch->ast, &connected);
- chan_misdn_log(1, bc->port, " --> copying cpndialplan:%d and cad:%s to the A-Channel\n", bc->cpnnumplan, bc->cad);
- if (bridged_ch) {
- bridged_ch->bc->cpnnumplan = bc->cpnnumplan;
- ast_copy_string(bridged_ch->bc->cad, bc->cad, sizeof(bridged_ch->bc->cad));
- }
- }
- }
ch->l3id = bc->l3_id;
ch->addr = bc->addr;
@@ -4874,6 +5612,7 @@ cb_events(enum event_e event, struct misdn_bchannel *bc, void *user_data)
ast_queue_control(ch->ast, AST_CONTROL_ANSWER);
break;
+ }
case EVENT_CONNECT_ACKNOWLEDGE:
ch->l3id = bc->l3_id;
ch->addr = bc->addr;
@@ -4947,8 +5686,9 @@ cb_events(enum event_e event, struct misdn_bchannel *bc, void *user_data)
stop_bc_tones(ch);
hangup_chan(ch);
- if (ch)
+ if (ch) {
ch->state = MISDN_CLEANING;
+ }
release_chan(bc);
break;
@@ -5003,16 +5743,16 @@ cb_events(enum event_e event, struct misdn_bchannel *bc, void *user_data)
} else {
bc->tone_cnt = 0;
}
- }
break;
-
+ }
case EVENT_BCHAN_DATA:
if (ch->bc->AOCD_need_export) {
export_aoc_vars(ch->originator, ch->ast, ch->bc);
}
if (!misdn_cap_is_speech(ch->bc->capability)) {
struct ast_frame frame;
- /*In Data Modes we queue frames*/
+
+ /* In Data Modes we queue frames */
frame.frametype = AST_FRAME_VOICE; /* we have no data frames yet */
frame.subclass = AST_FORMAT_ALAW;
frame.datalen = bc->bframe_len;
@@ -5023,8 +5763,9 @@ cb_events(enum event_e event, struct misdn_bchannel *bc, void *user_data)
frame.src = NULL;
frame.data.ptr = bc->bframe;
- if (ch->ast)
+ if (ch->ast) {
ast_queue_frame(ch->ast, &frame);
+ }
} else {
fd_set wrfs;
struct timeval tv = { 0, 0 };
@@ -5099,6 +5840,7 @@ cb_events(enum event_e event, struct misdn_bchannel *bc, void *user_data)
break;
default:
misdn_lib_send_event(bc, EVENT_RELEASE_COMPLETE);
+ break;
}
break;
@@ -5137,8 +5879,8 @@ cb_events(enum event_e event, struct misdn_bchannel *bc, void *user_data)
chan_misdn_log(4, bc->port, " --> RETRIEVE_ACK failed\n");
misdn_lib_send_event(bc, EVENT_RETRIEVE_REJECT);
}
- }
break;
+ }
case EVENT_HOLD:
{
int hold_allowed;
@@ -5171,8 +5913,8 @@ cb_events(enum event_e event, struct misdn_bchannel *bc, void *user_data)
misdn_lib_send_event(bc, EVENT_HOLD_REJECT);
chan_misdn_log(0, bc->port, "We aren't bridged to anybody\n");
}
- }
break;
+ }
case EVENT_FACILITY:
print_facility(&(bc->fac_in), bc);
@@ -5189,7 +5931,7 @@ cb_events(enum event_e event, struct misdn_bchannel *bc, void *user_data)
ch_br = MISDN_ASTERISK_TECH_PVT(bridged);
/*ch->state = MISDN_FACILITY_DEFLECTED;*/
if (ch_br->bc) {
- if (ast_exists_extension(bridged, ch->context, (char *)bc->fac_in.u.CDeflection.DeflectedToNumber, 1, bc->oad)) {
+ if (ast_exists_extension(bridged, ch->context, (char *) bc->fac_in.u.CDeflection.DeflectedToNumber, 1, bc->caller.number)) {
ch_br->state = MISDN_DIALING;
if (pbx_start_chan(ch_br) < 0) {
chan_misdn_log(-1, ch_br->bc->port, "ast_pbx_start returned < 0 in misdn_overlap_dial_task\n");
@@ -5461,6 +6203,7 @@ static int misdn_facility_exec(struct ast_channel *chan, void *data)
{
struct chan_list *ch = MISDN_ASTERISK_TECH_PVT(chan);
char *parse;
+
AST_DECLARE_APP_ARGS(args,
AST_APP_ARG(facility_type);
AST_APP_ARG(arg)[99];
@@ -5473,7 +6216,7 @@ static int misdn_facility_exec(struct ast_channel *chan, void *data)
return -1;
}
- if (ast_strlen_zero((char *)data)) {
+ if (ast_strlen_zero((char *) data)) {
ast_log(LOG_WARNING, "misdn_facility requires arguments: facility_type[,<args>]\n");
return -1;
}
@@ -5492,7 +6235,9 @@ static int misdn_facility_exec(struct ast_channel *chan, void *data)
}
if (strlen(args.arg[0]) >= sizeof(ch->bc->fac_out.u.CDeflection.DeflectedToNumber)) {
- ast_log(LOG_WARNING, "Facility: Number argument too long (up to %d digits are allowed). Ignoring.\n", (int)sizeof(ch->bc->fac_out.u.CDeflection.DeflectedToNumber));
+ ast_log(LOG_WARNING,
+ "Facility: Number argument too long (up to %d digits are allowed). Ignoring.\n",
+ (int) sizeof(ch->bc->fac_out.u.CDeflection.DeflectedToNumber));
return 0;
}
ch->bc->fac_out.Function = Fac_CD;
@@ -5516,11 +6261,11 @@ static int misdn_check_l2l1(struct ast_channel *chan, void *data)
int port_up;
AST_DECLARE_APP_ARGS(args,
- AST_APP_ARG(grouppar);
- AST_APP_ARG(timeout);
+ AST_APP_ARG(grouppar);
+ AST_APP_ARG(timeout);
);
- if (ast_strlen_zero((char *)data)) {
+ if (ast_strlen_zero((char *) data)) {
ast_log(LOG_WARNING, "misdn_check_l2l1 Requires arguments\n");
return -1;
}
@@ -5543,7 +6288,7 @@ static int misdn_check_l2l1(struct ast_channel *chan, void *data)
ast_copy_string(group, port_str, sizeof(group));
chan_misdn_log(2, 0, "Checking Ports in group: %s\n", group);
- for ( port = misdn_cfg_get_next_port(port);
+ for (port = misdn_cfg_get_next_port(port);
port > 0;
port = misdn_cfg_get_next_port(port)) {
char cfg_group[BUFFERSIZE + 1];
@@ -5554,7 +6299,6 @@ static int misdn_check_l2l1(struct ast_channel *chan, void *data)
if (!strcasecmp(cfg_group, group)) {
port_up = misdn_lib_port_up(port, 1);
-
if (!port_up) {
chan_misdn_log(2, 0, " --> port '%d'\n", port);
misdn_lib_get_port_up(port);
@@ -5752,12 +6496,15 @@ static int misdn_set_opt_exec(struct ast_channel *chan, void *data)
chan_misdn_log(1, ch->bc->port, "SETOPT: callerpres: %s\n", &tok[1]);
/* CRICH: callingpres!!! */
if (strstr(tok, "allowed")) {
- ch->bc->pres = 0;
+ ch->bc->presentation = 0;
+ ch->bc->set_presentation = 1;
} else if (strstr(tok, "restricted")) {
- ch->bc->pres = 1;
+ ch->bc->presentation = 1;
+ ch->bc->set_presentation = 1;
} else if (strstr(tok, "not_screened")) {
chan_misdn_log(0, ch->bc->port, "SETOPT: callerpres: not_screened is deprecated\n");
- ch->bc->pres = 1;
+ ch->bc->presentation = 1;
+ ch->bc->set_presentation = 1;
}
break;
case 'i' :
@@ -5975,16 +6722,10 @@ int misdn_jb_empty(struct misdn_jb *jb, char *data, int len)
return read;
}
-
-
-
/*******************************************************/
/*************** JITTERBUFFER END *********************/
/*******************************************************/
-
-
-
static void chan_misdn_log(int level, int port, char *tmpl, ...)
{
va_list ap;
@@ -6005,7 +6746,6 @@ static void chan_misdn_log(int level, int port, char *tmpl, ...)
if (level == -1) {
ast_log(LOG_WARNING, "%s", buf);
-
} else if (misdn_debug_only[port] ?
(level == 1 && misdn_debug[port]) || (level == misdn_debug[port])
: level <= misdn_debug[port]) {
@@ -6021,7 +6761,8 @@ static void chan_misdn_log(int level, int port, char *tmpl, ...)
FILE *fp = fopen(global_tracefile, "a+");
- if ((p = strchr(tmp, '\n'))) {
+ p = strchr(tmp, '\n');
+ if (p) {
*p = ':';
}