[asterisk-commits] trunk r37318 - in /trunk: ./ apps/ channels/ include/asterisk/

asterisk-commits at lists.digium.com asterisk-commits at lists.digium.com
Fri Jul 7 19:24:07 MST 2006


Author: markster
Date: Fri Jul  7 21:24:07 2006
New Revision: 37318

URL: http://svn.digium.com/view/asterisk?rev=37318&view=rev
Log:
Support hold/unhold in Zap, update IAX2 parser to know about modern commands, forward hold/unhold in dial, add hold device state 
and implement holding in the SLA.

Modified:
    trunk/apps/app_dial.c
    trunk/apps/app_meetme.c
    trunk/channels/chan_zap.c
    trunk/channels/iax2-parser.c
    trunk/devicestate.c
    trunk/include/asterisk/devicestate.h
    trunk/include/asterisk/pbx.h
    trunk/pbx.c

Modified: trunk/apps/app_dial.c
URL: http://svn.digium.com/view/asterisk/trunk/apps/app_dial.c?rev=37318&r1=37317&r2=37318&view=diff
==============================================================================
--- trunk/apps/app_dial.c (original)
+++ trunk/apps/app_dial.c Fri Jul  7 21:24:07 2006
@@ -728,10 +728,13 @@
 				if (ast_write(outgoing->chan, f))
 					ast_log(LOG_WARNING, "Unable to forward voice\n");
 			}
-			if (single && (f->frametype == AST_FRAME_CONTROL) && (f->subclass == AST_CONTROL_VIDUPDATE)) {
+			if (single && (f->frametype == AST_FRAME_CONTROL) && 
+				((f->subclass == AST_CONTROL_HOLD) || 
+				 (f->subclass == AST_CONTROL_UNHOLD) || 
+				 (f->subclass == AST_CONTROL_VIDUPDATE))) {
 				if (option_verbose > 2)
-					ast_verbose(VERBOSE_PREFIX_3 "%s requested a video update, passing it to %s\n", in->name,outgoing->chan->name);
-				ast_indicate(outgoing->chan, AST_CONTROL_VIDUPDATE);
+					ast_verbose(VERBOSE_PREFIX_3 "%s requested special control %d, passing it to %s\n", in->name, f->subclass, outgoing->chan->name);
+				ast_indicate_data(outgoing->chan, f->subclass, f->data, f->datalen);
 			}
 			ast_frfree(f);
 		}

Modified: trunk/apps/app_meetme.c
URL: http://svn.digium.com/view/asterisk/trunk/apps/app_meetme.c?rev=37318&r1=37317&r2=37318&view=diff
==============================================================================
--- trunk/apps/app_meetme.c (original)
+++ trunk/apps/app_meetme.c Fri Jul  7 21:24:07 2006
@@ -145,11 +145,17 @@
 	/*! If set, won't speak the extra prompt when the first person 
 	 *  enters the conference */
 	CONFFLAG_NOONLYPERSON = (1 << 22),
-	CONFFLAG_INTROUSERNOREVIEW = (1 << 23),
 	/*! If set, user will be asked to record name on entry of conference 
 	 *  without review */
-	CONFFLAG_STARTMUTED = (1 << 24)
+	CONFFLAG_INTROUSERNOREVIEW = (1 << 23),
 	/*! If set, the user will be initially self-muted */
+	CONFFLAG_STARTMUTED = (1 << 24),
+	/*! If set, the user is a shared line appearance station */
+	CONFFLAG_SLA_STATION = (1 << 25),
+	/*! If set, the user is a shared line appearance trunk */
+	CONFFLAG_SLA_TRUNK = (1 << 26),
+	/*! If set, the user has put us on hold */
+	CONFFLAG_HOLD = (1 << 27)
 };
 
 AST_APP_OPTIONS(meetme_opts, {
@@ -332,7 +338,9 @@
 	int talking;                            /*!< Is user talking */
 	int zapchannel;                         /*!< Is a Zaptel channel */
 	char usrvalue[50];                      /*!< Custom User Value */
-	char namerecloc[PATH_MAX];		/*!< Name Recorded file Location */
+	char namerecloc[PATH_MAX];				/*!< Name Recorded file Location */
+	int control;							/*! Queue Control for transmission */
+	int dtmf;								/*! Queue DTMF for transmission */
 	time_t jointime;                        /*!< Time the user joined the conference */
 	struct volume talk;
 	struct volume listen;
@@ -809,7 +817,7 @@
 			min = ((now - user->jointime) % 3600) / 60;
 			sec = (now - user->jointime) % 60;
 			if ( !concise )
-				ast_cli(fd, "User #: %-2.2d %12.12s %-20.20s Channel: %s %s %s %s %s %02d:%02d:%02d\n",
+				ast_cli(fd, "User #: %-2.2d %12.12s %-20.20s Channel: %s %s %s %s %s %s %02d:%02d:%02d\n",
 					user->user_no,
 					S_OR(user->chan->cid.cid_num, "<unknown>"),
 					S_OR(user->chan->cid.cid_name, "<no name>"),
@@ -817,7 +825,8 @@
 					user->userflags & CONFFLAG_ADMIN ? "(Admin)" : "",
 					user->userflags & CONFFLAG_MONITOR ? "(Listen only)" : "",
 					user->adminflags & ADMINFLAG_MUTED ? "(Admin Muted)" : user->adminflags & ADMINFLAG_SELFMUTED ? "(Muted)" : "",
-					istalking(user->talking), hr, min, sec);
+					istalking(user->talking), 
+					user->userflags & CONFFLAG_HOLD ? " (On Hold) " : "", hr, min, sec);
 			else 
 				ast_cli(fd, "%d!%s!%s!%s!%s!%s!%s!%d!%02d:%02d:%02d\n",
 					user->user_no,
@@ -979,6 +988,23 @@
 
 	return 0;
 }
+
+static void conf_queue_dtmf(struct ast_conference *conf, int digit)
+{
+	struct ast_conf_user *user;
+	AST_LIST_TRAVERSE(&conf->userlist, user, list) {
+		user->dtmf = digit;
+	}
+}
+
+static void conf_queue_control(struct ast_conference *conf, int control)
+{
+	struct ast_conf_user *user;
+	AST_LIST_TRAVERSE(&conf->userlist, user, list) {
+		user->control = control;
+	}
+}
+
 
 static int conf_run(struct ast_channel *chan, struct ast_conference *conf, int confflags)
 {
@@ -1087,6 +1113,8 @@
 	/* This device changed state now - if this is the first user */
 	if (conf->users == 1)
 		ast_device_state_changed("meetme:%s", conf->confno);
+	if (confflags & (CONFFLAG_SLA_STATION|CONFFLAG_SLA_TRUNK))
+		ast_device_state_changed("SLA:%s", conf->confno + 4);
 
 	ast_mutex_unlock(&conf->playlock);
 
@@ -1549,6 +1577,17 @@
 						if (user->talking || !(confflags & CONFFLAG_OPTIMIZETALKER))
 							careful_write(fd, f->data, f->datalen, 0);
 					}
+				} else if ((f->frametype == AST_FRAME_DTMF) && 
+							(confflags & (CONFFLAG_SLA_STATION|CONFFLAG_SLA_TRUNK))) {
+					conf_queue_dtmf(conf, f->subclass);
+				} else if ((f->frametype == AST_FRAME_CONTROL) && 
+							(confflags & (CONFFLAG_SLA_STATION|CONFFLAG_SLA_TRUNK))) {
+					conf_queue_control(conf, f->subclass);
+					if (f->subclass == AST_CONTROL_HOLD)
+						confflags |= CONFFLAG_HOLD;
+					else if (f->subclass == AST_CONTROL_UNHOLD)
+						confflags &= ~CONFFLAG_HOLD;
+					user->userflags = confflags;
 				} else if ((f->frametype == AST_FRAME_DTMF) && (confflags & CONFFLAG_EXIT_CONTEXT)) {
 					char tmp[2];
 
@@ -1727,6 +1766,33 @@
 				}
 				ast_frfree(f);
 			} else if (outfd > -1) {
+				if (user->control) {
+					switch(user->control) {
+					case AST_CONTROL_RINGING:
+					case AST_CONTROL_PROGRESS:
+					case AST_CONTROL_PROCEEDING:
+						ast_indicate(chan, user->control);
+						break;
+					case AST_CONTROL_ANSWER:
+						if (chan->_state != AST_STATE_UP)
+							ast_answer(chan);
+						break;
+					}
+					user->control = 0;
+					if (confflags & (CONFFLAG_SLA_STATION|CONFFLAG_SLA_TRUNK))
+						ast_device_state_changed("SLA:%s", conf->confno + 4);
+					continue;
+				}
+				if (user->dtmf) {
+					memset(&fr, 0, sizeof(fr));
+					fr.frametype = AST_FRAME_DTMF;
+					fr.subclass = user->dtmf;
+					if (ast_write(chan, &fr) < 0) {
+						ast_log(LOG_WARNING, "Unable to write frame to channel: %s\n", strerror(errno));
+					}
+					user->dtmf = 0;
+					continue;
+				}
 				res = read(outfd, buf, CONF_SIZE);
 				if (res > 0) {
 					memset(&fr, 0, sizeof(fr));
@@ -1867,6 +1933,8 @@
 		/* This device changed state now */
 		if (!conf->users)	/* If there are no more members */
 			ast_device_state_changed("meetme:%s", conf->confno);
+		if (confflags & (CONFFLAG_SLA_STATION|CONFFLAG_SLA_TRUNK))
+			ast_device_state_changed("SLA:%s", conf->confno + 4);
 	}
 	free(user);
 	AST_LIST_UNLOCK(&confs);
@@ -2402,6 +2470,31 @@
 }
 
 
+static int sla_checkforhold(struct ast_conference *conf, int hangup)
+{
+	struct ast_conf_user *user;
+	struct ast_channel *onhold=NULL;
+	int holdcount = 0;
+	int stationcount = 0;
+	int amonhold = 0;
+	AST_LIST_TRAVERSE(&conf->userlist, user, list) {
+		if (user->userflags & CONFFLAG_SLA_STATION) {
+			stationcount++;
+			if ((user->userflags & CONFFLAG_HOLD)) {
+				holdcount++;
+				onhold = user->chan;
+			}
+		}
+	}
+	if ((holdcount == 1) && (stationcount == 1)) {
+		amonhold = 1;
+		if (hangup)
+			ast_softhangup(onhold, AST_SOFTHANGUP_EXPLICIT);
+	} else if (holdcount && (stationcount == holdcount))
+		amonhold = 1;
+	return amonhold;
+}
+
 
 /*! \brief The slas()/slat() application */
 static int sla_exec(struct ast_channel *chan, void *data, int trunk)
@@ -2435,29 +2528,31 @@
 	
 	LOCAL_USER_ADD(u);
 
-	if (chan->_state != AST_STATE_UP)
-		ast_answer(chan);
 
 	if (args.options)
 		ast_app_parse_options(sla_opts, &confflags, NULL, args.options);
 		
 	ast_set_flag(&confflags, CONFFLAG_QUIET|CONFFLAG_DYNAMIC);
 	if (trunk)
-		ast_set_flag(&confflags, CONFFLAG_WAITMARKED|CONFFLAG_MARKEDEXIT);
+		ast_set_flag(&confflags, CONFFLAG_WAITMARKED|CONFFLAG_MARKEDEXIT|CONFFLAG_SLA_TRUNK);
 	else
-		ast_set_flag(&confflags, CONFFLAG_MARKEDUSER);
+		ast_set_flag(&confflags, CONFFLAG_MARKEDUSER|CONFFLAG_SLA_STATION);
 
 	sla = ASTOBJ_CONTAINER_FIND(&slas, args.confno);
 	if (sla) {
 		snprintf(confno, sizeof(confno), "sla-%s", args.confno);
 		cnf = find_conf(chan, confno, 1, dynamic, "", 1, &confflags);
 		if (cnf) {
+			sla_checkforhold(cnf, 1);
 			if (!cnf->users) {
-				if (trunk)
+				if (trunk) {
+					ast_indicate(chan, AST_CONTROL_RINGING);
 					invite_stations(chan, sla);
-				else
+				} else
 					invite_trunk(chan, sla);
-			}
+			} else if (chan->_state != AST_STATE_UP)
+				ast_answer(chan);
+
 			/* Run the conference */
 			res = conf_run(chan, cnf, confflags.flags);
 		} else
@@ -2808,6 +2903,44 @@
 	return AST_DEVICE_INUSE;
 }
 
+/*! \brief Callback for devicestate providers */
+static int slastate(const char *data)
+{
+	struct ast_conference *conf;
+	struct ast_sla *sla, *sla2;
+
+	ast_log(LOG_DEBUG, "asked for sla state for '%s'\n", data);
+
+	/* Find conference */
+	AST_LIST_LOCK(&confs);
+	AST_LIST_TRAVERSE(&confs, conf, list) {
+		if (!strncmp(conf->confno, "sla-", 4) && !strcmp(data, conf->confno + 4))
+			break;
+	}
+	AST_LIST_UNLOCK(&confs);
+
+	/* Find conference */
+	sla = sla2 = ASTOBJ_CONTAINER_FIND(&slas, data);
+	ASTOBJ_UNREF(sla2, sla_destroy);
+
+	ast_log(LOG_DEBUG, "for '%s' conf = %p, sla = %p\n", data, conf, sla);
+
+	if (!conf && !sla)
+		return AST_DEVICE_INVALID;
+
+	/* SKREP to fill */
+	if (!conf || !conf->users)
+		return AST_DEVICE_NOT_INUSE;
+	
+	if (conf && sla_checkforhold(conf, 0))
+		return AST_DEVICE_ONHOLD;
+
+	if ((conf->users == 1) && (AST_LIST_FIRST(&conf->userlist)->userflags & CONFFLAG_SLA_TRUNK))
+		return AST_DEVICE_RINGING;
+
+	return AST_DEVICE_INUSE;
+}
+
 static void load_config_meetme(void)
 {
 	struct ast_config *cfg;
@@ -2874,6 +3007,7 @@
 	if (sla) {
 		ASTOBJ_UNMARK(sla);
 		ASTOBJ_WRLOCK(sla);
+		ASTOBJ_CONTAINER_DESTROYALL(&sla->stations, station_destroy);
 		while (v) {
 			if (!strcasecmp(v->name, "trunk")) {
 				char *c;
@@ -2888,6 +3022,7 @@
 			v = v->next;
 		}
 		ASTOBJ_UNLOCK(sla);
+		ast_device_state_changed("SLA:%s", cat);
 	}
 }
 
@@ -2930,6 +3065,7 @@
 	res |= ast_unregister_application(app);
 
 	ast_devstate_prov_del("Meetme");
+	ast_devstate_prov_del("SLA");
 	STANDARD_HANGUP_LOCALUSERS;
 
 	return res;
@@ -2939,7 +3075,6 @@
 {
 	int res;
 
-	load_config();
 	ASTOBJ_CONTAINER_INIT(&slas);
 	res = ast_cli_register(&cli_show_confs);
 	res |= ast_cli_register(&cli_sla_show);
@@ -2953,6 +3088,8 @@
 	res |= ast_register_application(appslat, slat_exec, synopslat, descripslat);
 
 	res |= ast_devstate_prov_add("Meetme", meetmestate);
+	res |= ast_devstate_prov_add("SLA", slastate);
+	load_config();
 	return res;
 }
 

Modified: trunk/channels/chan_zap.c
URL: http://svn.digium.com/view/asterisk/trunk/channels/chan_zap.c?rev=37318&r1=37317&r2=37318&view=diff
==============================================================================
--- trunk/channels/chan_zap.c (original)
+++ trunk/channels/chan_zap.c Fri Jul  7 21:24:07 2006
@@ -515,6 +515,8 @@
 	unsigned int needcallerid:1;
 	unsigned int needanswer:1;
 	unsigned int needflash:1;
+	unsigned int needhold:1;
+	unsigned int needunhold:1;
 	unsigned int linear:1;
 	unsigned int inthreeway:1;
 	ZT_CONFINFO curconf;
@@ -3899,6 +3901,7 @@
 					/* Okay -- probably call waiting*/
 					if (ast_bridged_channel(p->owner))
 							ast_moh_stop(ast_bridged_channel(p->owner));
+					p->subs[index].needunhold = 1;
 					break;
 				case AST_STATE_RESERVED:
 					/* Start up dialtone */
@@ -4056,8 +4059,10 @@
 					/* Start music on hold if appropriate */
 					if (!p->subs[SUB_CALLWAIT].inthreeway && ast_bridged_channel(p->subs[SUB_CALLWAIT].owner))
 						ast_moh_start(ast_bridged_channel(p->subs[SUB_CALLWAIT].owner), NULL);
+					p->subs[SUB_CALLWAIT].needhold = 1;
 					if (ast_bridged_channel(p->subs[SUB_REAL].owner))
 						ast_moh_stop(ast_bridged_channel(p->subs[SUB_REAL].owner));
+					p->subs[SUB_REAL].needunhold = 1;
 				} else if (!p->subs[SUB_THREEWAY].owner) {
 					char cid_num[256];
 					char cid_name[256];
@@ -4116,6 +4121,7 @@
 							/* Start music on hold if appropriate */
 							if (ast_bridged_channel(p->subs[SUB_THREEWAY].owner))
 								ast_moh_start(ast_bridged_channel(p->subs[SUB_THREEWAY].owner), NULL);
+							p->subs[SUB_THREEWAY].needhold = 1;
 						}		
 					}
 				} else {
@@ -4153,6 +4159,7 @@
 							}
 							if (p->subs[otherindex].owner && ast_bridged_channel(p->subs[otherindex].owner))
 								ast_moh_stop(ast_bridged_channel(p->subs[otherindex].owner));
+							p->subs[otherindex].needunhold = 1;
 							p->owner = p->subs[SUB_REAL].owner;
 							if (ast->_state == AST_STATE_RINGING) {
 								ast_log(LOG_DEBUG, "Enabling ringtone on real and threeway\n");
@@ -4167,6 +4174,7 @@
 							p->owner = p->subs[SUB_REAL].owner;
 							if (p->subs[SUB_REAL].owner && ast_bridged_channel(p->subs[SUB_REAL].owner))
 								ast_moh_stop(ast_bridged_channel(p->subs[SUB_REAL].owner));
+							p->subs[SUB_REAL].needunhold = 1;
 							zt_enable_ec(p);
 						}
 							
@@ -4354,6 +4362,7 @@
 			p->owner = p->subs[SUB_REAL].owner;
 			if (p->owner && ast_bridged_channel(p->owner))
 				ast_moh_stop(ast_bridged_channel(p->owner));
+			p->subs[SUB_REAL].needunhold = 1;
 		}
 		switch (res) {
 		case ZT_EVENT_ONHOOK:
@@ -4397,6 +4406,7 @@
 				p->cidcwexpire = 0;
 				if (ast_bridged_channel(p->owner))
 					ast_moh_stop(ast_bridged_channel(p->owner));
+				p->subs[SUB_REAL].needunhold = 1;
 			} else
 				ast_log(LOG_WARNING, "Absorbed on hook, but nobody is left!?!?\n");
 			update_conf(p);
@@ -4541,6 +4551,26 @@
 		p->subs[index].f.frametype = AST_FRAME_CONTROL;
 		p->subs[index].f.subclass = AST_CONTROL_FLASH;
 		ast_mutex_unlock(&p->lock);
+		return &p->subs[index].f;
+	}	
+	
+	if (p->subs[index].needhold) {
+		/* Send answer frame if requested */
+		p->subs[index].needhold = 0;
+		p->subs[index].f.frametype = AST_FRAME_CONTROL;
+		p->subs[index].f.subclass = AST_CONTROL_HOLD;
+		ast_mutex_unlock(&p->lock);
+		ast_log(LOG_DEBUG, "Sending hold on '%s'\n", ast->name);
+		return &p->subs[index].f;
+	}	
+	
+	if (p->subs[index].needunhold) {
+		/* Send answer frame if requested */
+		p->subs[index].needunhold = 0;
+		p->subs[index].f.frametype = AST_FRAME_CONTROL;
+		p->subs[index].f.subclass = AST_CONTROL_UNHOLD;
+		ast_mutex_unlock(&p->lock);
+		ast_log(LOG_DEBUG, "Sending unhold on '%s'\n", ast->name);
 		return &p->subs[index].f;
 	}	
 	

Modified: trunk/channels/iax2-parser.c
URL: http://svn.digium.com/view/asterisk/trunk/channels/iax2-parser.c?rev=37318&r1=37317&r2=37318&view=diff
==============================================================================
--- trunk/channels/iax2-parser.c (original)
+++ trunk/channels/iax2-parser.c Fri Jul  7 21:24:07 2006
@@ -444,7 +444,18 @@
 		"ANSWER ",
 		"BUSY   ",
 		"TKOFFHK",
-		"OFFHOOK" };
+		"OFFHOOK",
+		"CONGSTN",
+		"FLASH  ",
+		"WINK   ",
+		"OPTION ",
+		"RDKEY  ",
+		"RDUNKEY",
+		"PROGRES",
+		"PROCDNG",
+		"HOLD   ",
+		"UNHOLD ",
+		"VIDUPDT", };
 	struct ast_iax2_full_hdr *fh;
 	char retries[20];
 	char class2[20];

Modified: trunk/devicestate.c
URL: http://svn.digium.com/view/asterisk/trunk/devicestate.c?rev=37318&r1=37317&r2=37318&view=diff
==============================================================================
--- trunk/devicestate.c (original)
+++ trunk/devicestate.c Fri Jul  7 21:24:07 2006
@@ -52,6 +52,8 @@
 	/* 4 AST_DEVICE_INVALID */	"Invalid",	/*!< Invalid - not known to Asterisk */
 	/* 5 AST_DEVICE_UNAVAILABLE */	"Unavailable",	/*!< Unavailable (not registred) */
 	/* 6 AST_DEVICE_RINGING */	"Ringing"	/*!< Ring, ring, ring */
+	/* 7 AST_DEVICE_RINGINUSE */	"Ring+Inuse"	/*!< Ring and in use */
+	/* 8 AST_DEVICE_ONHOLD */	"On Hold"	/*!< On Hold */
 };
 
 /*! \brief  A device state provider (not a channel) */

Modified: trunk/include/asterisk/devicestate.h
URL: http://svn.digium.com/view/asterisk/trunk/include/asterisk/devicestate.h?rev=37318&r1=37317&r2=37318&view=diff
==============================================================================
--- trunk/include/asterisk/devicestate.h (original)
+++ trunk/include/asterisk/devicestate.h Fri Jul  7 21:24:07 2006
@@ -43,6 +43,8 @@
 #define AST_DEVICE_RINGING	6
 /*! Device is ringing *and* in use */
 #define AST_DEVICE_RINGINUSE	7
+/*! Device is on hold */
+#define AST_DEVICE_ONHOLD	8
 
 /*! \brief Devicestate watcher call back */
 typedef int (*ast_devstate_cb_type)(const char *dev, int state, void *data);

Modified: trunk/include/asterisk/pbx.h
URL: http://svn.digium.com/view/asterisk/trunk/include/asterisk/pbx.h?rev=37318&r1=37317&r2=37318&view=diff
==============================================================================
--- trunk/include/asterisk/pbx.h (original)
+++ trunk/include/asterisk/pbx.h Fri Jul  7 21:24:07 2006
@@ -52,6 +52,7 @@
 	AST_EXTENSION_BUSY = 1 << 1,	/*!< All devices BUSY */
 	AST_EXTENSION_UNAVAILABLE = 1 << 2, /*!< All devices UNAVAILABLE/UNREGISTERED */
 	AST_EXTENSION_RINGING = 1 << 3,	/*!< All devices RINGING */
+	AST_EXTENSION_ONHOLD = 1 << 4,	/*!< All devices ONHOLD */
 };
 
 

Modified: trunk/pbx.c
URL: http://svn.digium.com/view/asterisk/trunk/pbx.c?rev=37318&r1=37317&r2=37318&view=diff
==============================================================================
--- trunk/pbx.c (original)
+++ trunk/pbx.c Fri Jul  7 21:24:07 2006
@@ -206,7 +206,9 @@
 	{ AST_EXTENSION_BUSY,                          "Busy" },
 	{ AST_EXTENSION_UNAVAILABLE,                   "Unavailable" },
 	{ AST_EXTENSION_RINGING,                       "Ringing" },
-	{ AST_EXTENSION_INUSE | AST_EXTENSION_RINGING, "InUse&Ringing" }
+	{ AST_EXTENSION_INUSE | AST_EXTENSION_RINGING, "InUse&Ringing" },
+	{ AST_EXTENSION_ONHOLD,                        "Hold" },
+	{ AST_EXTENSION_INUSE | AST_EXTENSION_ONHOLD,  "InUse&Hold" }
 };
 
 int ast_pbx_outgoing_cdr_failed(void);
@@ -1754,7 +1756,7 @@
 {
 	char hint[AST_MAX_EXTENSION];
 	char *cur, *rest;
-	int allunavailable = 1, allbusy = 1, allfree = 1;
+	int allunavailable = 1, allbusy = 1, allfree = 1, allonhold = 1;
 	int busy = 0, inuse = 0, ring = 0;
 
 	if (!e)
@@ -1769,37 +1771,48 @@
 		case AST_DEVICE_NOT_INUSE:
 			allunavailable = 0;
 			allbusy = 0;
+			allonhold = 0;
 			break;
 		case AST_DEVICE_INUSE:
 			inuse = 1;
 			allunavailable = 0;
 			allfree = 0;
+			allonhold = 0;
 			break;
 		case AST_DEVICE_RINGING:
 			ring = 1;
 			allunavailable = 0;
 			allfree = 0;
+			allonhold = 0;
 			break;
 		case AST_DEVICE_RINGINUSE:
 			inuse = 1;
 			ring = 1;
 			allunavailable = 0;
 			allfree = 0;
+			allonhold = 0;
+			break;
+		case AST_DEVICE_ONHOLD:
+			allunavailable = 0;
+			allfree = 0;
 			break;
 		case AST_DEVICE_BUSY:
 			allunavailable = 0;
 			allfree = 0;
+			allonhold = 0;
 			busy = 1;
 			break;
 		case AST_DEVICE_UNAVAILABLE:
 		case AST_DEVICE_INVALID:
 			allbusy = 0;
 			allfree = 0;
+			allonhold = 0;
 			break;
 		default:
 			allunavailable = 0;
 			allbusy = 0;
 			allfree = 0;
+			allonhold = 0;
 		}
 	}
 
@@ -1811,6 +1824,8 @@
 		return AST_EXTENSION_INUSE;
 	if (allfree)
 		return AST_EXTENSION_NOT_INUSE;
+	if (allonhold)
+		return AST_EXTENSION_ONHOLD;
 	if (allbusy)
 		return AST_EXTENSION_BUSY;
 	if (allunavailable)



More information about the asterisk-commits mailing list