[libpri-commits] rmudgett: branch group/ccss r993 - /team/group/ccss/

SVN commits to the libpri project libpri-commits at lists.digium.com
Thu Aug 20 09:38:46 CDT 2009


Author: rmudgett
Date: Thu Aug 20 09:38:42 2009
New Revision: 993

URL: http://svn.asterisk.org/svn-view/libpri?view=rev&rev=993
Log:
Work so far.  Certainly not functional.

Added:
    team/group/ccss/pri_cc.c   (with props)
Modified:
    team/group/ccss/Makefile
    team/group/ccss/libpri.h
    team/group/ccss/pri.c
    team/group/ccss/pri_facility.c
    team/group/ccss/pri_internal.h
    team/group/ccss/q931.c

Modified: team/group/ccss/Makefile
URL: http://svn.asterisk.org/svn-view/libpri/team/group/ccss/Makefile?view=diff&rev=993&r1=992&r2=993
==============================================================================
--- team/group/ccss/Makefile (original)
+++ team/group/ccss/Makefile Thu Aug 20 09:38:42 2009
@@ -47,6 +47,7 @@
 	q921.o \
 	prisched.o \
 	q931.o \
+	pri_cc.o \
 	pri_facility.o \
 	asn1_primitive.o \
 	rose.o \
@@ -70,6 +71,7 @@
 	q921.lo \
 	prisched.lo \
 	q931.lo \
+	pri_cc.lo \
 	pri_facility.lo \
 	asn1_primitive.lo \
 	rose.lo \

Modified: team/group/ccss/libpri.h
URL: http://svn.asterisk.org/svn-view/libpri/team/group/ccss/libpri.h?view=diff&rev=993&r1=992&r2=993
==============================================================================
--- team/group/ccss/libpri.h (original)
+++ team/group/ccss/libpri.h Thu Aug 20 09:38:42 2009
@@ -346,7 +346,7 @@
 #define PRI_NSF_ATT_MULTIQUEST         0xF0
 #define PRI_NSF_CALL_REDIRECTION_SERVICE       0xF7
 
-/* ECMA 186 */
+/* BUGBUG eliminate these defines ECMA 186 */
 #define PRI_CC_CCNRREQUEST		27
 #define PRI_CC_CANCEL			28
 #define PRI_CC_RINGOUT			31
@@ -435,6 +435,14 @@
 	 * BCD/binary and thus have a null byte as part of the contents.
 	 */
 	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. */
@@ -474,12 +482,14 @@
 	int reason;
 };
 
+/* BUGBUG eliminate this struct definition. */
 /* Structures for qsig_cc_facilities */
 struct pri_qsig_cc_extension {
 	int	cc_extension_tag;
 	char extension[256];
 };
 
+/* BUGBUG eliminate this struct definition. */
 struct pri_qsig_cc_optional_arg {
 	char number_A[256];
 	char number_B[256];
@@ -487,6 +497,7 @@
 	struct pri_qsig_cc_extension cc_extension;
 };
 
+/* BUGBUG eliminate this struct definition. */
 struct pri_qsig_cc_request_res {
 	int	no_path_reservation;
 	int	retain_service;
@@ -494,44 +505,168 @@
 };
 
 /* Subcommands derived from supplementary services. */
-#define PRI_SUBCMD_REDIRECTING			1
-#define PRI_SUBCMD_CONNECTED_LINE		2
-#define PRI_SUBCMD_CC_CCBSREQUEST_RR	3
-#define PRI_SUBCMD_CC_CCNRREQUEST_RR	4
-#define PRI_SUBCMD_CC_CANCEL_INV		5
-#define PRI_SUBCMD_CC_EXECPOSSIBLE_INV	6
-#define PRI_SUBCMD_CC_RINGOUT_INV		7
-#define PRI_SUBCMD_CC_SUSPEND_INV		8
-#define PRI_SUBCMD_CC_ERROR				9
-
+#define PRI_SUBCMD_REDIRECTING				1	/*!< Redirecting information update */
+#define PRI_SUBCMD_CONNECTED_LINE			2	/*!< Connected line information update */
+#define PRI_SUBCMD_STATUS_REQ				3	/*!< Determine the status of the given party. */
+#define PRI_SUBCMD_STATUS_REQ_RSP			4	/*!< Status request response */
+#define PRI_SUBCMD_CC_RECORD_RETENTION		5	/*!< Give cc_id to upper layer */
+#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 */
+#define PRI_SUBCMD_CC_STATUS_REQ			10	/*!< Request/prod to receive updates of CC party A status */
+#define PRI_SUBCMD_CC_STATUS				11	/*!< Unsolicited update of CC party A status */
+#define PRI_SUBCMD_CC_CALL					12	/*!< Indicate that this call is a CC callback */
+#define PRI_SUBCMD_CC_CANCEL				13	/*!< Unsolicited indication that CC is canceled */
+#define PRI_SUBCMD_CC_DEACTIVATE_REQ		14	/*!< CC deactivation request */
+#define PRI_SUBCMD_CC_DEACTIVATE_RSP		15	/*!< CC deactivation request response */
+
+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;
+};
+
+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)
+	 * unknown(3),
+	 * timeout(4),
+	 */
+	int status;
+};
+
+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),
+	 * short_term_denial(2),
+	 * long_term_denial(3),
+	 * not_subscribed(4)
+	 */
+	int status;
+	/*!
+	 * \brief Error code that can be converted to a string to further
+	 * explain the non-timeout failure.
+	 * \note Valid when non-zero.
+	 * \note Use pri_facility_error2str() to convert the error_code.
+	 */
+	int error_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_deactivate_rsp {
+	/*! \brief Call-Completion record id */
+	long cc_id;
+	/*!
+	 * \brief Status of the requested call-completion deactivation.
+	 * \details
+	 * success(0),
+	 * timeout(1),
+	 * fail(2)
+	 */
+	int status;
+	/*!
+	 * \brief Error code that can be converted to a string to further
+	 * explain the non-timeout failure.
+	 * \note Valid when non-zero.
+	 * \note Use pri_facility_error2str() to convert the error_code.
+	 */
+	int error_code;
+};
+
+/* BUGBUG eliminate the following defines */
+#define PRI_SUBCMD_CC_CCBSREQUEST_RR	93
+#define PRI_SUBCMD_CC_CCNRREQUEST_RR	94
+#define PRI_SUBCMD_CC_CANCEL_INV		95
+#define PRI_SUBCMD_CC_EXECPOSSIBLE_INV	96
+#define PRI_SUBCMD_CC_RINGOUT_INV		97
+#define PRI_SUBCMD_CC_SUSPEND_INV		98
+#define PRI_SUBCMD_CC_ERROR				99
+
+/* BUGBUG eliminate the following defines */
 #define PRI_CCERROR_UNSPECIFIED				1008
 #define PRI_CCERROR_REMOTE_USER_BUSY_AGAIN	1012
 #define PRI_CCERROR_FAILURE_TO_MATCH		1013
 
+/* BUGBUG eliminate this struct definition. */
 struct pri_subcmd_cc_ccbs_rr {
 	struct pri_qsig_cc_request_res cc_request_res;
 };
 
+/* BUGBUG eliminate this struct definition. */
 struct pri_subcmd_cc_ccnr_rr {
 	struct pri_qsig_cc_request_res cc_request_res;
 };
 
+/* BUGBUG eliminate this struct definition. */
 struct pri_subcmd_cc_cancel_inv {
 	struct pri_qsig_cc_optional_arg	cc_optional_arg;
 };
 
+/* BUGBUG eliminate this struct definition. */
 struct pri_subcmd_cc_execpossible_inv {
 	struct pri_qsig_cc_optional_arg	cc_optional_arg;
 };
 
+/* BUGBUG eliminate this struct definition. */
 struct pri_subcmd_cc_suspend_inv {
 	struct pri_qsig_cc_extension cc_extension;
 };
 
+/* BUGBUG eliminate this struct definition. */
 struct pri_subcmd_cc_ringout_inv {
 	struct pri_qsig_cc_extension cc_extension;
 };
 
+/* BUGBUG eliminate this struct definition. */
 struct pri_subcmd_cc_error {
 	int	error_value;
 };
@@ -544,6 +679,20 @@
 		char reserve_space[512];
 		struct pri_party_connected_line connected_line;
 		struct pri_party_redirecting redirecting;
+		struct pri_subcmd_status_request status_request;
+		struct pri_subcmd_status_request_rsp status_request_rsp;
+		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_status_req;
+		struct pri_subcmd_cc_status cc_status;
+		struct pri_subcmd_cc_id cc_call;
+		struct pri_subcmd_cc_id cc_cancel;
+		struct pri_subcmd_cc_id cc_deactivate_req;
+		struct pri_subcmd_cc_deactivate_rsp cc_deactivate_rsp;
+
+/* BUGBUG eliminate these struct members. */
 		struct pri_subcmd_cc_ccbs_rr cc_ccbs_rr;
 		struct pri_subcmd_cc_ccnr_rr cc_ccnr_rr;
 		struct pri_subcmd_cc_cancel_inv cc_cancel_inv;
@@ -669,7 +818,7 @@
 	long aoc_units;				/* Advise of Charge number of charged units */
 	char useruserinfo[260];		/* User->User info */
 	struct pri_subcommands *subcmds;
-} pri_event_hangup;	
+} pri_event_hangup;
 
 typedef struct pri_event_restart_ack {
 	int e;
@@ -687,7 +836,7 @@
 	q931_call *call;
 	struct pri_subcommands *subcmds;
 } pri_event_proceeding;
- 
+
 typedef struct pri_event_setup_ack {
 	int e;
 	int channel;
@@ -751,7 +900,7 @@
 
 /* Create a D-channel on a given file descriptor.  The file descriptor must be a
    channel operating in HDLC mode with FCS computed by the fd's driver.  Also it
-   must be NON-BLOCKING! Frames received on the fd should include FCS.  Nodetype 
+   must be NON-BLOCKING! Frames received on the fd should include FCS.  Nodetype
    must be one of PRI_NETWORK or PRI_CPE.  switchtype should be PRI_SWITCH_* */
 struct pri *pri_new(int fd, int nodetype, int switchtype);
 struct pri *pri_new_bri(int fd, int ptpmode, int nodetype, int switchtype);
@@ -806,6 +955,15 @@
 
 /* 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);
 
 /* 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 */
@@ -868,10 +1026,14 @@
 
 /* Create a new call */
 q931_call *pri_new_call(struct pri *pri);
+
+/* BUGBUG eliminate this prototype. */
 q931_call *pri_new_nochannel_call(struct pri *pri, int *cr);
 
+/* BUGBUG eliminate this prototype. */
 q931_call *pri_find_call(struct pri *pri, int cr);
 
+/* BUGBUG eliminate this prototype. */
 void pri_call_set_cc_operation(q931_call *call, int cc_operation);
 
 /* Retrieve CRV reference for GR-303 calls.  Returns >0 on success. */
@@ -922,8 +1084,9 @@
 /*! \note Use pri_sr_set_redirecting_parties() instead to pass more precise redirecting information. */
 int pri_sr_set_redirecting(struct pri_sr *sr, char *num, int plan, int pres, int reason);
 
-
+/* BUGBUG eliminate this prototype. */
 int pri_sr_set_ccringout(struct pri_sr *sr, int ccringout);
+/* BUGBUG eliminate this prototype. */
 int pri_sr_set_ccbsnr(struct pri_sr *sr, int ccbsnr);
 
 #define PRI_USER_USER_TX
@@ -935,10 +1098,16 @@
 
 int pri_setup(struct pri *pri, q931_call *call, struct pri_sr *req);
 
-/* Set a call has a call indpendent signalling connection (i.e. no bchan) */
+/*!
+ * \brief Set a call has a call indpendent signalling connection (i.e. no bchan)
+ * \note Call will automaticlly disconnect after signalling sent.
+ */
 int pri_sr_set_connection_call_independent(struct pri_sr *req);
 
-/* Set a no channel call (i.e. QSIG-CCBS/CCNR) */
+/*!
+ * \brief Set a call has a call indpendent signalling connection (i.e. no bchan)
+ * \note Call will stay connected until explicitly disconnected.
+ */
 int pri_sr_set_no_channel_call(struct pri_sr *req);
 
 /* Send an MWI indication to a remote location.  If activate is non zero, activates, if zero, deactivates */
@@ -1004,6 +1173,20 @@
 int pri_notify(struct pri *pri, q931_call *c, int channel, int info);
 
 int pri_callrerouting_facility(struct pri *pri, q931_call *call, const char *dest, const char* original, const char* reason);
+
+int pri_status_request(struct pri *ctrl, int request_id, const struct pri_sr *req);
+void pri_status_request_response(struct pri *ctrl, int invoke_id, int status);
+
+/* Call-completion function prototypes */
+void pri_cc_available(struct pri *ctrl, q931_call *call);
+int pri_cc_request(struct pri *ctrl, long cc_id, int mode);
+void pri_cc_request_response(struct pri *ctrl, long cc_id, int status);
+void pri_cc_remote_user_free(struct pri *ctrl, long cc_id);
+int pri_cc_status_request(struct pri *ctrl, long cc_id);
+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, int channel, int exclusive);
+void pri_cc_cancel(struct pri *ctrl, long cc_id);
+int pri_cc_deactivate_request(struct pri *ctrl, long cc_id);
 
 /* Get/Set PRI Timers  */
 #define PRI_GETSET_TIMERS
@@ -1047,11 +1230,33 @@
 	PRI_TIMER_TM20,	/*!< Maximum time awaiting XID response */
 	PRI_TIMER_NM20,	/*!< Number of XID retransmits */
 
-	PRI_TIMER_CCBST2,/*!< maximum time on completion of CC Call */
+	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,
-	PRI_MAX_TIMERS = (_PRI_MAX_TIMERS < 32) ? 32 : _PRI_MAX_TIMERS
+	PRI_MAX_TIMERS
 };
 
 /* Get PRI version */

Modified: team/group/ccss/pri.c
URL: http://svn.asterisk.org/svn-view/libpri/team/group/ccss/pri.c?view=diff&rev=993&r1=992&r2=993
==============================================================================
--- team/group/ccss/pri.c (original)
+++ team/group/ccss/pri.c Thu Aug 20 09:38:42 2009
@@ -45,6 +45,7 @@
 
 #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;
@@ -86,7 +87,24 @@
 	{ "T320",           PRI_TIMER_T320,             PRI_ALL_SWITCHES },
 	{ "T321",           PRI_TIMER_T321,             PRI_ALL_SWITCHES },
 	{ "T322",           PRI_TIMER_T322,             PRI_ALL_SWITCHES },
-	{ "CCT2",           PRI_TIMER_CCBST2,           PRI_BIT(PRI_SWITCH_QSIG) },
+	{ "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 },
+	{ "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) },
 /* *INDENT-ON* */
 };
 
@@ -151,7 +169,30 @@
 	ctrl->timers[PRI_TIMER_T313] = 4 * 1000;	/* Wait for CONNECT acknowledge, CPE side only */
 	ctrl->timers[PRI_TIMER_TM20] = 2500;		/* Max time awaiting XID response - Q.921 Appendix IV */
 	ctrl->timers[PRI_TIMER_NM20] = 3;			/* Number of XID retransmits - Q.921 Appendix IV */
-	ctrl->timers[PRI_TIMER_CCBST2] = 45 * 60 * 1000;/* Q.SIG CC-Timer2 45 min */
+
+	/* 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. */
 
 	/* Set any switch specific override default values */
 	switch (switchtype) {
@@ -778,6 +819,53 @@
 	return 0;
 }
 
+/*!
+ * \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 or unknown termination response.)
+ * \note
+ * If the switch type is not ETSI BRI PTMP NT then the status will always be
+ * an immediate unknown.
+ * \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_request(struct pri *ctrl, int request_id, const struct pri_sr *req)
+{
+	/*! \todo BUGBUG pri_status_request() not written */
+	return -1;
+}
+
+/*!
+ * \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_request_response(struct pri *ctrl, int invoke_id, int status)
+{
+	/*! \todo BUGBUG pri_status_request_response() not written */
+}
+
 #if 0
 /* deprecated routines, use pri_hangup */
 int pri_release(struct pri *pri, q931_call *call, int cause)
@@ -910,7 +998,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);
@@ -924,7 +1012,8 @@
 	if (!req)
 		return -1;
 
-	req->justsignalling = 1; /* have to set justsignalling for all those pesky IEs we need to setup */
+	req->cis_call = 1; /* have to set cis_call for all those pesky IEs we need to setup */
+	req->cis_auto_disconnect = 1;
 	return 0;
 }
 
@@ -933,7 +1022,7 @@
 	if (!req)
 		return -1;
 
-	req->nochannelsignalling = 1;
+	req->cis_call = 1;
 	return 0;
 }
 

Added: team/group/ccss/pri_cc.c
URL: http://svn.asterisk.org/svn-view/libpri/team/group/ccss/pri_cc.c?view=auto&rev=993
==============================================================================
--- team/group/ccss/pri_cc.c (added)
+++ team/group/ccss/pri_cc.c Thu Aug 20 09:38:42 2009
@@ -1,0 +1,566 @@
+/*
+ * libpri: An implementation of Primary Rate ISDN
+ *
+ * Copyright (C) 2009 Digium, Inc.
+ *
+ * Richard Mudgett <rmudgett at digium.com>
+ *
+ * See http://www.asterisk.org for more information about
+ * the Asterisk project. Please do not directly contact
+ * any of the maintainers of this project for assistance;
+ * the project provides a web site, mailing lists and IRC
+ * channels for your use.
+ *
+ * This program is free software, distributed under the terms of
+ * the GNU General Public License Version 2 as published by the
+ * Free Software Foundation. See the LICENSE file included with
+ * this program for more details.
+ *
+ * In addition, when this program is distributed with Asterisk in
+ * any form that would qualify as a 'combined work' or as a
+ * 'derivative work' (but not mere aggregation), you can redistribute
+ * and/or modify the combination under the terms of the license
+ * provided with that copy of Asterisk, instead of the license
+ * terms granted here.
+ */
+
+/*!
+ * \file
+ * \brief Call Completion controller
+ *
+ * \author Richard Mudgett <rmudgett at digium.com>
+ */
+
+
+#include "compat.h"
+#include "libpri.h"
+#include "pri_internal.h"
+#include "pri_q921.h"
+#include "pri_q931.h"
+
+#include <stdlib.h>
+
+
+/* ------------------------------------------------------------------- */
+
+#if defined(BUGBUG_NOT_USED_YET)
+/*!
+ * \internal
+ * \brief Find a cc_record by the PTMP reference_id.
+ *
+ * \param ctrl D channel controller.
+ * \param reference_id CCBS reference ID to look for in cc_record pool.
+ *
+ * \retval cc_record on success.
+ * \retval NULL on error.
+ */
+static struct pri_cc_record *pri_cc_find_by_reference(struct pri *ctrl, unsigned reference_id)
+{
+	struct pri_cc_record *cc_record;
+
+	for (cc_record = ctrl->cc_pool; cc_record; cc_record = cc_record->next) {
+		if (cc_record->ccbs_reference_id == reference_id) {
+			/* Found the record */
+			break;
+		}
+	}
+
+	return cc_record;
+}
+#endif
+
+#if defined(BUGBUG_NOT_USED_YET)
+/*!
+ * \internal
+ * \brief Find a cc_record by the PTMP linkage_id.
+ *
+ * \param ctrl D channel controller.
+ * \param linkage_id Call linkage ID to look for in cc_record pool.
+ *
+ * \retval cc_record on success.
+ * \retval NULL on error.
+ */
+static struct pri_cc_record *pri_cc_find_by_linkage(struct pri *ctrl, unsigned linkage_id)
+{
+	struct pri_cc_record *cc_record;
+
+	for (cc_record = ctrl->cc_pool; cc_record; cc_record = cc_record->next) {
+		if (cc_record->call_linkage_id == linkage_id) {
+			/* Found the record */
+			break;
+		}
+	}
+
+	return cc_record;
+}
+#endif
+
+/*!
+ * \internal
+ * \brief Find a cc_record by the cc_id.
+ *
+ * \param ctrl D channel controller.
+ * \param cc_id ID to look for in cc_record pool.
+ *
+ * \retval cc_record on success.
+ * \retval NULL on error.
+ */
+static struct pri_cc_record *pri_cc_find_by_id(struct pri *ctrl, long cc_id)
+{
+	struct pri_cc_record *cc_record;
+
+	for (cc_record = ctrl->cc_pool; cc_record; cc_record = cc_record->next) {
+		if (cc_record->record_id == cc_id) {
+			/* Found the record */
+			break;
+		}
+	}
+
+	return cc_record;
+}
+
+#if defined(BUGBUG_NOT_USED_YET)
+/*!
+ * \internal
+ * \brief Find a cc_record by an incoming call addressing data.
+ *
+ * \param ctrl D channel controller.
+ * \param party_a Party A address. 
+ * \param party_b Party B address.
+ *
+ * \retval cc_record on success.
+ * \retval NULL on error.
+ */
+static struct pri_cc_record *pri_cc_find_by_addressing(struct pri *ctrl, const struct q931_party_address *party_a, const struct q931_party_address *party_b)
+{
+	struct pri_cc_record *cc_record;
+
+	for (cc_record = ctrl->cc_pool; cc_record; cc_record = cc_record->next) {
+		if (!q931_cmp_party_id_to_address(&cc_record->party_a, party_a)
+			&& !q931_party_address_cmp(&cc_record->party_b, party_b)) {
+			/* Found the record */
+			break;
+		}
+	}
+
+	return cc_record;
+
+	/*! \todo BUGBUG pri_cc_find_by_addressing() not written */
+}
+#endif
+
+#if defined(BUGBUG_NOT_USED_YET)
+/*!
+ * \internal
+ * \brief Allocate a new cc_record id.
+ *
+ * \param ctrl D channel controller.
+ *
+ * \retval cc_id on success.
+ * \retval -1 on error.
+ */
+static long pri_cc_new_id(struct pri *ctrl)
+{
+	long record_id;
+	long first_id;
+
+	record_id = ++ctrl->last_cc_id;
+	first_id = record_id;
+	while (pri_cc_find_by_id(ctrl, record_id)) {
+		record_id = ++ctrl->last_cc_id;
+		if (record_id == first_id) {
+			/*
+			 * We have a resource leak.
+			 * We should never need to allocate 64k records on a D channel.
+			 */
+			pri_error(ctrl, "ERROR Too many call completion records!\n");
+			record_id = -1;
+			break;
+		}
+	}
+
+	return record_id;
+}
+#endif
+
+#if defined(BUGBUG_NOT_USED_YET)
+/*!
+ * \internal
+ * \brief Delete the given call completion record
+ *
+ * \param ctrl D channel controller.
+ * \param doomed Call completion record to destroy
+ *
+ * \return Nothing
+ */
+static void pri_cc_delete_record(struct pri *ctrl, struct pri_cc_record *doomed)
+{
+	struct pri_cc_record **prev;
+	struct pri_cc_record *current;
+
+	for (prev = &ctrl->cc_pool, current = ctrl->cc_pool; current;
+		prev = &current->next, current = current->next) {
+		if (current == doomed) {
+			*prev = current->next;
+			free(doomed);
+			return;
+		}
+	}
+
+	/* The doomed node is not in the call completion database */
+}
+#endif
+
+#if defined(BUGBUG_NOT_USED_YET)
+/*!
+ * \internal
+ * \brief Allocate a new cc_record.
+ *
+ * \param ctrl D channel controller.
+ *
+ * \retval cc_id on success.
+ * \retval -1 on error.
+ */
+static long pri_cc_new_record(struct pri *ctrl)
+{
+	struct pri_cc_record *cc_record;
+	long record_id;
+
+	cc_record = calloc(1, sizeof(*cc_record));
+	if (!cc_record) {
+		return -1;
+	}
+	record_id = pri_cc_new_id(ctrl);
+	if (record_id < 0) {
+		free(cc_record);
+		return -1;
+	}
+
+	/* Initialize the new record */
+	cc_record->record_id = record_id;
+	cc_record->call_linkage_id = 0xFF;/* Invalid so it will never be found this way */
+	cc_record->ccbs_reference_id = 0xFF;/* Invalid so it will never be found this way */
+	q931_party_id_init(&cc_record->party_a);
+	q931_party_address_init(&cc_record->party_b);
+/*! \todo BUGBUG need more initialization?? */
+
+	/* Insert the new record into the database */
+	cc_record->next = ctrl->cc_pool;
+	ctrl->cc_pool = cc_record;
+
+	return record_id;
+}
+#endif
+
+/*!
+ * \brief Indicate to the far end that CCBS/CCNR is available.
+ *
+ * \param ctrl D channel controller.
+ * \param call Q.931 call leg.
+ *
+ * \details
+ * The CC available indication will go out with the next
+ * DISCONNECT(busy/congested)/ALERTING message.
+ *
+ * \return Nothing
+ */
+void pri_cc_available(struct pri *ctrl, q931_call *call)
+{
+	switch (ctrl->switchtype) {
+	case PRI_SWITCH_QSIG:
+		/*
+		 * Q.SIG has no message to send when CC is available.
+		 * Q.SIG assumes CC is always available and is denied when
+		 * requested if CC is not possible or allowed.
+		 */
+		break;
+	case PRI_SWITCH_EUROISDN_E1:
+	case PRI_SWITCH_EUROISDN_T1:
+		if (q931_is_ptmp(ctrl)) {
+		} else {
+		}
+		/*! \todo BUGBUG pri_cc_available() not written */
+		break;
+	default:
+		break;
+	}
+}
+
+/*!
+ * \brief Request to activate CC.
+ *
+ * \param ctrl D channel controller.
+ * \param cc_id CC record ID to activate.
+ * \param mode Which CC mode to use CCBS(0)/CCNR(1)
+ *
+ * \note
+ * Will always get a reply from libpri.  libpri will start a timer to guarantee
+ * that a reply will be passed back to the upper layer.
+ *
+ * \retval 0 on success.
+ * \retval -1 on error.
+ */
+int pri_cc_request(struct pri *ctrl, long cc_id, int mode)
+{
+	struct pri_sr req;
+	q931_call *call;
+	struct pri_cc_record *cc_record;
+
+	cc_record = pri_cc_find_by_id(ctrl, cc_id);
+	if (!cc_record) {
+		return -1;
+	}
+
+	if (cc_record->state == CC_STATE_IDLE) {
+		cc_record->party_b_is_remote = 1;
+	}
+
+	switch (ctrl->switchtype) {
+	case PRI_SWITCH_QSIG:
+		call = q931_new_call(ctrl);
+		if (!call) {
+			return -1;
+		}
+
+/* BUGBUG */
+		//add_qsigCcRequestArg_facility_ie(ctrl, call, Q931_SETUP, cc_record, mode);
+
+		pri_sr_init(&req);
+		req.caller = cc_record->party_a;
+		req.called = cc_record->party_b;
+		req.numcomplete = 1;
+		req.cis_auto_disconnect = 0;
+		req.cis_call = 1;
+		if (q931_setup(ctrl, call, &req)) {
+			return -1;
+		}
+		break;
+	case PRI_SWITCH_EUROISDN_E1:
+	case PRI_SWITCH_EUROISDN_T1:
+		if (q931_is_ptmp(ctrl)) {
+		} else {
+		}
+		return -1;
+		break;
+	default:
+		return -1;
+	}
+
+	cc_record->state = CC_STATE_REQUESTED;
+
+	return 0;
+
+	/*! \todo BUGBUG pri_cc_request() not written */
+}
+
+/*!
+ * \brief Response to an incoming CC activation request.
+ *
+ * \param ctrl D channel controller.
+ * \param cc_id CC record ID to activate.
+ * \param status success(0)/timeout(1)/
+ *		short_term_denial(2)/long_term_denial(3)/not_subscribed(4)
+ *
+ * \return Nothing
+ */
+void pri_cc_request_response(struct pri *ctrl, long cc_id, int status)
+{
+	switch (ctrl->switchtype) {
+	case PRI_SWITCH_QSIG:
+		break;
+	case PRI_SWITCH_EUROISDN_E1:
+	case PRI_SWITCH_EUROISDN_T1:
+		if (q931_is_ptmp(ctrl)) {
+		} else {
+		}
+		break;
+	default:
+		break;
+	}
+
+	/*! \todo BUGBUG pri_cc_request_response() not written */
+}
+
+/*!
+ * \brief Indicate that the remote user (Party B) is free to call.
+ *
+ * \param ctrl D channel controller.
+ * \param cc_id CC record ID to activate.
+ *
+ * \return Nothing
+ */
+void pri_cc_remote_user_free(struct pri *ctrl, long cc_id)
+{
+	switch (ctrl->switchtype) {
+	case PRI_SWITCH_QSIG:
+		break;
+	case PRI_SWITCH_EUROISDN_E1:
+	case PRI_SWITCH_EUROISDN_T1:
+		if (q931_is_ptmp(ctrl)) {
+		} else {
+		}
+		break;
+	default:
+		break;
+	}
+
+	/*! \todo BUGBUG pri_cc_remote_user_free() not written */
+}
+
+/*!
+ * \brief Poll/Ping for the status of CC party A.
+ *
+ * \param ctrl D channel controller.
+ * \param cc_id CC record ID to activate.
+ *
+ * \note
+ * There could be zero, one, or more PRI_SUBCMD_CC_STATUS responses to the
+ * status request depending upon how many endpoints respond to the request.
+ * \note
+ * This is expected to be called only if there are two PTMP links between
+ * party A and the network.  (e.g., A --> * --> PSTN)
+ *
+ * \retval 0 on success.
+ * \retval -1 on error.
+ */
+int pri_cc_status_request(struct pri *ctrl, long cc_id)
+{
+	switch (ctrl->switchtype) {
+	case PRI_SWITCH_QSIG:
+		break;
+	case PRI_SWITCH_EUROISDN_E1:
+	case PRI_SWITCH_EUROISDN_T1:
+		if (q931_is_ptmp(ctrl)) {
+		} else {
+		}
+		break;
+	default:
+		break;
+	}
+
+	/*! \todo BUGBUG pri_cc_status_request() not written */
+	return -1;
+}
+
+/*!
+ * \brief Update the busy status of CC party A.
+ *
+ * \param ctrl D channel controller.
+ * \param cc_id CC record ID to activate.
+ * \param status Updated party A status free(0)/busy(1)
+ *
+ * \note
+ * Party A status is used to suspend/resume monitoring party B.
+ *
+ * \return Nothing
+ */
+void pri_cc_status(struct pri *ctrl, long cc_id, int status)
+{
+	switch (ctrl->switchtype) {
+	case PRI_SWITCH_QSIG:
+		break;
+	case PRI_SWITCH_EUROISDN_E1:
+	case PRI_SWITCH_EUROISDN_T1:
+		if (q931_is_ptmp(ctrl)) {
+		} else {
+		}
+		break;
+	default:
+		break;
+	}
+
+	/*! \todo BUGBUG pri_cc_status() not written */
+}
+
+/*!
+ * \brief Initiate the CC callback call.
+ *
+ * \param ctrl D channel controller.
+ * \param cc_id CC record ID to activate.
+ * \param call Q.931 call leg.
+ * \param channel Encoded B channel to use.
+ * \param exclusive TRUE if the specified B channel must be used.
+ *
+ * \retval 0 on success.
+ * \retval -1 on error.
+ */
+int pri_cc_call(struct pri *ctrl, long cc_id, q931_call *call, int channel, int exclusive)
+{
+	switch (ctrl->switchtype) {
+	case PRI_SWITCH_QSIG:
+		break;
+	case PRI_SWITCH_EUROISDN_E1:
+	case PRI_SWITCH_EUROISDN_T1:
+		if (q931_is_ptmp(ctrl)) {
+		} else {
+		}
+		break;
+	default:
+		break;
+	}
+
+	/*! \todo BUGBUG pri_cc_call() not written */
+	return -1;
+}
+
+/*!
+ * \brief Unsolicited indication that CC is cancelled.
+ *
+ * \param ctrl D channel controller.
+ * \param cc_id CC record ID to deactivate.
+ *
+ * \return Nothing.  The cc_id is no longer valid.
+ */
+void pri_cc_cancel(struct pri *ctrl, long cc_id)
+{
+	switch (ctrl->switchtype) {
+	case PRI_SWITCH_QSIG:
+		break;
+	case PRI_SWITCH_EUROISDN_E1:
+	case PRI_SWITCH_EUROISDN_T1:
+		if (q931_is_ptmp(ctrl)) {
+		} else {
+		}
+		break;
+	default:
+		break;
+	}
+
+	/*! \todo BUGBUG pri_cc_cancel() not written */
+}
+
+/*!
+ * \brief Request that the CC be canceled.
+ *
+ * \param ctrl D channel controller.
+ * \param cc_id CC record ID to request deactivation.
+ *
+ * \note
+ * Will always get a PRI_SUBCMD_CC_DEACTIVATE_RSP from libpri.
+ * \note
+ * Deactivate is used in the party A to party B direction.
+ *
+ * \retval 0 on success.
+ * \retval -1 on error.
+ */
+int pri_cc_deactivate_request(struct pri *ctrl, long cc_id)
+{
+	switch (ctrl->switchtype) {
+	case PRI_SWITCH_QSIG:
+		break;
+	case PRI_SWITCH_EUROISDN_E1:
+	case PRI_SWITCH_EUROISDN_T1:
+		if (q931_is_ptmp(ctrl)) {
+		} else {
+		}
+		break;
+	default:
+		break;
+	}
+
+	/*! \todo BUGBUG pri_cc_deactivate_request() not written */
+	return -1;
+}
+
+/* ------------------------------------------------------------------- */
+/* end pri_cc.c */

Propchange: team/group/ccss/pri_cc.c
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: team/group/ccss/pri_cc.c
------------------------------------------------------------------------------
    svn:keywords = 'Author Date Id Revision'

Propchange: team/group/ccss/pri_cc.c
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Modified: team/group/ccss/pri_facility.c
URL: http://svn.asterisk.org/svn-view/libpri/team/group/ccss/pri_facility.c?view=diff&rev=993&r1=992&r2=993
==============================================================================
--- team/group/ccss/pri_facility.c (original)
+++ team/group/ccss/pri_facility.c Thu Aug 20 09:38:42 2009
@@ -39,6 +39,11 @@
 #include <stdlib.h>
 #include <string.h>
 #include <limits.h>
+
+const char *pri_facility_error2str(int facility_error_code)
+{
+	return rose_error2str(facility_error_code);
+}
 
 static short get_invokeid(struct pri *ctrl)
 {
@@ -170,6 +175,7 @@
 }
 
 /*!
+ * \internal
  * \brief Convert the Q.931 type-of-number field to facility.
  *
  * \param ctrl D channel controller for diagnostic messages or global options.

Modified: team/group/ccss/pri_internal.h
URL: http://svn.asterisk.org/svn-view/libpri/team/group/ccss/pri_internal.h?view=diff&rev=993&r1=992&r2=993
==============================================================================
--- team/group/ccss/pri_internal.h (original)
+++ team/group/ccss/pri_internal.h Thu Aug 20 09:38:42 2009
@@ -47,9 +47,10 @@
 struct q921_frame;
 enum q931_state;
 enum q931_mode;
+struct pri_cc_record;
 
 /*! Maximum number of scheduled events active at the same time. */
-#define MAX_SCHED (128 + 256) /* 256 ccT2 timer events*/
+#define MAX_SCHED	(128 + 256) /* 256 CC supervision timer events */
 
 /*! \brief D channel controller structure */
 struct pri {
@@ -114,6 +115,9 @@
 	q931_call **callpool;
 	q931_call *localpool;
 
+	/*! Active call-completion records */
+	struct pri_cc_record *cc_pool;
+
 	/* do we do overlap dialing */
 	int overlapdial;
 
@@ -131,6 +135,8 @@
 	unsigned int q931_rxcount;
 #endif
 
+	/*! Last CC id allocated. */
+	unsigned short last_cc_id;
 	short last_invoke;	/* Last ROSE invoke ID */
 	unsigned char sendfacility;
 };
@@ -292,8 +298,8 @@
 	struct q931_party_address called;
 	int userl1;
 	int numcomplete;
-	int justsignalling;
-	int nochannelsignalling;
+	int cis_call;
+	int cis_auto_disconnect;
 	const char *useruserinfo;
 	int transferable;
 	int reversecharge;
@@ -370,8 +376,13 @@
 	int userl3;
 	int rateadaption;
 
-	int justsignalling;		/* for a signalling-only connection */
-	int nochannelsignalling;
+	/*!
+	 * \brief TRUE if the call is a Call Independent Signalling connection.
+	 * \note The call has no B channel associated with it. (Just signalling)
+	 */
+	int cis_call;
+	/*! \brief TRUE if we will auto disconnect the cis_call we originated. */
+	int cis_auto_disconnect;
 
 	int progcode;			/* Progress coding */
 	int progloc;			/* Progress Location */	
@@ -388,6 +399,7 @@
 	int ourcallstate;		/* Our call state */
 	int sugcallstate;		/* Status call state */
 
+/* BUGBUG These CC elements may not be retained. */
 	int ccoperation;		/* QSIG_CCBSREQUEST/QSIG_CCNRREQUEST */
 	int ccrequestresult;
 	int cctimer2;			/* Timer for QSIG-timer2 */
@@ -473,6 +485,46 @@
 							0,2-7 - Reserved for future use */
 };
 
+enum CC_STATES {
+	/*! CC is not active. */
+	CC_STATE_IDLE,
+	/*! CC has recorded call information in anticipation of CC availability. */
+	CC_STATE_RECORD_RETENTION,
+	/*! CC is available and waiting on possible CC request. */
+	CC_STATE_AVAILABLE,
+	/*! CC is requested to be activated and waiting on party B to acknowledge. */
+	CC_STATE_REQUESTED,
+	/*! CC is activated and waiting for party B to become available. */
+	CC_STATE_ACTIVATED,
+	/*! CC party B is available and waiting for status of party A. */
+	CC_STATE_B_AVAILABLE,
+	/*! CC is suspended because party A is not available. */
+	CC_STATE_SUSPENDED,
+	/*! CC is waiting for party A to initiate CC callback. */
+	CC_STATE_WAIT_CALLBACK,
+};
+
+/*! \brief Call-completion record */
+struct pri_cc_record {
+	/*! Next call-completion record in the list */
+	struct pri_cc_record *next;
+	/*! Call-completion record id */
+	long record_id;
+	/*! Call-completion state */
+	enum CC_STATES state;
+	/*! Original calling party. */
+	struct q931_party_id party_a;
+	/*! Original called party. */
+	struct q931_party_address party_b;
+

[... 357 lines stripped ...]



More information about the libpri-commits mailing list