diff options
Diffstat (limited to 'channels/chan_misdn.c')
-rw-r--r-- | channels/chan_misdn.c | 1553 |
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 = ':'; } |