mirror of
				https://github.com/asterisk/asterisk.git
				synced 2025-10-31 10:47:18 +00:00 
			
		
		
		
	Merged revisions 54066 via svnmerge from
https://origsvn.digium.com/svn/asterisk/branches/1.4 ........ r54066 | russell | 2007-02-12 11:58:43 -0600 (Mon, 12 Feb 2007) | 4 lines - Add the ability to register a callback to monitor state changes in an asynchronous dial operation. - Rename the various references to "status" to "state" in the dial API ........ git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@54067 65c4cc65-6c06-0410-ace0-fbb531ad65f3
This commit is contained in:
		| @@ -3153,7 +3153,7 @@ static void *sla_thread(void *data) | |||||||
| 			ast_mutex_t cond_lock; | 			ast_mutex_t cond_lock; | ||||||
| 			ast_cond_t cond; | 			ast_cond_t cond; | ||||||
|  |  | ||||||
| 			switch ((dial_res = ast_dial_status(station_ref->station->dial))) { | 			switch ((dial_res = ast_dial_state(station_ref->station->dial))) { | ||||||
| 			case AST_DIAL_RESULT_HANGUP: | 			case AST_DIAL_RESULT_HANGUP: | ||||||
| 			case AST_DIAL_RESULT_INVALID: | 			case AST_DIAL_RESULT_INVALID: | ||||||
| 			case AST_DIAL_RESULT_FAILED: | 			case AST_DIAL_RESULT_FAILED: | ||||||
| @@ -3296,7 +3296,7 @@ static void *dial_trunk(void *data) | |||||||
|  |  | ||||||
| 	for (;;) { | 	for (;;) { | ||||||
| 		unsigned int done = 0; | 		unsigned int done = 0; | ||||||
| 		switch ((dial_res = ast_dial_status(dial))) { | 		switch ((dial_res = ast_dial_state(dial))) { | ||||||
| 		case AST_DIAL_RESULT_ANSWERED: | 		case AST_DIAL_RESULT_ANSWERED: | ||||||
| 			trunk->chan = ast_dial_answered(dial); | 			trunk->chan = ast_dial_answered(dial); | ||||||
| 		case AST_DIAL_RESULT_HANGUP: | 		case AST_DIAL_RESULT_HANGUP: | ||||||
|   | |||||||
| @@ -178,7 +178,7 @@ static int page_exec(struct ast_channel *chan, void *data) | |||||||
| 		struct ast_dial *dial = dials[i]; | 		struct ast_dial *dial = dials[i]; | ||||||
|  |  | ||||||
| 		/* If the dial is already answered, then they will/should get kicked out by Meetme */ | 		/* If the dial is already answered, then they will/should get kicked out by Meetme */ | ||||||
| 		if (ast_dial_status(dial) != AST_DIAL_RESULT_ANSWERED) | 		if (ast_dial_state(dial) != AST_DIAL_RESULT_ANSWERED) | ||||||
| 			ast_dial_join(dial); | 			ast_dial_join(dial); | ||||||
|  |  | ||||||
| 		/* Hangup all channels */ | 		/* Hangup all channels */ | ||||||
|   | |||||||
| @@ -33,6 +33,8 @@ struct ast_dial; | |||||||
| /*! \brief Dialing channel structure. Contains per-channel dialing options, asterisk channel, and more! */ | /*! \brief Dialing channel structure. Contains per-channel dialing options, asterisk channel, and more! */ | ||||||
| struct ast_dial_channel; | struct ast_dial_channel; | ||||||
|  |  | ||||||
|  | typedef void (*ast_dial_state_callback)(struct ast_dial *); | ||||||
|  |  | ||||||
| /*! \brief List of options that are applicable either globally or per dialed channel */ | /*! \brief List of options that are applicable either globally or per dialed channel */ | ||||||
| enum ast_dial_option { | enum ast_dial_option { | ||||||
| 	AST_DIAL_OPTION_RINGING,     /*!< Always indicate ringing to caller */ | 	AST_DIAL_OPTION_RINGING,     /*!< Always indicate ringing to caller */ | ||||||
| @@ -78,11 +80,11 @@ enum ast_dial_result ast_dial_run(struct ast_dial *dial, struct ast_channel *cha | |||||||
|  */ |  */ | ||||||
| struct ast_channel *ast_dial_answered(struct ast_dial *dial); | struct ast_channel *ast_dial_answered(struct ast_dial *dial); | ||||||
|  |  | ||||||
| /*! \brief Return status of dial | /*! \brief Return state of dial | ||||||
|  * \note Returns the status of the dial attempt |  * \note Returns the state of the dial attempt | ||||||
|  * \param dial Dialing structure |  * \param dial Dialing structure | ||||||
|  */ |  */ | ||||||
| enum ast_dial_result ast_dial_status(struct ast_dial *dial); | enum ast_dial_result ast_dial_state(struct ast_dial *dial); | ||||||
|  |  | ||||||
| /*! \brief Cancel async thread | /*! \brief Cancel async thread | ||||||
|  * \note Cancel a running async thread |  * \note Cancel a running async thread | ||||||
| @@ -135,6 +137,13 @@ int ast_dial_option_global_disable(struct ast_dial *dial, enum ast_dial_option o | |||||||
|  */ |  */ | ||||||
| int ast_dial_option_disable(struct ast_dial *dial, int num, enum ast_dial_option option); | int ast_dial_option_disable(struct ast_dial *dial, int num, enum ast_dial_option option); | ||||||
|  |  | ||||||
|  | /*! \brief Set a callback for state changes | ||||||
|  |  * \param dial The dial structure to watch for state changes | ||||||
|  |  * \param callback the callback | ||||||
|  |  * \return nothing | ||||||
|  |  */ | ||||||
|  | void ast_set_state_callback(struct ast_dial *dial, ast_dial_state_callback callback); | ||||||
|  |  | ||||||
| #if defined(__cplusplus) || defined(c_plusplus) | #if defined(__cplusplus) || defined(c_plusplus) | ||||||
| } | } | ||||||
| #endif | #endif | ||||||
|   | |||||||
							
								
								
									
										65
									
								
								main/dial.c
									
									
									
									
									
								
							
							
						
						
									
										65
									
								
								main/dial.c
									
									
									
									
									
								
							| @@ -47,8 +47,9 @@ ASTERISK_FILE_VERSION(__FILE__, "$Revision$") | |||||||
| /*! \brief Main dialing structure. Contains global options, channels being dialed, and more! */ | /*! \brief Main dialing structure. Contains global options, channels being dialed, and more! */ | ||||||
| struct ast_dial { | struct ast_dial { | ||||||
| 	int num;                                           /*! Current number to give to next dialed channel */ | 	int num;                                           /*! Current number to give to next dialed channel */ | ||||||
| 	enum ast_dial_result status;                       /*! Status of dial */ | 	enum ast_dial_result state;                       /*! Status of dial */ | ||||||
| 	void *options[AST_DIAL_OPTION_MAX];                /*! Global options */ | 	void *options[AST_DIAL_OPTION_MAX];                /*! Global options */ | ||||||
|  | 	ast_dial_state_callback state_callback;          /*! Status callback */ | ||||||
| 	AST_LIST_HEAD_NOLOCK(, ast_dial_channel) channels; /*! Channels being dialed */ | 	AST_LIST_HEAD_NOLOCK(, ast_dial_channel) channels; /*! Channels being dialed */ | ||||||
| 	pthread_t thread;                                  /*! Thread (if running in async) */ | 	pthread_t thread;                                  /*! Thread (if running in async) */ | ||||||
| }; | }; | ||||||
| @@ -288,6 +289,14 @@ static struct ast_dial_channel *find_relative_dial_channel(struct ast_dial *dial | |||||||
| 	return channel; | 	return channel; | ||||||
| } | } | ||||||
|  |  | ||||||
|  | static void set_state(struct ast_dial *dial, enum ast_dial_result state) | ||||||
|  | { | ||||||
|  | 	dial->state = state; | ||||||
|  |  | ||||||
|  | 	if (dial->state_callback) | ||||||
|  | 		dial->state_callback(dial); | ||||||
|  | } | ||||||
|  |  | ||||||
| /*! \brief Helper function that handles control frames WITH owner */ | /*! \brief Helper function that handles control frames WITH owner */ | ||||||
| static void handle_frame(struct ast_dial *dial, struct ast_dial_channel *channel, struct ast_frame *fr, struct ast_channel *chan) | static void handle_frame(struct ast_dial *dial, struct ast_dial_channel *channel, struct ast_frame *fr, struct ast_channel *chan) | ||||||
| { | { | ||||||
| @@ -298,7 +307,7 @@ static void handle_frame(struct ast_dial *dial, struct ast_dial_channel *channel | |||||||
| 				ast_verbose( VERBOSE_PREFIX_3 "%s answered %s\n", channel->owner->name, chan->name); | 				ast_verbose( VERBOSE_PREFIX_3 "%s answered %s\n", channel->owner->name, chan->name); | ||||||
| 			AST_LIST_REMOVE(&dial->channels, channel, list); | 			AST_LIST_REMOVE(&dial->channels, channel, list); | ||||||
| 			AST_LIST_INSERT_HEAD(&dial->channels, channel, list); | 			AST_LIST_INSERT_HEAD(&dial->channels, channel, list); | ||||||
| 			dial->status = AST_DIAL_RESULT_ANSWERED; | 			set_state(dial, AST_DIAL_RESULT_ANSWERED); | ||||||
| 			break; | 			break; | ||||||
| 		case AST_CONTROL_BUSY: | 		case AST_CONTROL_BUSY: | ||||||
| 			if (option_verbose > 2) | 			if (option_verbose > 2) | ||||||
| @@ -360,7 +369,7 @@ static void handle_frame(struct ast_dial *dial, struct ast_dial_channel *channel | |||||||
| /*! \brief Helper function that handles control frames WITHOUT owner */ | /*! \brief Helper function that handles control frames WITHOUT owner */ | ||||||
| static void handle_frame_ownerless(struct ast_dial *dial, struct ast_dial_channel *channel, struct ast_frame *fr) | static void handle_frame_ownerless(struct ast_dial *dial, struct ast_dial_channel *channel, struct ast_frame *fr) | ||||||
| { | { | ||||||
| 	/* If we have no owner we can only update the status of the dial structure, so only look at control frames */ | 	/* If we have no owner we can only update the state of the dial structure, so only look at control frames */ | ||||||
| 	if (fr->frametype != AST_FRAME_CONTROL) | 	if (fr->frametype != AST_FRAME_CONTROL) | ||||||
| 		return; | 		return; | ||||||
|  |  | ||||||
| @@ -370,7 +379,7 @@ static void handle_frame_ownerless(struct ast_dial *dial, struct ast_dial_channe | |||||||
| 			ast_verbose( VERBOSE_PREFIX_3 "%s answered\n", channel->owner->name); | 			ast_verbose( VERBOSE_PREFIX_3 "%s answered\n", channel->owner->name); | ||||||
| 		AST_LIST_REMOVE(&dial->channels, channel, list); | 		AST_LIST_REMOVE(&dial->channels, channel, list); | ||||||
| 		AST_LIST_INSERT_HEAD(&dial->channels, channel, list); | 		AST_LIST_INSERT_HEAD(&dial->channels, channel, list); | ||||||
| 		dial->status = AST_DIAL_RESULT_ANSWERED; | 		set_state(dial, AST_DIAL_RESULT_ANSWERED); | ||||||
| 		break; | 		break; | ||||||
| 	case AST_CONTROL_BUSY: | 	case AST_CONTROL_BUSY: | ||||||
| 		if (option_verbose > 2) | 		if (option_verbose > 2) | ||||||
| @@ -387,17 +396,17 @@ static void handle_frame_ownerless(struct ast_dial *dial, struct ast_dial_channe | |||||||
| 	case AST_CONTROL_RINGING: | 	case AST_CONTROL_RINGING: | ||||||
| 		if (option_verbose > 2) | 		if (option_verbose > 2) | ||||||
| 			ast_verbose(VERBOSE_PREFIX_3 "%s is ringing\n", channel->owner->name); | 			ast_verbose(VERBOSE_PREFIX_3 "%s is ringing\n", channel->owner->name); | ||||||
| 		dial->status = AST_DIAL_RESULT_RINGING; | 		set_state(dial, AST_DIAL_RESULT_RINGING); | ||||||
| 		break; | 		break; | ||||||
| 	case AST_CONTROL_PROGRESS: | 	case AST_CONTROL_PROGRESS: | ||||||
| 		if (option_verbose > 2) | 		if (option_verbose > 2) | ||||||
| 			ast_verbose (VERBOSE_PREFIX_3 "%s is making progress\n", channel->owner->name); | 			ast_verbose (VERBOSE_PREFIX_3 "%s is making progress\n", channel->owner->name); | ||||||
| 		dial->status = AST_DIAL_RESULT_PROGRESS; | 		set_state(dial, AST_DIAL_RESULT_PROGRESS); | ||||||
| 		break; | 		break; | ||||||
| 	case AST_CONTROL_PROCEEDING: | 	case AST_CONTROL_PROCEEDING: | ||||||
| 		if (option_verbose > 2) | 		if (option_verbose > 2) | ||||||
| 			ast_verbose (VERBOSE_PREFIX_3 "%s is proceeding\n", channel->owner->name); | 			ast_verbose (VERBOSE_PREFIX_3 "%s is proceeding\n", channel->owner->name); | ||||||
| 		dial->status = AST_DIAL_RESULT_PROCEEDING; | 		set_state(dial, AST_DIAL_RESULT_PROCEEDING); | ||||||
| 		break; | 		break; | ||||||
| 	default: | 	default: | ||||||
| 		break; | 		break; | ||||||
| @@ -414,18 +423,17 @@ static enum ast_dial_result monitor_dial(struct ast_dial *dial, struct ast_chann | |||||||
| 	struct ast_dial_channel *channel = NULL; | 	struct ast_dial_channel *channel = NULL; | ||||||
| 	struct answer_exec_struct *answer_exec = NULL; | 	struct answer_exec_struct *answer_exec = NULL; | ||||||
|  |  | ||||||
| 	/* Switch dialing status to trying */ | 	set_state(dial, AST_DIAL_RESULT_TRYING); | ||||||
| 	dial->status = AST_DIAL_RESULT_TRYING; |  | ||||||
|  |  | ||||||
| 	/* If the "always indicate ringing" option is set, change status to ringing and indicate to the owner if present */ | 	/* If the "always indicate ringing" option is set, change state to ringing and indicate to the owner if present */ | ||||||
| 	if (dial->options[AST_DIAL_OPTION_RINGING]) { | 	if (dial->options[AST_DIAL_OPTION_RINGING]) { | ||||||
| 		dial->status = AST_DIAL_RESULT_RINGING; | 		set_state(dial, AST_DIAL_RESULT_RINGING); | ||||||
| 		if (chan) | 		if (chan) | ||||||
| 			ast_indicate(chan, AST_CONTROL_RINGING); | 			ast_indicate(chan, AST_CONTROL_RINGING); | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	/* Go into an infinite loop while we are trying */ | 	/* Go into an infinite loop while we are trying */ | ||||||
| 	while ((dial->status != AST_DIAL_RESULT_UNANSWERED) && (dial->status != AST_DIAL_RESULT_ANSWERED) && (dial->status != AST_DIAL_RESULT_HANGUP) && (dial->status != AST_DIAL_RESULT_TIMEOUT)) { | 	while ((dial->state != AST_DIAL_RESULT_UNANSWERED) && (dial->state != AST_DIAL_RESULT_ANSWERED) && (dial->state != AST_DIAL_RESULT_HANGUP) && (dial->state != AST_DIAL_RESULT_TIMEOUT)) { | ||||||
| 		int pos = 0; | 		int pos = 0; | ||||||
| 		struct ast_frame *fr = NULL; | 		struct ast_frame *fr = NULL; | ||||||
|  |  | ||||||
| @@ -442,9 +450,9 @@ static enum ast_dial_result monitor_dial(struct ast_dial *dial, struct ast_chann | |||||||
| 			} | 			} | ||||||
| 		} | 		} | ||||||
|  |  | ||||||
| 		/* If we have no outbound channels in progress, switch status to unanswered and stop */ | 		/* If we have no outbound channels in progress, switch state to unanswered and stop */ | ||||||
| 		if (!count) { | 		if (!count) { | ||||||
| 			dial->status = AST_DIAL_RESULT_UNANSWERED; | 			set_state(dial, AST_DIAL_RESULT_UNANSWERED); | ||||||
| 			break; | 			break; | ||||||
| 		} | 		} | ||||||
|  |  | ||||||
| @@ -469,9 +477,9 @@ static enum ast_dial_result monitor_dial(struct ast_dial *dial, struct ast_chann | |||||||
|  |  | ||||||
| 		/* Attempt to read in a frame */ | 		/* Attempt to read in a frame */ | ||||||
| 		if (!(fr = ast_read(who))) { | 		if (!(fr = ast_read(who))) { | ||||||
| 			/* If this is the caller then we switch status to hangup and stop */ | 			/* If this is the caller then we switch state to hangup and stop */ | ||||||
| 			if (chan && IS_CALLER(chan, who)) { | 			if (chan && IS_CALLER(chan, who)) { | ||||||
| 				dial->status = AST_DIAL_RESULT_HANGUP; | 				set_state(dial, AST_DIAL_RESULT_HANGUP); | ||||||
| 				break; | 				break; | ||||||
| 			} | 			} | ||||||
| 			ast_hangup(who); | 			ast_hangup(who); | ||||||
| @@ -490,7 +498,7 @@ static enum ast_dial_result monitor_dial(struct ast_dial *dial, struct ast_chann | |||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	/* Do post-processing from loop */ | 	/* Do post-processing from loop */ | ||||||
| 	if (dial->status == AST_DIAL_RESULT_ANSWERED) { | 	if (dial->state == AST_DIAL_RESULT_ANSWERED) { | ||||||
| 		/* Hangup everything except that which answered */ | 		/* Hangup everything except that which answered */ | ||||||
| 		AST_LIST_TRAVERSE(&dial->channels, channel, list) { | 		AST_LIST_TRAVERSE(&dial->channels, channel, list) { | ||||||
| 			if (!channel->owner || channel->owner == who) | 			if (!channel->owner || channel->owner == who) | ||||||
| @@ -501,7 +509,7 @@ static enum ast_dial_result monitor_dial(struct ast_dial *dial, struct ast_chann | |||||||
| 		/* If ANSWER_EXEC is enabled as an option, execute application on answered channel */ | 		/* If ANSWER_EXEC is enabled as an option, execute application on answered channel */ | ||||||
| 		if ((channel = find_relative_dial_channel(dial, who)) && (answer_exec = FIND_RELATIVE_OPTION(dial, channel, AST_DIAL_OPTION_ANSWER_EXEC))) | 		if ((channel = find_relative_dial_channel(dial, who)) && (answer_exec = FIND_RELATIVE_OPTION(dial, channel, AST_DIAL_OPTION_ANSWER_EXEC))) | ||||||
| 			answer_exec_run(who, answer_exec->app, answer_exec->args); | 			answer_exec_run(who, answer_exec->app, answer_exec->args); | ||||||
| 	} else if (dial->status == AST_DIAL_RESULT_HANGUP) { | 	} else if (dial->state == AST_DIAL_RESULT_HANGUP) { | ||||||
| 		/* Hangup everything */ | 		/* Hangup everything */ | ||||||
| 		AST_LIST_TRAVERSE(&dial->channels, channel, list) { | 		AST_LIST_TRAVERSE(&dial->channels, channel, list) { | ||||||
| 			if (!channel->owner) | 			if (!channel->owner) | ||||||
| @@ -511,7 +519,7 @@ static enum ast_dial_result monitor_dial(struct ast_dial *dial, struct ast_chann | |||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	return dial->status; | 	return dial->state; | ||||||
| } | } | ||||||
|  |  | ||||||
| /*! \brief Dial async thread function */ | /*! \brief Dial async thread function */ | ||||||
| @@ -551,7 +559,7 @@ enum ast_dial_result ast_dial_run(struct ast_dial *dial, struct ast_channel *cha | |||||||
|  |  | ||||||
| 	/* If we are running async spawn a thread and send it away... otherwise block here */ | 	/* If we are running async spawn a thread and send it away... otherwise block here */ | ||||||
| 	if (async) { | 	if (async) { | ||||||
| 		dial->status = AST_DIAL_RESULT_TRYING; | 		set_state(dial, AST_DIAL_RESULT_TRYING); | ||||||
| 		/* Try to create a thread */ | 		/* Try to create a thread */ | ||||||
| 		if (ast_pthread_create(&dial->thread, NULL, async_dial, dial)) { | 		if (ast_pthread_create(&dial->thread, NULL, async_dial, dial)) { | ||||||
| 			/* Failed to create the thread - hangup all dialed channels and return failed */ | 			/* Failed to create the thread - hangup all dialed channels and return failed */ | ||||||
| @@ -574,16 +582,16 @@ struct ast_channel *ast_dial_answered(struct ast_dial *dial) | |||||||
| 	if (!dial) | 	if (!dial) | ||||||
| 		return NULL; | 		return NULL; | ||||||
|  |  | ||||||
| 	return ((dial->status == AST_DIAL_RESULT_ANSWERED) ? AST_LIST_FIRST(&dial->channels)->owner : NULL); | 	return ((dial->state == AST_DIAL_RESULT_ANSWERED) ? AST_LIST_FIRST(&dial->channels)->owner : NULL); | ||||||
| } | } | ||||||
|  |  | ||||||
| /*! \brief Return status of dial | /*! \brief Return state of dial | ||||||
|  * \note Returns the status of the dial attempt |  * \note Returns the state of the dial attempt | ||||||
|  * \param dial Dialing structure |  * \param dial Dialing structure | ||||||
|  */ |  */ | ||||||
| enum ast_dial_result ast_dial_status(struct ast_dial *dial) | enum ast_dial_result ast_dial_state(struct ast_dial *dial) | ||||||
| { | { | ||||||
| 	return dial->status; | 	return dial->state; | ||||||
| } | } | ||||||
|  |  | ||||||
| /*! \brief Cancel async thread | /*! \brief Cancel async thread | ||||||
| @@ -613,7 +621,7 @@ enum ast_dial_result ast_dial_join(struct ast_dial *dial) | |||||||
| 	/* Yay thread is all gone */ | 	/* Yay thread is all gone */ | ||||||
| 	dial->thread = AST_PTHREADT_NULL; | 	dial->thread = AST_PTHREADT_NULL; | ||||||
|  |  | ||||||
| 	return dial->status; | 	return dial->state; | ||||||
| } | } | ||||||
|  |  | ||||||
| /*! \brief Hangup channels | /*! \brief Hangup channels | ||||||
| @@ -809,3 +817,8 @@ int ast_dial_option_disable(struct ast_dial *dial, int num, enum ast_dial_option | |||||||
|  |  | ||||||
| 	return 0; | 	return 0; | ||||||
| } | } | ||||||
|  |  | ||||||
|  | void ast_set_state_callback(struct ast_dial *dial, ast_dial_state_callback callback) | ||||||
|  | { | ||||||
|  | 	dial->state_callback = callback; | ||||||
|  | } | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user