diff --git a/libpri.h b/libpri.h index 2dc9a4f..2394846 100644 --- a/libpri.h +++ b/libpri.h @@ -2102,6 +2102,27 @@ void pri_cc_status(struct pri *ctrl, long cc_id, int status); int pri_cc_call(struct pri *ctrl, long cc_id, q931_call *call, struct pri_sr *req); void pri_cc_cancel(struct pri *ctrl, long cc_id); +/* Date/time ie send policy option values. */ +#define PRI_DATE_TIME_SEND_DEFAULT 0 /*!< Send date/time ie default. */ +#define PRI_DATE_TIME_SEND_NO 1 /*!< Send date/time ie never. */ +#define PRI_DATE_TIME_SEND_DATE 2 /*!< Send date/time ie date only. */ +#define PRI_DATE_TIME_SEND_DATE_HH 3 /*!< Send date/time ie date and hour. */ +#define PRI_DATE_TIME_SEND_DATE_HHMM 4 /*!< Send date/time ie date, hour, and minute. */ +#define PRI_DATE_TIME_SEND_DATE_HHMMSS 5 /*!< Send date/time ie date, hour, minute, and second. */ + +/*! + * \brief Set the date/time ie send policy option. + * + * \param ctrl D channel controller. + * \param option Policy option to set. + * + * \note + * Only valid in NT mode. + * + * \return Nothing + */ +void pri_date_time_send_option(struct pri *ctrl, int option); + /* Get/Set PRI Timers */ #define PRI_GETSET_TIMERS int pri_set_timer(struct pri *pri, int timer, int value); diff --git a/pri.c b/pri.c index f137da7..45882a4 100644 --- a/pri.c +++ b/pri.c @@ -344,6 +344,27 @@ static unsigned long pri_display_options_receive_default(struct pri *ctrl) return flags; } +/*! + * \internal + * \brief Determine the default date/time send option default. + * + * \param ctrl D channel controller. + * + * \return Default date/time send option. + */ +static int pri_date_time_send_default(struct pri *ctrl) +{ + int date_time_send; + + if (BRI_NT_PTMP(ctrl)) { + date_time_send = PRI_DATE_TIME_SEND_DATE_HHMM; + } else { + date_time_send = PRI_DATE_TIME_SEND_NO; + } + + return date_time_send; +} + /*! * \brief Destroy the given link. * @@ -565,6 +586,7 @@ static struct pri *pri_ctrl_new(int fd, int node, int switchtype, pri_io_cb rd, tei); break; } + ctrl->date_time_send = pri_date_time_send_default(ctrl); if (dummy_ctrl) { /* Initialize the dummy call reference call record. */ ctrl->link.dummy_call = &dummy_ctrl->dummy_call; @@ -2174,3 +2196,30 @@ int pri_display_text(struct pri *ctrl, q931_call *call, const struct pri_subcmd_ } return q931_display_text(ctrl, call, display); } + +void pri_date_time_send_option(struct pri *ctrl, int option) +{ + if (!ctrl) { + return; + } + switch (option) { + case PRI_DATE_TIME_SEND_DEFAULT: + ctrl->date_time_send = pri_date_time_send_default(ctrl); + break; + default: + case PRI_DATE_TIME_SEND_NO: + ctrl->date_time_send = PRI_DATE_TIME_SEND_NO; + break; + case PRI_DATE_TIME_SEND_DATE: + case PRI_DATE_TIME_SEND_DATE_HH: + case PRI_DATE_TIME_SEND_DATE_HHMM: + case PRI_DATE_TIME_SEND_DATE_HHMMSS: + if (NT_MODE(ctrl)) { + /* Only networks may send date/time ie. */ + ctrl->date_time_send = option; + } else { + ctrl->date_time_send = PRI_DATE_TIME_SEND_NO; + } + break; + } +} diff --git a/pri_internal.h b/pri_internal.h index bc74162..5f0de9f 100644 --- a/pri_internal.h +++ b/pri_internal.h @@ -189,6 +189,8 @@ struct pri { /*! Receive display text policy option flags. */ unsigned long receive; } display_flags; + /*! Configured date/time ie send policy option. */ + int date_time_send; }; /*! \brief Maximum name length plus null terminator (From ECMA-164) */ diff --git a/q931.c b/q931.c index 82acfe1..aa88f77 100644 --- a/q931.c +++ b/q931.c @@ -3082,16 +3082,44 @@ static int transmit_time_date(int full_ie, struct pri *ctrl, q931_call *call, in { time_t now; struct tm timedate; + int ie_len; - /* Send the current time. */ - time(&now); - localtime_r(&now, &timedate); - ie->data[0] = timedate.tm_year - 100; /* 1900+ */ - ie->data[1] = timedate.tm_mon + 1; - ie->data[2] = timedate.tm_mday; - ie->data[3] = timedate.tm_hour; - ie->data[4] = timedate.tm_min; - return 7; + do { + if (ctrl->date_time_send < PRI_DATE_TIME_SEND_DATE) { + ie_len = 0; + break; + } + + /* Send the current date/time. */ + time(&now); + localtime_r(&now, &timedate); + ie->data[0] = timedate.tm_year - 100; /* 1900+ */ + ie->data[1] = timedate.tm_mon + 1; + ie->data[2] = timedate.tm_mday; + ie_len = 2 + 3; + if (ctrl->date_time_send < PRI_DATE_TIME_SEND_DATE_HH) { + break; + } + + /* Add optional hour. */ + ie->data[3] = timedate.tm_hour; + ++ie_len; + if (ctrl->date_time_send < PRI_DATE_TIME_SEND_DATE_HHMM) { + break; + } + + /* Add optional minutes. */ + ie->data[4] = timedate.tm_min; + ++ie_len; + if (ctrl->date_time_send < PRI_DATE_TIME_SEND_DATE_HHMMSS) { + break; + } + + /* Add optional seconds. */ + ie->data[5] = timedate.tm_sec; + ++ie_len; + } while (0); + return ie_len; } static void dump_keypad_facility(int full_ie, struct pri *ctrl, q931_ie *ie, int len, char prefix) @@ -5597,16 +5625,6 @@ static void pri_disconnect_timeout(void *data) } static int connect_ies[] = { - Q931_CHANNEL_IDENT, - Q931_IE_FACILITY, - Q931_PROGRESS_INDICATOR, - Q931_DISPLAY, - Q931_IE_CONNECTED_NUM, - Q931_IE_CONNECTED_SUBADDR, - -1 -}; - -static int connect_net_ies[] = { Q931_CHANNEL_IDENT, Q931_IE_FACILITY, Q931_PROGRESS_INDICATOR, @@ -5675,12 +5693,7 @@ int q931_connect(struct pri *ctrl, q931_call *c, int channel, int nonisdn) } else { q931_display_clear(c); } - if (ctrl->localtype == PRI_NETWORK) { - /* networks may send date/time */ - return send_message(ctrl, c, Q931_CONNECT, connect_net_ies); - } else { - return send_message(ctrl, c, Q931_CONNECT, connect_ies); - } + return send_message(ctrl, c, Q931_CONNECT, connect_ies); } static int release_ies[] = { Q931_CAUSE, Q931_IE_FACILITY, Q931_IE_USER_USER, -1 };