[libpri-commits] rmudgett: branch 1.4 r1714 - in /branches/1.4: ./ doc/
SVN commits to the libpri project
libpri-commits at lists.digium.com
Wed May 26 11:01:16 CDT 2010
Author: rmudgett
Date: Wed May 26 11:01:10 2010
New Revision: 1714
URL: http://svnview.digium.com/svn/libpri?view=rev&rev=1714
Log:
Add Call Completion Suppplementary Service
Call Completion Supplementary Service (CCSS) added for the following
switch types: ETSI PTMP, ETSI PTP, Q.SIG.
Specifications:
ETS 300 359 CCBS for PTMP and PTP
ETS 301 065 CCNR for PTMP and PTP
ECMA-186 Call Completion for Q.SIG
Several support services were added to support CC:
Dummy Call Reference.
Q.931 REGISTER message.
Dynamic expansion of the number of available timers (up to 8192).
Enhanced facility message handling.
Current implementation limitations preclude the following:
CC service retention is not supported.
Q.SIG path reservation is not supported.
(closes issue #14292)
Reported by: tomaso
Tested by: rmudgett
JIRA SWP-1493
Review: https://reviewboard.asterisk.org/r/522/
Added:
branches/1.4/doc/
- copied from r1704, team/group/ccss/doc/
branches/1.4/doc/cc_ptmp_agent.fsm
- copied unchanged from r1704, team/group/ccss/doc/cc_ptmp_agent.fsm
branches/1.4/doc/cc_ptmp_agent_flattened.fsm
- copied unchanged from r1704, team/group/ccss/doc/cc_ptmp_agent_flattened.fsm
branches/1.4/doc/cc_ptmp_monitor.fsm
- copied unchanged from r1704, team/group/ccss/doc/cc_ptmp_monitor.fsm
branches/1.4/doc/cc_ptmp_monitor_flattened.fsm
- copied unchanged from r1704, team/group/ccss/doc/cc_ptmp_monitor_flattened.fsm
branches/1.4/doc/cc_ptp_agent.fsm
- copied unchanged from r1704, team/group/ccss/doc/cc_ptp_agent.fsm
branches/1.4/doc/cc_ptp_agent_flattened.fsm
- copied unchanged from r1704, team/group/ccss/doc/cc_ptp_agent_flattened.fsm
branches/1.4/doc/cc_ptp_monitor.fsm
- copied unchanged from r1704, team/group/ccss/doc/cc_ptp_monitor.fsm
branches/1.4/doc/cc_ptp_monitor_flattened.fsm
- copied unchanged from r1704, team/group/ccss/doc/cc_ptp_monitor_flattened.fsm
branches/1.4/doc/cc_qsig_agent.fsm
- copied unchanged from r1704, team/group/ccss/doc/cc_qsig_agent.fsm
branches/1.4/doc/cc_qsig_agent_flattened.fsm
- copied unchanged from r1704, team/group/ccss/doc/cc_qsig_agent_flattened.fsm
branches/1.4/doc/cc_qsig_monitor.fsm
- copied unchanged from r1704, team/group/ccss/doc/cc_qsig_monitor.fsm
branches/1.4/doc/cc_qsig_monitor_flattened.fsm
- copied unchanged from r1704, team/group/ccss/doc/cc_qsig_monitor_flattened.fsm
branches/1.4/pri_cc.c
- copied unchanged from r1704, team/group/ccss/pri_cc.c
branches/1.4/rose_etsi_cc.c
- copied unchanged from r1704, team/group/ccss/rose_etsi_cc.c
branches/1.4/rose_qsig_cc.c
- copied unchanged from r1704, team/group/ccss/rose_qsig_cc.c
Modified:
branches/1.4/Makefile
branches/1.4/libpri.h
branches/1.4/pri.c
branches/1.4/pri_facility.c
branches/1.4/pri_facility.h
branches/1.4/pri_internal.h
branches/1.4/pri_q931.h
branches/1.4/prisched.c
branches/1.4/q931.c
branches/1.4/rose.c
branches/1.4/rose.h
branches/1.4/rose_internal.h
branches/1.4/rosetest.c
Modified: branches/1.4/Makefile
URL: http://svnview.digium.com/svn/libpri/branches/1.4/Makefile?view=diff&rev=1714&r1=1713&r2=1714
==============================================================================
--- branches/1.4/Makefile (original)
+++ branches/1.4/Makefile Wed May 26 11:01:10 2010
@@ -47,16 +47,19 @@
q921.o \
prisched.o \
q931.o \
+ pri_cc.o \
pri_facility.o \
asn1_primitive.o \
rose.o \
rose_address.o \
rose_etsi_aoc.o \
+ rose_etsi_cc.o \
rose_etsi_diversion.o \
rose_etsi_ect.o \
rose_other.o \
rose_q931.o \
rose_qsig_aoc.o \
+ rose_qsig_cc.o \
rose_qsig_ct.o \
rose_qsig_diversion.o \
rose_qsig_mwi.o \
@@ -68,16 +71,19 @@
q921.lo \
prisched.lo \
q931.lo \
+ pri_cc.lo \
pri_facility.lo \
asn1_primitive.lo \
rose.lo \
rose_address.lo \
rose_etsi_aoc.lo \
+ rose_etsi_cc.lo \
rose_etsi_diversion.lo \
rose_etsi_ect.lo \
rose_other.lo \
rose_q931.lo \
rose_qsig_aoc.lo \
+ rose_qsig_cc.lo \
rose_qsig_ct.lo \
rose_qsig_diversion.lo \
rose_qsig_mwi.lo \
Modified: branches/1.4/libpri.h
URL: http://svnview.digium.com/svn/libpri/branches/1.4/libpri.h?view=diff&rev=1714&r1=1713&r2=1714
==============================================================================
--- branches/1.4/libpri.h (original)
+++ branches/1.4/libpri.h Wed May 26 11:01:10 2010
@@ -51,6 +51,7 @@
#define PRI_DEBUG_Q931_ANOMALY (1 << 7) /* Show unexpected events */
#define PRI_DEBUG_APDU (1 << 8) /* Debug of APDU components such as ROSE */
#define PRI_DEBUG_AOC (1 << 9) /* Debug of Advice of Charge ROSE Messages */
+#define PRI_DEBUG_CC (1 << 10) /* Debug call-completion. */
#define PRI_DEBUG_ALL (0xffff) /* Everything */
@@ -439,6 +440,14 @@
unsigned char data[32];
};
+/*! \brief Addressing information needed to identify an endpoint in a call. */
+struct pri_party_address {
+ /*! \brief Subscriber phone number */
+ struct pri_party_number number;
+ /*! \brief Subscriber subaddress */
+ struct pri_party_subaddress subaddress;
+};
+
/*! \brief Information needed to identify an endpoint in a call. */
struct pri_party_id {
/*! \brief Subscriber name */
@@ -503,11 +512,127 @@
int invoke_id;
};
+/*
+ * NOTE:
+ * The code surrounded by STATUS_REQUEST_PLACE_HOLDER is not implemented.
+ * The STATUS_REQUEST_PLACE_HOLDER code will be made unconditional if support
+ * for the messages is ever needed (and gets written).
+ */
+
/* Subcommands derived from supplementary services. */
-#define PRI_SUBCMD_REDIRECTING 1
-#define PRI_SUBCMD_CONNECTED_LINE 2
-#define PRI_SUBCMD_REROUTING 3
-
+#define PRI_SUBCMD_REDIRECTING 1 /*!< Redirecting information update */
+#define PRI_SUBCMD_CONNECTED_LINE 2 /*!< Connected line information update */
+#define PRI_SUBCMD_REROUTING 3 /*!< CallRerouting/CallDeflection received. */
+#if defined(STATUS_REQUEST_PLACE_HOLDER)
+#define PRI_SUBCMD_STATUS_REQ 4 /*!< Determine the status of the given party. */
+#define PRI_SUBCMD_STATUS_REQ_RSP 5 /*!< Status request response */
+#endif /* defined(STATUS_REQUEST_PLACE_HOLDER) */
+#define PRI_SUBCMD_CC_AVAILABLE 6 /*!< Indicate that CC is available */
+#define PRI_SUBCMD_CC_REQ 7 /*!< CC activation request */
+#define PRI_SUBCMD_CC_REQ_RSP 8 /*!< CC activation request response */
+#define PRI_SUBCMD_CC_REMOTE_USER_FREE 9 /*!< Indicate that CC party B is available, party A is considered free. */
+#define PRI_SUBCMD_CC_B_FREE 10 /*!< Indicate that CC party B is available, party A is considered busy. */
+#define PRI_SUBCMD_CC_STATUS_REQ 11 /*!< Request/prod to receive updates of CC party A status */
+#define PRI_SUBCMD_CC_STATUS_REQ_RSP 12 /*!< Requested update of CC party A status */
+#define PRI_SUBCMD_CC_STATUS 13 /*!< Unsolicited update of CC party A status */
+#define PRI_SUBCMD_CC_CALL 14 /*!< Indicate that this call is a CC callback */
+#define PRI_SUBCMD_CC_CANCEL 15 /*!< Unsolicited indication that CC is canceled */
+#define PRI_SUBCMD_CC_STOP_ALERTING 16 /*!< Indicate that someone else has responed to remote user free */
+
+#if defined(STATUS_REQUEST_PLACE_HOLDER)
+struct pri_subcmd_status_request {
+ /*!
+ * \brief Invoke id in case there are multiple outstanding requests.
+ * \note Used to match any responses with the original invoke in case
+ * there are several requests active.
+ */
+ int invoke_id;
+ /*! \brief Party address requesting status about. */
+ struct pri_party_address party;
+};
+#endif /* defined(STATUS_REQUEST_PLACE_HOLDER) */
+
+#if defined(STATUS_REQUEST_PLACE_HOLDER)
+struct pri_subcmd_status_request_rsp {
+ /*!
+ * \brief Request id in case there are multiple outstanding requests.
+ * \note Used to match any responses with the request in case there
+ * are several requests active.
+ */
+ int request_id;
+ /*!
+ * \brief Response status to the status request.
+ * \details
+ * free(0),
+ * busy(1),
+ * incompatible(2)
+ * timeout(3),
+ */
+ int status;
+};
+#endif /* defined(STATUS_REQUEST_PLACE_HOLDER) */
+
+struct pri_subcmd_cc_id {
+ /*! \brief Call-Completion record id */
+ long cc_id;
+};
+
+struct pri_subcmd_cc_request {
+ /*! \brief Call-Completion record id */
+ long cc_id;
+ /*!
+ * \brief Mode of call-completion requested.
+ * \details
+ * ccbs(0),
+ * ccnr(1)
+ */
+ int mode;
+};
+
+struct pri_subcmd_cc_request_rsp {
+ /*! \brief Call-Completion record id */
+ long cc_id;
+ /*!
+ * \brief Status of the requested call-completion activation.
+ * \details
+ * success(0),
+ * timeout(1),
+ * error(2),
+ * reject(3)
+ */
+ int status;
+ /*!
+ * \brief Failure code that can be converted to a string to further
+ * explain the non-timeout failure.
+ * \note Valid when status is error or reject.
+ * \note Use pri_facility_error2str() to convert the error_code.
+ * \note Use pri_facility_reject2str() to convert the reject_code.
+ */
+ int fail_code;
+};
+
+struct pri_subcmd_cc_status {
+ /*! \brief Call-Completion record id */
+ long cc_id;
+ /*!
+ * \brief Party A status.
+ * \details
+ * free(0),
+ * busy(1)
+ */
+ int status;
+};
+
+struct pri_subcmd_cc_cancel {
+ /*! \brief Call-Completion record id */
+ long cc_id;
+ /*!
+ * \brief TRUE if the cc_id is for an agent.
+ * \note This is a convenience value so the upper layer can know which
+ * list it should search for the cc_id.
+ */
+ int is_agent;
+};
struct pri_subcommand {
/*! PRI_SUBCMD_xxx defined values */
@@ -518,6 +643,21 @@
struct pri_party_connected_line connected_line;
struct pri_party_redirecting redirecting;
struct pri_rerouting_data rerouting;
+#if defined(STATUS_REQUEST_PLACE_HOLDER)
+ struct pri_subcmd_status_request status_request;
+ struct pri_subcmd_status_request_rsp status_request_rsp;
+#endif /* defined(STATUS_REQUEST_PLACE_HOLDER) */
+ struct pri_subcmd_cc_id cc_available;
+ struct pri_subcmd_cc_request cc_request;
+ struct pri_subcmd_cc_request_rsp cc_request_rsp;
+ struct pri_subcmd_cc_id cc_remote_user_free;
+ struct pri_subcmd_cc_id cc_b_free;
+ struct pri_subcmd_cc_id cc_stop_alerting;
+ struct pri_subcmd_cc_id cc_status_req;
+ struct pri_subcmd_cc_status cc_status_req_rsp;
+ struct pri_subcmd_cc_status cc_status;
+ struct pri_subcmd_cc_id cc_call;
+ struct pri_subcmd_cc_cancel cc_cancel;
} u;
};
@@ -867,6 +1007,24 @@
/* Turn cause into a string */
char *pri_cause2str(int cause);
+/*!
+ * \brief Convert the given facility error code to a descriptive string.
+ *
+ * \param facility_error_code Error code to convert to a string.
+ *
+ * \return Descriptive error string.
+ */
+const char *pri_facility_error2str(int facility_error_code);
+
+/*!
+ * \brief Convert the given facility reject code to a descriptive string.
+ *
+ * \param facility_reject_code Error code to convert to a string.
+ *
+ * \return Descriptive reject string.
+ */
+const char *pri_facility_reject2str(int facility_reject_code);
+
/* Acknowledge a call and place it on the given channel. Set info to non-zero if there
is in-band data available on the channel */
int pri_acknowledge(struct pri *pri, q931_call *call, int channel, int info);
@@ -1261,6 +1419,65 @@
* \retval -1 on error.
*/
int pri_retrieve_rej(struct pri *ctrl, q931_call *call, int cause);
+
+#if defined(STATUS_REQUEST_PLACE_HOLDER)
+int pri_status_req(struct pri *ctrl, int request_id, const struct pri_sr *req);
+void pri_status_req_rsp(struct pri *ctrl, int invoke_id, int status);
+#endif /* defined(STATUS_REQUEST_PLACE_HOLDER) */
+
+/*!
+ * \brief Set the call completion feature enable flag.
+ *
+ * \param ctrl D channel controller.
+ * \param enable TRUE to enable call completion feature.
+ *
+ * \return Nothing
+ */
+void pri_cc_enable(struct pri *ctrl, int enable);
+
+/*!
+ * \brief Set the PTMP NT call completion recall mode.
+ *
+ * \param ctrl D channel controller.
+ * \param mode globalRecall(0), specificRecall(1)
+ *
+ * \return Nothing
+ */
+void pri_cc_recall_mode(struct pri *ctrl, int mode);
+
+/*!
+ * \brief Set the Q.SIG call completion signaling link retention mode.
+ * (Requestor/Initiator/Originator/Party-A)
+ *
+ * \param ctrl D channel controller.
+ * \param signaling_retention release(0), retain(1), do-not-care(2).
+ *
+ * \return Nothing
+ */
+void pri_cc_retain_signaling_req(struct pri *ctrl, int signaling_retention);
+
+/*!
+ * \brief Set the Q.SIG call completion signaling link retention mode.
+ * (Responder/Answerer/Party-B)
+ *
+ * \param ctrl D channel controller.
+ * \param signaling_retention release(0), retain(1).
+ *
+ * \return Nothing
+ */
+void pri_cc_retain_signaling_rsp(struct pri *ctrl, int signaling_retention);
+
+long pri_cc_available(struct pri *ctrl, q931_call *call);
+int pri_cc_req(struct pri *ctrl, long cc_id, int mode);
+int pri_cc_req_rsp(struct pri *ctrl, long cc_id, int status);
+void pri_cc_remote_user_free(struct pri *ctrl, long cc_id);
+void pri_cc_b_free(struct pri *ctrl, long cc_id);
+void pri_cc_stop_alerting(struct pri *ctrl, long cc_id);
+void pri_cc_status_req(struct pri *ctrl, long cc_id);
+void pri_cc_status_req_rsp(struct pri *ctrl, long cc_id, int status);
+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);
/* Get/Set PRI Timers */
#define PRI_GETSET_TIMERS
@@ -1309,6 +1526,31 @@
PRI_TIMER_T_RESPONSE, /*!< Maximum time to wait for a typical APDU response. */
+ PRI_TIMER_T_STATUS, /*!< Max time to wait for all replies to check for compatible terminals */
+
+ PRI_TIMER_T_ACTIVATE, /*!< Request supervision timeout. */
+ PRI_TIMER_T_DEACTIVATE, /*!< Deactivate supervision timeout. */
+ PRI_TIMER_T_INTERROGATE,/*!< Interrogation supervision timeout. */
+
+ /* ETSI call-completion timers */
+ PRI_TIMER_T_RETENTION, /*!< Max time to wait for user A to activate call-completion. */
+ PRI_TIMER_T_CCBS1, /*!< T-STATUS timer equivalent for CC user A status. */
+ PRI_TIMER_T_CCBS2, /*!< Max time the CCBS service will be active */
+ PRI_TIMER_T_CCBS3, /*!< Max time to wait for user A to respond to user B availability. */
+ PRI_TIMER_T_CCBS4, /*!< CC user B guard time before sending CC recall indication. */
+ PRI_TIMER_T_CCBS5, /*!< Network B CCBS supervision timeout. */
+ PRI_TIMER_T_CCBS6, /*!< Network A CCBS supervision timeout. */
+ PRI_TIMER_T_CCNR2, /*!< Max time the CCNR service will be active */
+ PRI_TIMER_T_CCNR5, /*!< Network B CCNR supervision timeout. */
+ PRI_TIMER_T_CCNR6, /*!< Network A CCNR supervision timeout. */
+
+ /* Q.SIG call-completion timers */
+ PRI_TIMER_QSIG_CC_T1, /*!< CC request supervision timeout. */
+ PRI_TIMER_QSIG_CCBS_T2, /*!< CCBS supervision timeout. */
+ PRI_TIMER_QSIG_CCNR_T2, /*!< CCNR supervision timeout. */
+ PRI_TIMER_QSIG_CC_T3, /*!< Max time to wait for user A to respond to user B availability. */
+ PRI_TIMER_QSIG_CC_T4, /*!< Path reservation supervision timeout. */
+
/* Must be last in the enum list */
PRI_MAX_TIMERS
};
Modified: branches/1.4/pri.c
URL: http://svnview.digium.com/svn/libpri/branches/1.4/pri.c?view=diff&rev=1714&r1=1713&r2=1714
==============================================================================
--- branches/1.4/pri.c (original)
+++ branches/1.4/pri.c Wed May 26 11:01:10 2010
@@ -40,11 +40,10 @@
#include "libpri.h"
#include "pri_internal.h"
#include "pri_facility.h"
-#include "pri_q921.h"
-#include "pri_q931.h"
#define PRI_BIT(a_bit) (1UL << (a_bit))
#define PRI_ALL_SWITCHES 0xFFFFFFFF
+#define PRI_ETSI_SWITCHES (PRI_BIT(PRI_SWITCH_EUROISDN_E1) | PRI_BIT(PRI_SWITCH_EUROISDN_T1))
struct pri_timer_table {
const char *name;
@@ -89,6 +88,27 @@
{ "T-HOLD", PRI_TIMER_T_HOLD, PRI_ALL_SWITCHES },
{ "T-RETRIEVE", PRI_TIMER_T_RETRIEVE, PRI_ALL_SWITCHES },
{ "T-RESPONSE", PRI_TIMER_T_RESPONSE, PRI_ALL_SWITCHES },
+ { "T-STATUS", PRI_TIMER_T_STATUS, PRI_ETSI_SWITCHES },
+ { "T-ACTIVATE", PRI_TIMER_T_ACTIVATE, PRI_ETSI_SWITCHES },
+ { "T-DEACTIVATE", PRI_TIMER_T_DEACTIVATE, PRI_ETSI_SWITCHES },
+ { "T-INTERROGATE", PRI_TIMER_T_INTERROGATE, PRI_ETSI_SWITCHES },
+ { "T-RETENTION", PRI_TIMER_T_RETENTION, PRI_ETSI_SWITCHES | PRI_BIT(PRI_SWITCH_QSIG) },
+ { "T-CCBS1", PRI_TIMER_T_CCBS1, PRI_ETSI_SWITCHES },
+ { "T-CCBS2", PRI_TIMER_T_CCBS2, PRI_ETSI_SWITCHES },
+ { "T-CCBS3", PRI_TIMER_T_CCBS3, PRI_ETSI_SWITCHES },
+ { "T-CCBS4", PRI_TIMER_T_CCBS4, PRI_ETSI_SWITCHES },
+ { "T-CCBS5", PRI_TIMER_T_CCBS5, PRI_ETSI_SWITCHES },
+ { "T-CCBS6", PRI_TIMER_T_CCBS6, PRI_ETSI_SWITCHES },
+ { "T-CCNR2", PRI_TIMER_T_CCNR2, PRI_ETSI_SWITCHES },
+ { "T-CCNR5", PRI_TIMER_T_CCNR5, PRI_ETSI_SWITCHES },
+ { "T-CCNR6", PRI_TIMER_T_CCNR6, PRI_ETSI_SWITCHES },
+ { "CC-T1", PRI_TIMER_QSIG_CC_T1, PRI_BIT(PRI_SWITCH_QSIG) },
+ { "CCBS-T2", PRI_TIMER_QSIG_CCBS_T2, PRI_BIT(PRI_SWITCH_QSIG) },
+ { "CCNR-T2", PRI_TIMER_QSIG_CCNR_T2, PRI_BIT(PRI_SWITCH_QSIG) },
+ { "CC-T3", PRI_TIMER_QSIG_CC_T3, PRI_BIT(PRI_SWITCH_QSIG) },
+#if defined(QSIG_PATH_RESERVATION_SUPPORT)
+ { "CC-T4", PRI_TIMER_QSIG_CC_T4, PRI_BIT(PRI_SWITCH_QSIG) },
+#endif /* defined(QSIG_PATH_RESERVATION_SUPPORT) */
/* *INDENT-ON* */
};
@@ -166,6 +186,33 @@
ctrl->timers[PRI_TIMER_T_RESPONSE] = 4 * 1000; /* Maximum time to wait for a typical APDU response. */
+ /* ETSI timers */
+ ctrl->timers[PRI_TIMER_T_STATUS] = 4 * 1000; /* Max time to wait for all replies to check for compatible terminals */
+ ctrl->timers[PRI_TIMER_T_ACTIVATE] = 10 * 1000; /* Request supervision timeout. */
+ ctrl->timers[PRI_TIMER_T_DEACTIVATE] = 4 * 1000;/* Deactivate supervision timeout. */
+ ctrl->timers[PRI_TIMER_T_INTERROGATE] = 4 * 1000;/* Interrogation supervision timeout. */
+
+ /* ETSI call-completion timers */
+ ctrl->timers[PRI_TIMER_T_RETENTION] = 30 * 1000;/* Max time to wait for user A to activate call-completion. */
+ ctrl->timers[PRI_TIMER_T_CCBS1] = 4 * 1000; /* T-STATUS timer equivalent for CC user A status. */
+ ctrl->timers[PRI_TIMER_T_CCBS2] = 45 * 60 * 1000;/* Max time the CCBS service will be active */
+ ctrl->timers[PRI_TIMER_T_CCBS3] = 20 * 1000; /* Max time to wait for user A to respond to user B availability. */
+ ctrl->timers[PRI_TIMER_T_CCBS4] = 5 * 1000; /* CC user B guard time before sending CC recall indication. */
+ ctrl->timers[PRI_TIMER_T_CCBS5] = 60 * 60 * 1000;/* Network B CCBS supervision timeout. */
+ ctrl->timers[PRI_TIMER_T_CCBS6] = 60 * 60 * 1000;/* Network A CCBS supervision timeout. */
+ ctrl->timers[PRI_TIMER_T_CCNR2] = 180 * 60 * 1000;/* Max time the CCNR service will be active */
+ ctrl->timers[PRI_TIMER_T_CCNR5] = 195 * 60 * 1000;/* Network B CCNR supervision timeout. */
+ ctrl->timers[PRI_TIMER_T_CCNR6] = 195 * 60 * 1000;/* Network A CCNR supervision timeout. */
+
+ /* Q.SIG call-completion timers */
+ ctrl->timers[PRI_TIMER_QSIG_CC_T1] = 30 * 1000;/* CC request supervision timeout. */
+ ctrl->timers[PRI_TIMER_QSIG_CCBS_T2] = 60 * 60 * 1000;/* CCBS supervision timeout. */
+ ctrl->timers[PRI_TIMER_QSIG_CCNR_T2] = 195 * 60 * 1000;/* CCNR supervision timeout. */
+ ctrl->timers[PRI_TIMER_QSIG_CC_T3] = 30 * 1000;/* Max time to wait for user A to respond to user B availability. */
+#if defined(QSIG_PATH_RESERVATION_SUPPORT)
+ ctrl->timers[PRI_TIMER_QSIG_CC_T4] = 40 * 1000;/* Path reservation supervision timeout. */
+#endif /* defined(QSIG_PATH_RESERVATION_SUPPORT) */
+
/* Set any switch specific override default values */
switch (switchtype) {
default:
@@ -246,6 +293,7 @@
pri_call_apdu_queue_cleanup(call);
}
free(p->msg_line);
+ free(p->sched.timer);
free(p);
}
}
@@ -903,6 +951,52 @@
return 0;
}
+#if defined(STATUS_REQUEST_PLACE_HOLDER)
+/*!
+ * \brief Poll/ping for the status of any "called" party.
+ *
+ * \param ctrl D channel controller.
+ * \param request_id The upper layer's ID number to match with the response in case
+ * there are several requests at the same time.
+ * \param req Setup request for "called" party to determine the status.
+ *
+ * \note
+ * There could be one or more PRI_SUBCMD_STATUS_REQ_RSP to the status request
+ * depending upon how many endpoints respond to the request.
+ * (This includes the timeout termination response.)
+ * \note
+ * Could be used to poll for the status of call-completion party B.
+ *
+ * \retval 0 on success.
+ * \retval -1 on error.
+ */
+int pri_status_req(struct pri *ctrl, int request_id, const struct pri_sr *req)
+{
+ return -1;
+}
+#endif /* defined(STATUS_REQUEST_PLACE_HOLDER) */
+
+#if defined(STATUS_REQUEST_PLACE_HOLDER)
+/*!
+ * \brief Response to a poll/ping request for status of any "called" party by libpri.
+ *
+ * \param ctrl D channel controller.
+ * \param invoke_id ID given by libpri when it requested the party status.
+ * \param status free(0)/busy(1)/incompatible(2)
+ *
+ * \note
+ * There could be zero, one, or more responses to the original
+ * status request depending upon how many endpoints respond to the request.
+ * \note
+ * Could be used to poll for the status of call-completion party B.
+ *
+ * \return Nothing
+ */
+void pri_status_req_rsp(struct pri *ctrl, int invoke_id, int status)
+{
+}
+#endif /* defined(STATUS_REQUEST_PLACE_HOLDER) */
+
#if 0
/* deprecated routines, use pri_hangup */
int pri_release(struct pri *pri, q931_call *call, int cause)
@@ -930,7 +1024,7 @@
return -1;
/* Check for bearer capability */
- if (call1->transcapability != call2->transcapability)
+ if (call1->bc.transcapability != call2->bc.transcapability)
return -1;
/* Check to see if we're on the same PRI */
@@ -1040,7 +1134,7 @@
}
}
-static void pri_sr_init(struct pri_sr *req)
+void pri_sr_init(struct pri_sr *req)
{
memset(req, 0, sizeof(struct pri_sr));
q931_party_redirecting_init(&req->redirecting);
@@ -1618,3 +1712,35 @@
return send_reroute_request(ctrl, call, caller_id, &reroute, subscription_option);
}
+
+void pri_cc_enable(struct pri *ctrl, int enable)
+{
+ if (ctrl) {
+ ctrl = PRI_MASTER(ctrl);
+ ctrl->cc_support = enable ? 1 : 0;
+ }
+}
+
+void pri_cc_recall_mode(struct pri *ctrl, int mode)
+{
+ if (ctrl) {
+ ctrl = PRI_MASTER(ctrl);
+ ctrl->cc.option.recall_mode = mode ? 1 : 0;
+ }
+}
+
+void pri_cc_retain_signaling_req(struct pri *ctrl, int signaling_retention)
+{
+ if (ctrl && 0 <= signaling_retention && signaling_retention < 3) {
+ ctrl = PRI_MASTER(ctrl);
+ ctrl->cc.option.signaling_retention_req = signaling_retention;
+ }
+}
+
+void pri_cc_retain_signaling_rsp(struct pri *ctrl, int signaling_retention)
+{
+ if (ctrl) {
+ ctrl = PRI_MASTER(ctrl);
+ ctrl->cc.option.signaling_retention_rsp = signaling_retention ? 1 : 0;
+ }
+}
Modified: branches/1.4/pri_facility.c
URL: http://svnview.digium.com/svn/libpri/branches/1.4/pri_facility.c?view=diff&rev=1714&r1=1713&r2=1714
==============================================================================
--- branches/1.4/pri_facility.c (original)
+++ branches/1.4/pri_facility.c Wed May 26 11:01:10 2010
@@ -30,20 +30,21 @@
#include "compat.h"
#include "libpri.h"
#include "pri_internal.h"
-#include "pri_q921.h"
-#include "pri_q931.h"
#include "pri_facility.h"
-#include "rose.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <limits.h>
-static short get_invokeid(struct pri *ctrl)
-{
- ctrl = PRI_MASTER(ctrl);
- return ++ctrl->last_invoke;
+const char *pri_facility_error2str(int facility_error_code)
+{
+ return rose_error2str(facility_error_code);
+}
+
+const char *pri_facility_reject2str(int facility_reject_code)
+{
+ return rose_reject2str(facility_reject_code);
}
static int redirectingreason_from_q931(struct pri *ctrl, int redirectingreason)
@@ -171,6 +172,7 @@
}
/*!
+ * \internal
* \brief Convert the Q.931 type-of-number field to facility.
*
* \param ctrl D channel controller for diagnostic messages or global options.
@@ -497,7 +499,6 @@
}
/*!
- * \internal
* \brief Copy the given rose party number to the q931_party_number
*
* \param ctrl D channel controller for diagnostic messages or global options.
@@ -508,8 +509,8 @@
*
* \return Nothing
*/
-static void rose_copy_number_to_q931(struct pri *ctrl,
- struct q931_party_number *q931_number, const struct rosePartyNumber *rose_number)
+void rose_copy_number_to_q931(struct pri *ctrl, struct q931_party_number *q931_number,
+ const struct rosePartyNumber *rose_number)
{
//q931_party_number_init(q931_number);
libpri_copy_string(q931_number->str, (char *) rose_number->str,
@@ -520,7 +521,6 @@
}
/*!
- * \internal
* \brief Copy the given rose subaddress to the q931_party_subaddress.
*
* \param ctrl D channel controller for diagnostic messages or global options.
@@ -531,7 +531,7 @@
*
* \return Nothing
*/
-static void rose_copy_subaddress_to_q931(struct pri *ctrl,
+void rose_copy_subaddress_to_q931(struct pri *ctrl,
struct q931_party_subaddress *q931_subaddress,
const struct rosePartySubaddress *rose_subaddress)
{
@@ -571,19 +571,18 @@
}
/*!
- * \internal
- * \brief Copy the given rose address to the q931_party_id address.
- *
- * \param ctrl D channel controller for diagnostic messages or global options.
- * \param q931_address Q.931 party id structure to fill address
+ * \brief Copy the given rose address to the q931_party_address.
+ *
+ * \param ctrl D channel controller for diagnostic messages or global options.
+ * \param q931_address Q.931 party address structure
* \param rose_address ROSE address structure
*
* \note It is assumed that the q931_address has been initialized before calling.
*
* \return Nothing
*/
-static void rose_copy_address_to_q931(struct pri *ctrl,
- struct q931_party_id *q931_address, const struct roseAddress *rose_address)
+void rose_copy_address_to_q931(struct pri *ctrl, struct q931_party_address *q931_address,
+ const struct roseAddress *rose_address)
{
rose_copy_number_to_q931(ctrl, &q931_address->number, &rose_address->number);
rose_copy_subaddress_to_q931(ctrl, &q931_address->subaddress,
@@ -591,7 +590,25 @@
}
/*!
- * \internal
+ * \brief Copy the given rose address to the q931_party_id address.
+ *
+ * \param ctrl D channel controller for diagnostic messages or global options.
+ * \param q931_address Q.931 party id structure to fill address
+ * \param rose_address ROSE address structure
+ *
+ * \note It is assumed that the q931_address has been initialized before calling.
+ *
+ * \return Nothing
+ */
+void rose_copy_address_to_id_q931(struct pri *ctrl, struct q931_party_id *q931_address,
+ const struct roseAddress *rose_address)
+{
+ rose_copy_number_to_q931(ctrl, &q931_address->number, &rose_address->number);
+ rose_copy_subaddress_to_q931(ctrl, &q931_address->subaddress,
+ &rose_address->subaddress);
+}
+
+/*!
* \brief Copy the given rose presented screened party number to the q931_party_number
*
* \param ctrl D channel controller for diagnostic messages or global options.
@@ -600,7 +617,7 @@
*
* \return Nothing
*/
-static void rose_copy_presented_number_screened_to_q931(struct pri *ctrl,
+void rose_copy_presented_number_screened_to_q931(struct pri *ctrl,
struct q931_party_number *q931_number,
const struct rosePresentedNumberScreened *rose_presented)
{
@@ -622,7 +639,6 @@
}
/*!
- * \internal
* \brief Copy the given rose presented unscreened party number to the q931_party_number
*
* \param ctrl D channel controller for diagnostic messages or global options.
@@ -631,7 +647,7 @@
*
* \return Nothing
*/
-static void rose_copy_presented_number_unscreened_to_q931(struct pri *ctrl,
+void rose_copy_presented_number_unscreened_to_q931(struct pri *ctrl,
struct q931_party_number *q931_number,
const struct rosePresentedNumberUnscreened *rose_presented)
{
@@ -650,7 +666,6 @@
}
/*!
- * \internal
* \brief Copy the given rose presented screened party address to the q931_party_number
*
* \param ctrl D channel controller for diagnostic messages or global options.
@@ -659,7 +674,7 @@
*
* \return Nothing
*/
-static void rose_copy_presented_address_screened_to_q931(struct pri *ctrl,
+void rose_copy_presented_address_screened_to_id_q931(struct pri *ctrl,
struct q931_party_id *q931_address,
const struct rosePresentedAddressScreened *rose_presented)
{
@@ -685,7 +700,6 @@
}
/*!
- * \internal
* \brief Copy the given rose party name to the q931_party_name
*
* \param ctrl D channel controller for diagnostic messages or global options.
@@ -694,8 +708,8 @@
*
* \return Nothing
*/
-static void rose_copy_name_to_q931(struct pri *ctrl,
- struct q931_party_name *qsig_name, const struct roseQsigName *rose_name)
+void rose_copy_name_to_q931(struct pri *ctrl, struct q931_party_name *qsig_name,
+ const struct roseQsigName *rose_name)
{
//q931_party_name_init(qsig_name);
qsig_name->valid = 1;
@@ -706,7 +720,6 @@
}
/*!
- * \internal
* \brief Copy the given q931_party_number to the rose party number
*
* \param ctrl D channel controller for diagnostic messages or global options.
@@ -715,8 +728,8 @@
*
* \return Nothing
*/
-static void q931_copy_number_to_rose(struct pri *ctrl,
- struct rosePartyNumber *rose_number, const struct q931_party_number *q931_number)
+void q931_copy_number_to_rose(struct pri *ctrl, struct rosePartyNumber *rose_number,
+ const struct q931_party_number *q931_number)
{
rose_number->plan = numbering_plan_from_q931(ctrl, q931_number->plan);
rose_number->ton = typeofnumber_from_q931(ctrl, q931_number->plan);
@@ -727,7 +740,6 @@
}
/*!
- * \internal
* \brief Copy the given q931_party_subaddress to the rose subaddress.
*
* \param ctrl D channel controller for diagnostic messages or global options.
@@ -736,7 +748,7 @@
*
* \return Nothing
*/
-static void q931_copy_subaddress_to_rose(struct pri *ctrl,
+void q931_copy_subaddress_to_rose(struct pri *ctrl,
struct rosePartySubaddress *rose_subaddress,
const struct q931_party_subaddress *q931_subaddress)
{
@@ -778,17 +790,16 @@
}
/*!
- * \internal
- * \brief Copy the given q931_party_id address to the rose address.
+ * \brief Copy the given q931_party_address to the rose address.
*
* \param ctrl D channel controller for diagnostic messages or global options.
* \param rose_address ROSE address structure
- * \param q931_address Q.931 party id structure to give address
+ * \param q931_address Q.931 party address structure
*
* \return Nothing
*/
-static void q931_copy_address_to_rose(struct pri *ctrl, struct roseAddress *rose_address,
- const struct q931_party_id *q931_address)
+void q931_copy_address_to_rose(struct pri *ctrl, struct roseAddress *rose_address,
+ const struct q931_party_address *q931_address)
{
q931_copy_number_to_rose(ctrl, &rose_address->number, &q931_address->number);
q931_copy_subaddress_to_rose(ctrl, &rose_address->subaddress,
@@ -796,7 +807,23 @@
}
/*!
- * \internal
+ * \brief Copy the given q931_party_id address to the rose address.
+ *
+ * \param ctrl D channel controller for diagnostic messages or global options.
+ * \param rose_address ROSE address structure
+ * \param q931_address Q.931 party id structure to give address
+ *
+ * \return Nothing
+ */
+void q931_copy_id_address_to_rose(struct pri *ctrl, struct roseAddress *rose_address,
+ const struct q931_party_id *q931_address)
+{
+ q931_copy_number_to_rose(ctrl, &rose_address->number, &q931_address->number);
+ q931_copy_subaddress_to_rose(ctrl, &rose_address->subaddress,
+ &q931_address->subaddress);
+}
+
+/*!
* \brief Copy the given q931_party_number to the rose presented screened party number
*
* \param ctrl D channel controller for diagnostic messages or global options.
@@ -805,7 +832,7 @@
*
* \return Nothing
*/
-static void q931_copy_presented_number_screened_to_rose(struct pri *ctrl,
+void q931_copy_presented_number_screened_to_rose(struct pri *ctrl,
struct rosePresentedNumberScreened *rose_presented,
const struct q931_party_number *q931_number)
{
@@ -821,7 +848,6 @@
}
/*!
- * \internal
* \brief Copy the given q931_party_number to the rose presented unscreened party number
*
* \param ctrl D channel controller for diagnostic messages or global options.
@@ -830,7 +856,7 @@
*
* \return Nothing
*/
-static void q931_copy_presented_number_unscreened_to_rose(struct pri *ctrl,
+void q931_copy_presented_number_unscreened_to_rose(struct pri *ctrl,
struct rosePresentedNumberUnscreened *rose_presented,
const struct q931_party_number *q931_number)
{
@@ -843,9 +869,7 @@
}
}
-#if 0 /* In case it is needed in the future */
-/*!
- * \internal
+/*!
* \brief Copy the given q931_party_number to the rose presented screened party address
*
* \param ctrl D channel controller for diagnostic messages or global options.
@@ -854,7 +878,7 @@
*
* \return Nothing
*/
-static void q931_copy_presented_address_screened_to_rose(struct pri *ctrl,
+void q931_copy_presented_id_address_screened_to_rose(struct pri *ctrl,
struct rosePresentedAddressScreened *rose_presented,
const struct q931_party_id *q931_address)
{
@@ -872,10 +896,8 @@
rose_presented->presentation = 2;/* numberNotAvailableDueToInterworking */
}
}
-#endif /* In case it is needed in the future */
-
-/*!
- * \internal
+
+/*!
* \brief Copy the given q931_party_name to the rose party name
*
* \param ctrl D channel controller for diagnostic messages or global options.
@@ -884,8 +906,8 @@
*
* \return Nothing
*/
-static void q931_copy_name_to_rose(struct pri *ctrl,
- struct roseQsigName *rose_name, const struct q931_party_name *qsig_name)
+void q931_copy_name_to_rose(struct pri *ctrl, struct roseQsigName *rose_name,
+ const struct q931_party_name *qsig_name)
{
if (qsig_name->valid) {
rose_name->presentation = qsig_name_presentation_from_q931(ctrl,
@@ -1841,7 +1863,7 @@
redirectingreason_from_q931(ctrl, deflection->reason);
/* calledAddress is the passed in deflection->to address */
- q931_copy_address_to_rose(ctrl, &msg.args.qsig.CallRerouting.called, &deflection->to);
+ q931_copy_id_address_to_rose(ctrl, &msg.args.qsig.CallRerouting.called, &deflection->to);
msg.args.qsig.CallRerouting.diversion_counter = deflection->count;
@@ -1849,7 +1871,7 @@
q931ie_pos = msg.args.qsig.CallRerouting.q931ie_contents;
*q931ie_pos++ = 0x04; /* Bearer Capability IE */
*q931ie_pos++ = 0x03; /* len */
- *q931ie_pos++ = 0x80 | call->transcapability; /* Rxed transfer capability. */
+ *q931ie_pos++ = 0x80 | call->bc.transcapability; /* Rxed transfer capability. */
*q931ie_pos++ = 0x90; /* circuit mode, 64kbit/s */
*q931ie_pos++ = 0xa3; /* level1 protocol, a-law */
*q931ie_pos++ = 0x95; /* locking shift to codeset 5 (national use) */
@@ -1953,7 +1975,7 @@
redirectingreason_from_q931(ctrl, deflection->reason);
/* calledAddress is the passed in deflection->to address */
- q931_copy_address_to_rose(ctrl, &msg.args.etsi.CallRerouting.called_address,
+ q931_copy_id_address_to_rose(ctrl, &msg.args.etsi.CallRerouting.called_address,
&deflection->to);
msg.args.etsi.CallRerouting.rerouting_counter = deflection->count;
@@ -1962,7 +1984,7 @@
q931ie_pos = msg.args.etsi.CallRerouting.q931ie_contents;
*q931ie_pos++ = 0x04; /* Bearer Capability IE */
*q931ie_pos++ = 0x03; /* len */
- *q931ie_pos++ = 0x80 | call->transcapability; /* Rxed transfer capability. */
+ *q931ie_pos++ = 0x80 | call->bc.transcapability; /* Rxed transfer capability. */
*q931ie_pos++ = 0x90; /* circuit mode, 64kbit/s */
*q931ie_pos++ = 0xa3; /* level1 protocol, a-law */
msg.args.etsi.CallRerouting.q931ie.length = q931ie_pos
@@ -2014,7 +2036,7 @@
msg.invoke_id = get_invokeid(ctrl);
/* deflectionAddress is the passed in deflection->to address */
- q931_copy_address_to_rose(ctrl, &msg.args.etsi.CallDeflection.deflection,
+ q931_copy_id_address_to_rose(ctrl, &msg.args.etsi.CallDeflection.deflection,
deflection);
msg.args.etsi.CallDeflection.presentation_allowed_to_diverted_to_user_present = 1;
@@ -2766,13 +2788,15 @@
call->apdus = NULL;
while (cur_event) {
if (cur_event->response.callback) {
+ /* Stop any response timeout. */
+ pri_schedule_del(call->pri, cur_event->timer);
+ cur_event->timer = 0;
+
/* Indicate to callback that the APDU is being cleaned up. */
cur_event->response.callback(APDU_CALLBACK_REASON_CLEANUP, call->pri,
call, cur_event, NULL);
-
- /* Stop any response timeout. */
- pri_schedule_del(call->pri, cur_event->timer);
}
+
free_event = cur_event;
cur_event = cur_event->next;
free(free_event);
@@ -2781,7 +2805,6 @@
}
/*!
- * \internal
* \brief Find an outstanding APDU with the given invoke id.
*
* \param call Call to find APDU.
@@ -2790,10 +2813,14 @@
* \retval apdu_event if found.
* \retval NULL if not found.
*/
-static struct apdu_event *pri_call_apdu_find(struct q931_call *call, int invoke_id)
+struct apdu_event *pri_call_apdu_find(struct q931_call *call, int invoke_id)
{
struct apdu_event *apdu;
+ if (invoke_id == APDU_INVALID_INVOKE_ID) {
+ /* No need to search the list since it cannot be in there. */
+ return NULL;
+ }
for (apdu = call->apdus; apdu; apdu = apdu->next) {
/*
* Note: The APDU cannot be sent and still in the queue without a
@@ -2808,14 +2835,15 @@
}
/*!
- * \brief Delete the given APDU event from the given call.
+ * \brief Extract the given APDU event from the given call.
*
* \param call Call to remove the APDU.
- * \param doomed APDU event to delete.
- *
- * \return Nothing
- */
-void pri_call_apdu_delete(struct q931_call *call, struct apdu_event *doomed)
+ * \param extract APDU event to extract.
+ *
+ * \retval TRUE on success.
+ * \retval FALSE on error.
+ */
+int pri_call_apdu_extract(struct q931_call *call, struct apdu_event *extract)
{
struct apdu_event **prev;
struct apdu_event *cur;
@@ -2824,15 +2852,35 @@
for (prev = &call->apdus, cur = call->apdus;
cur;
prev = &cur->next, cur = cur->next) {
- if (cur == doomed) {
+ if (cur == extract) {
/* Stop any response timeout. */
pri_schedule_del(call->pri, cur->timer);
+ cur->timer = 0;
/* Remove APDU from list. */
*prev = cur->next;
- free(cur);
- break;
- }
+
+ /* Found and extracted APDU from list. */
+ return 1;
+ }
+ }
+
+ /* Did not find the APDU in the list. */
+ return 0;
+}
+
+/*!
+ * \brief Delete the given APDU event from the given call.
+ *
+ * \param call Call to remove the APDU.
+ * \param doomed APDU event to delete.
+ *
+ * \return Nothing
+ */
+void pri_call_apdu_delete(struct q931_call *call, struct apdu_event *doomed)
+{
+ if (pri_call_apdu_extract(call, doomed)) {
+ free(doomed);
}
}
@@ -2985,18 +3033,18 @@
}
/*!
- * \internal
* \brief Encode and queue a plain facility error code.
*
* \param ctrl D channel controller for diagnostic messages or global options.
* \param call Call leg from which to encode error message response.
+ * \param msgtype Q.931 message type to put facility ie in.
* \param invoke_id Invoke id to put in error message response.
* \param code Error code to put in error message response.
*
* \retval 0 on success.
* \retval -1 on error.
*/
-static int rose_facility_error_encode(struct pri *ctrl, q931_call *call, int invoke_id,
+int rose_error_msg_encode(struct pri *ctrl, q931_call *call, int msgtype, int invoke_id,
enum rose_error_code code)
{
unsigned char buffer[256];
@@ -3019,7 +3067,7 @@
return -1;
}
- return pri_call_apdu_queue(call, Q931_FACILITY, buffer, end - buffer, NULL);
+ return pri_call_apdu_queue(call, msgtype, buffer, end - buffer, NULL);
}
/*!
@@ -3033,10 +3081,10 @@
* \retval 0 on success.
* \retval -1 on error.
*/
[... 4564 lines stripped ...]
More information about the libpri-commits
mailing list