[asterisk-commits] rmudgett: branch rmudgett/dahdi_ccss r240001 - /team/rmudgett/dahdi_ccss/chan...

SVN commits to the Asterisk project asterisk-commits at lists.digium.com
Wed Jan 13 17:31:36 CST 2010


Author: rmudgett
Date: Wed Jan 13 17:31:34 2010
New Revision: 240001

URL: http://svnview.digium.com/svn/asterisk?view=rev&rev=240001
Log:
Fill in CCSS PRI subcmd handling.

Modified:
    team/rmudgett/dahdi_ccss/channels/sig_pri.c

Modified: team/rmudgett/dahdi_ccss/channels/sig_pri.c
URL: http://svnview.digium.com/svn/asterisk/team/rmudgett/dahdi_ccss/channels/sig_pri.c?view=diff&rev=240001&r1=240000&r2=240001
==============================================================================
--- team/rmudgett/dahdi_ccss/channels/sig_pri.c (original)
+++ team/rmudgett/dahdi_ccss/channels/sig_pri.c Wed Jan 13 17:31:34 2010
@@ -73,11 +73,15 @@
 
 struct sig_pri_cc_monitor_instance {
 	/*!
-	 * CC core monitor structure associted with this monitor instance.
-	 * NULL if no association established.
+	 * \brief CC core monitor structure associted with this monitor instance.
+	 * \note NULL if no association established.
+	 * \note Holds a reference to the CC core monitor if not NULL.
 	 */
 	struct ast_cc_monitor *monitor;
-	/*! Asterisk span D channel control structure. */
+	/*!
+	 * \brief Asterisk span D channel control structure.
+	 * \note NULL if libpri association already canceled.
+	 */
 	struct sig_pri_pri *pri;
 	/*! CC id value to use with libpri. -1 if invalid. */
 	long cc_id;
@@ -1585,7 +1589,7 @@
 	struct sig_pri_cc_monitor_instance *monitor_1 = obj;
 	struct sig_pri_cc_monitor_instance *monitor_2 = arg;
 
-	return (monitor_1->pri == monitor_2->pri
+	return (monitor_1->pri && monitor_1->pri == monitor_2->pri
 		&& monitor_1->cc_id == monitor_2->cc_id) ? CMP_MATCH | CMP_STOP : 0;
 }
 #endif	/* defined(HAVE_PRI_CCSS) */
@@ -1768,8 +1772,8 @@
 		res = ast_queue_cc_frame(owner, sig_pri_cc_type_name,
 			sig_pri_get_orig_dialstring(pri->pvts[chanpos]), service);
 		if (res) {
+			ao2_unlink(sig_pri_cc_monitors, monitor);
 			monitor->pri = NULL;
-			ao2_unlink(sig_pri_cc_monitors, monitor);
 		}
 		ao2_ref(monitor, -1);
 		break;
@@ -1873,6 +1877,45 @@
 }
 #endif	/* defined(HAVE_PRI_CCSS) */
 
+#if defined(HAVE_PRI_CCSS)
+/*!
+ * \internal
+ * \brief The CC link canceled the CC instance.
+ * \since 1.8
+ *
+ * \param pri sig_pri PRI control structure.
+ * \param cc_id CC record ID.
+ * \param is_agent TRUE if the cc_id is for an agent.
+ *
+ * \return Nothing
+ */
+static void sig_pri_cc_link_canceled(struct sig_pri_pri *pri, long cc_id, int is_agent)
+{
+	if (is_agent) {
+		struct ast_cc_agent *agent;
+
+		agent = sig_pri_find_cc_agent_by_cc_id(pri, cc_id);
+		if (!agent) {
+			return;
+		}
+		ast_cc_failed(agent->core_id, "ISDN agent got canceled by link");
+		ao2_ref(agent, -1);
+	} else {
+		struct sig_pri_cc_monitor_instance *monitor;
+
+		monitor = sig_pri_find_cc_monitor_by_cc_id(pri, cc_id);
+		if (!monitor) {
+			return;
+		}
+		ao2_unlink(sig_pri_cc_monitors, monitor);
+		monitor->pri = NULL;
+		ast_cc_monitor_failed(monitor->core_id, monitor->name,
+			sig_pri_cc_type_name);
+		ao2_ref(monitor, -1);
+	}
+}
+#endif	/* defined(HAVE_PRI_CCSS) */
+
 /*!
  * \internal
  * \brief TRUE if PRI event came in on a CIS call.
@@ -1966,22 +2009,30 @@
 				break;
 			case 1:/* timeout */
 				ast_verb(2, "%s CC request timeout\n", sig_pri_cc_type_name);
+				ao2_unlink(sig_pri_cc_monitors, monitor);
+				monitor->pri = NULL;
 				ast_cc_monitor_failed(monitor->core_id, monitor->name,
 					sig_pri_cc_type_name);
 				break;
 			case 2:/* error */
 				ast_verb(2, "%s CC request error: %s\n", sig_pri_cc_type_name,
 					pri_facility_error2str(subcmd->u.cc_request_rsp.fail_code));
+				ao2_unlink(sig_pri_cc_monitors, monitor);
+				monitor->pri = NULL;
 				ast_cc_monitor_failed(monitor->core_id, monitor->name,
 					sig_pri_cc_type_name);
 				break;
 			case 3:/* reject */
 				ast_verb(2, "%s CC request reject: %s\n", sig_pri_cc_type_name,
 					pri_facility_reject2str(subcmd->u.cc_request_rsp.fail_code));
+				ao2_unlink(sig_pri_cc_monitors, monitor);
+				monitor->pri = NULL;
 				ast_cc_monitor_failed(monitor->core_id, monitor->name,
 					sig_pri_cc_type_name);
 				break;
 			default:
+				ao2_unlink(sig_pri_cc_monitors, monitor);
+				monitor->pri = NULL;
 				ast_cc_monitor_failed(monitor->core_id, monitor->name,
 					sig_pri_cc_type_name);
 				break;
@@ -1991,37 +2042,93 @@
 #endif	/* defined(HAVE_PRI_CCSS) */
 #if defined(HAVE_PRI_CCSS)
 		case PRI_SUBCMD_CC_REMOTE_USER_FREE:
-			/*! \todo BUGBUG sig_pri_handle_cis_subcmds() not written */
+			monitor = sig_pri_find_cc_monitor_by_cc_id(pri,
+				subcmd->u.cc_remote_user_free.cc_id);
+			if (!monitor) {
+				pri_cc_cancel(pri->pri, subcmd->u.cc_remote_user_free.cc_id);
+				break;
+			}
+			if (ast_cc_monitor_callee_available(monitor->monitor)) {
+				ao2_unlink(sig_pri_cc_monitors, monitor);
+			}
+			ao2_ref(monitor, -1);
 			break;
 #endif	/* defined(HAVE_PRI_CCSS) */
 #if defined(HAVE_PRI_CCSS)
 		case PRI_SUBCMD_CC_B_FREE:
-			/*! \todo BUGBUG sig_pri_handle_cis_subcmds() not written */
+			monitor = sig_pri_find_cc_monitor_by_cc_id(pri,
+				subcmd->u.cc_b_free.cc_id);
+			if (!monitor) {
+				pri_cc_cancel(pri->pri, subcmd->u.cc_b_free.cc_id);
+				break;
+			}
+			if (ast_cc_monitor_party_b_free(monitor->core_id)) {
+				ao2_unlink(sig_pri_cc_monitors, monitor);
+			}
+			ao2_ref(monitor, -1);
 			break;
 #endif	/* defined(HAVE_PRI_CCSS) */
 #if defined(HAVE_PRI_CCSS)
 		case PRI_SUBCMD_CC_STATUS_REQ:
-			/*! \todo BUGBUG sig_pri_handle_cis_subcmds() not written */
+			monitor = sig_pri_find_cc_monitor_by_cc_id(pri,
+				subcmd->u.cc_status_req.cc_id);
+			if (!monitor) {
+				pri_cc_cancel(pri->pri, subcmd->u.cc_status_req.cc_id);
+				break;
+			}
+			if (ast_cc_monitor_status_request(monitor->core_id)) {
+				ao2_unlink(sig_pri_cc_monitors, monitor);
+			}
+			ao2_ref(monitor, -1);
 			break;
 #endif	/* defined(HAVE_PRI_CCSS) */
 #if defined(HAVE_PRI_CCSS)
 		case PRI_SUBCMD_CC_STATUS_REQ_RSP:
-			/*! \todo BUGBUG sig_pri_handle_cis_subcmds() not written */
+			agent = sig_pri_find_cc_agent_by_cc_id(pri, subcmd->u.cc_status_req_rsp.cc_id);
+			if (!agent) {
+				pri_cc_cancel(pri->pri, subcmd->u.cc_status_req_rsp.cc_id);
+				break;
+			}
+			ast_cc_agent_status_response(agent->core_id,
+				subcmd->u.cc_status_req_rsp.status ? AST_DEVICE_INUSE
+				: AST_DEVICE_NOT_INUSE);
+			ao2_ref(agent, -1);
 			break;
 #endif	/* defined(HAVE_PRI_CCSS) */
 #if defined(HAVE_PRI_CCSS)
 		case PRI_SUBCMD_CC_STATUS:
-			/*! \todo BUGBUG sig_pri_handle_cis_subcmds() not written */
+			agent = sig_pri_find_cc_agent_by_cc_id(pri, subcmd->u.cc_status.cc_id);
+			if (!agent) {
+				pri_cc_cancel(pri->pri, subcmd->u.cc_status.cc_id);
+				break;
+			}
+			if (subcmd->u.cc_status.status) {
+				ast_cc_agent_caller_busy(agent->core_id, "ISDN agent caller is busy");
+			} else {
+				ast_cc_agent_caller_available(agent->core_id,
+					"ISDN agent caller is available");
+			}
+			ao2_ref(agent, -1);
 			break;
 #endif	/* defined(HAVE_PRI_CCSS) */
 #if defined(HAVE_PRI_CCSS)
 		case PRI_SUBCMD_CC_CANCEL:
-			/*! \todo BUGBUG sig_pri_handle_cis_subcmds() not written */
+			sig_pri_cc_link_canceled(pri, subcmd->u.cc_cancel.cc_id,
+				subcmd->u.cc_cancel.is_agent);
 			break;
 #endif	/* defined(HAVE_PRI_CCSS) */
 #if defined(HAVE_PRI_CCSS)
 		case PRI_SUBCMD_CC_STOP_ALERTING:
-			/*! \todo BUGBUG sig_pri_handle_cis_subcmds() not written */
+			monitor = sig_pri_find_cc_monitor_by_cc_id(pri,
+				subcmd->u.cc_stop_alerting.cc_id);
+			if (!monitor) {
+				pri_cc_cancel(pri->pri, subcmd->u.cc_stop_alerting.cc_id);
+				break;
+			}
+			if (ast_cc_monitor_stop_ringing(monitor->core_id)) {
+				ao2_unlink(sig_pri_cc_monitors, monitor);
+			}
+			ao2_ref(monitor, -1);
 			break;
 #endif	/* defined(HAVE_PRI_CCSS) */
 		default:
@@ -2237,12 +2344,30 @@
 #endif	/* defined(HAVE_PRI_CCSS) */
 #if defined(HAVE_PRI_CCSS)
 		case PRI_SUBCMD_CC_CALL:
-			/*! \todo BUGBUG sig_pri_handle_subcmds() not written */
+			sig_pri_lock_owner(pri, chanpos);
+			owner = pri->pvts[chanpos]->owner;
+			if (owner) {
+				struct ast_cc_agent *agent;
+				char device_name[AST_CHANNEL_NAME];
+
+				agent = sig_pri_find_cc_agent_by_cc_id(pri, subcmd->u.cc_call.cc_id);
+				if (agent) {
+					ast_setup_cc_recall_datastore(owner, agent->core_id);
+					ast_channel_get_device_name(owner, device_name, sizeof(device_name));
+					ast_set_cc_interfaces_chanvar(owner, device_name);
+					ast_cc_agent_recalling(agent->core_id,
+						"ISDN caller is attempting recall");
+					ao2_ref(agent, -1);
+				}
+
+				ast_channel_unlock(owner);
+			}
 			break;
 #endif	/* defined(HAVE_PRI_CCSS) */
 #if defined(HAVE_PRI_CCSS)
 		case PRI_SUBCMD_CC_CANCEL:
-			/*! \todo BUGBUG sig_pri_handle_subcmds() not written */
+			sig_pri_cc_link_canceled(pri, subcmd->u.cc_cancel.cc_id,
+				subcmd->u.cc_cancel.is_agent);
 			break;
 #endif	/* defined(HAVE_PRI_CCSS) */
 		default:




More information about the asterisk-commits mailing list