mirror of
				https://github.com/asterisk/asterisk.git
				synced 2025-10-31 02:37:10 +00:00 
			
		
		
		
	Add new AMI and ARI events for connected line changes on a channel.
The AMI event is called NewConnectedLine and the ARI event is called ChannelConnectedLine. ASTERISK-24554 #close Reported by Matt Jordan Review: https://reviewboard.asterisk.org/r/4231 git-svn-id: https://origsvn.digium.com/svn/asterisk/branches/13@429064 65c4cc65-6c06-0410-ace0-fbb531ad65f3
This commit is contained in:
		
							
								
								
									
										10
									
								
								CHANGES
									
									
									
									
									
								
							
							
						
						
									
										10
									
								
								CHANGES
									
									
									
									
									
								
							| @@ -388,6 +388,16 @@ res_pjsip_publish_asterisk | ||||
|    both mailbox state and device state information. | ||||
|  | ||||
|  | ||||
| AMI | ||||
| ------------------ | ||||
|  * Event NewConnectedLine is emitted when the connected line information on | ||||
|    a channel changes. | ||||
|  | ||||
| ARI | ||||
| ------------------ | ||||
|  * Event ChannelConnectedLine is emitted when the connected line information | ||||
|    on a channel changes. | ||||
|  | ||||
| ------------------------------------------------------------------------------ | ||||
| --- Functionality changes from Asterisk 12.4.0 to Asterisk 12.5.0 ------------ | ||||
| ------------------------------------------------------------------------------ | ||||
|   | ||||
| @@ -610,6 +610,20 @@ int ast_channel_snapshot_caller_id_equal( | ||||
| 	const struct ast_channel_snapshot *old_snapshot, | ||||
| 	const struct ast_channel_snapshot *new_snapshot); | ||||
|  | ||||
| /*! | ||||
|  * \brief Compares the connected line info of two snapshots. | ||||
|  * \since 13.1.0 | ||||
|  * | ||||
|  * \param old_snapshot Old snapshot | ||||
|  * \param new_snapshot New snapshot | ||||
|  * | ||||
|  * \return True (non-zero) if callerid are identical. | ||||
|  * \return False (zero) if callerid changed. | ||||
|  */ | ||||
| int ast_channel_snapshot_connected_line_equal( | ||||
| 	const struct ast_channel_snapshot *old_snapshot, | ||||
| 	const struct ast_channel_snapshot *new_snapshot); | ||||
|  | ||||
| /*! | ||||
|  * \brief Initialize the stasis channel topic and message types | ||||
|  * \return 0 on success | ||||
|   | ||||
| @@ -7960,6 +7960,7 @@ void ast_channel_set_connected_line(struct ast_channel *chan, const struct ast_p | ||||
|  | ||||
| 	ast_channel_lock(chan); | ||||
| 	ast_party_connected_line_set(ast_channel_connected(chan), connected, update); | ||||
| 	ast_channel_publish_snapshot(chan); | ||||
| 	ast_channel_unlock(chan); | ||||
| } | ||||
|  | ||||
|   | ||||
| @@ -570,6 +570,23 @@ static struct ast_manager_event_blob *channel_new_callerid( | ||||
| 		ast_describe_caller_presentation(new_snapshot->caller_pres)); | ||||
| } | ||||
|  | ||||
| static struct ast_manager_event_blob *channel_new_connected_line( | ||||
| 	struct ast_channel_snapshot *old_snapshot, | ||||
| 	struct ast_channel_snapshot *new_snapshot) | ||||
| { | ||||
| 	/* No NewConnectedLine event on cache clear or first event */ | ||||
| 	if (!old_snapshot || !new_snapshot) { | ||||
| 		return NULL; | ||||
| 	} | ||||
|  | ||||
| 	if (ast_channel_snapshot_connected_line_equal(old_snapshot, new_snapshot)) { | ||||
| 		return NULL; | ||||
| 	} | ||||
|  | ||||
| 	return ast_manager_event_blob_create( | ||||
| 		EVENT_FLAG_CALL, "NewConnectedLine", "%s", ""); | ||||
| } | ||||
|  | ||||
| static struct ast_manager_event_blob *channel_new_accountcode( | ||||
| 	struct ast_channel_snapshot *old_snapshot, | ||||
| 	struct ast_channel_snapshot *new_snapshot) | ||||
| @@ -591,7 +608,8 @@ channel_snapshot_monitor channel_monitors[] = { | ||||
| 	channel_state_change, | ||||
| 	channel_newexten, | ||||
| 	channel_new_callerid, | ||||
| 	channel_new_accountcode | ||||
| 	channel_new_accountcode, | ||||
| 	channel_new_connected_line, | ||||
| }; | ||||
|  | ||||
| static void channel_snapshot_update(void *data, struct stasis_subscription *sub, | ||||
|   | ||||
| @@ -938,6 +938,16 @@ int ast_channel_snapshot_caller_id_equal( | ||||
| 		strcmp(old_snapshot->caller_name, new_snapshot->caller_name) == 0; | ||||
| } | ||||
|  | ||||
| int ast_channel_snapshot_connected_line_equal( | ||||
| 	const struct ast_channel_snapshot *old_snapshot, | ||||
| 	const struct ast_channel_snapshot *new_snapshot) | ||||
| { | ||||
| 	ast_assert(old_snapshot != NULL); | ||||
| 	ast_assert(new_snapshot != NULL); | ||||
| 	return strcmp(old_snapshot->connected_number, new_snapshot->connected_number) == 0 && | ||||
| 		strcmp(old_snapshot->connected_name, new_snapshot->connected_name) == 0; | ||||
| } | ||||
|  | ||||
| static struct ast_json *channel_blob_to_json( | ||||
| 	struct stasis_message *message, | ||||
| 	const char *type, | ||||
|   | ||||
| @@ -2505,6 +2505,85 @@ ari_validator ast_ari_validate_channel_caller_id_fn(void) | ||||
| 	return ast_ari_validate_channel_caller_id; | ||||
| } | ||||
|  | ||||
| int ast_ari_validate_channel_connected_line(struct ast_json *json) | ||||
| { | ||||
| 	int res = 1; | ||||
| 	struct ast_json_iter *iter; | ||||
| 	int has_type = 0; | ||||
| 	int has_application = 0; | ||||
| 	int has_channel = 0; | ||||
|  | ||||
| 	for (iter = ast_json_object_iter(json); iter; iter = ast_json_object_iter_next(json, iter)) { | ||||
| 		if (strcmp("type", ast_json_object_iter_key(iter)) == 0) { | ||||
| 			int prop_is_valid; | ||||
| 			has_type = 1; | ||||
| 			prop_is_valid = ast_ari_validate_string( | ||||
| 				ast_json_object_iter_value(iter)); | ||||
| 			if (!prop_is_valid) { | ||||
| 				ast_log(LOG_ERROR, "ARI ChannelConnectedLine field type failed validation\n"); | ||||
| 				res = 0; | ||||
| 			} | ||||
| 		} else | ||||
| 		if (strcmp("application", ast_json_object_iter_key(iter)) == 0) { | ||||
| 			int prop_is_valid; | ||||
| 			has_application = 1; | ||||
| 			prop_is_valid = ast_ari_validate_string( | ||||
| 				ast_json_object_iter_value(iter)); | ||||
| 			if (!prop_is_valid) { | ||||
| 				ast_log(LOG_ERROR, "ARI ChannelConnectedLine field application failed validation\n"); | ||||
| 				res = 0; | ||||
| 			} | ||||
| 		} else | ||||
| 		if (strcmp("timestamp", ast_json_object_iter_key(iter)) == 0) { | ||||
| 			int prop_is_valid; | ||||
| 			prop_is_valid = ast_ari_validate_date( | ||||
| 				ast_json_object_iter_value(iter)); | ||||
| 			if (!prop_is_valid) { | ||||
| 				ast_log(LOG_ERROR, "ARI ChannelConnectedLine field timestamp failed validation\n"); | ||||
| 				res = 0; | ||||
| 			} | ||||
| 		} else | ||||
| 		if (strcmp("channel", ast_json_object_iter_key(iter)) == 0) { | ||||
| 			int prop_is_valid; | ||||
| 			has_channel = 1; | ||||
| 			prop_is_valid = ast_ari_validate_channel( | ||||
| 				ast_json_object_iter_value(iter)); | ||||
| 			if (!prop_is_valid) { | ||||
| 				ast_log(LOG_ERROR, "ARI ChannelConnectedLine field channel failed validation\n"); | ||||
| 				res = 0; | ||||
| 			} | ||||
| 		} else | ||||
| 		{ | ||||
| 			ast_log(LOG_ERROR, | ||||
| 				"ARI ChannelConnectedLine has undocumented field %s\n", | ||||
| 				ast_json_object_iter_key(iter)); | ||||
| 			res = 0; | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	if (!has_type) { | ||||
| 		ast_log(LOG_ERROR, "ARI ChannelConnectedLine missing required field type\n"); | ||||
| 		res = 0; | ||||
| 	} | ||||
|  | ||||
| 	if (!has_application) { | ||||
| 		ast_log(LOG_ERROR, "ARI ChannelConnectedLine missing required field application\n"); | ||||
| 		res = 0; | ||||
| 	} | ||||
|  | ||||
| 	if (!has_channel) { | ||||
| 		ast_log(LOG_ERROR, "ARI ChannelConnectedLine missing required field channel\n"); | ||||
| 		res = 0; | ||||
| 	} | ||||
|  | ||||
| 	return res; | ||||
| } | ||||
|  | ||||
| ari_validator ast_ari_validate_channel_connected_line_fn(void) | ||||
| { | ||||
| 	return ast_ari_validate_channel_connected_line; | ||||
| } | ||||
|  | ||||
| int ast_ari_validate_channel_created(struct ast_json *json) | ||||
| { | ||||
| 	int res = 1; | ||||
| @@ -4003,6 +4082,9 @@ int ast_ari_validate_event(struct ast_json *json) | ||||
| 	if (strcmp("ChannelCallerId", discriminator) == 0) { | ||||
| 		return ast_ari_validate_channel_caller_id(json); | ||||
| 	} else | ||||
| 	if (strcmp("ChannelConnectedLine", discriminator) == 0) { | ||||
| 		return ast_ari_validate_channel_connected_line(json); | ||||
| 	} else | ||||
| 	if (strcmp("ChannelCreated", discriminator) == 0) { | ||||
| 		return ast_ari_validate_channel_created(json); | ||||
| 	} else | ||||
| @@ -4171,6 +4253,9 @@ int ast_ari_validate_message(struct ast_json *json) | ||||
| 	if (strcmp("ChannelCallerId", discriminator) == 0) { | ||||
| 		return ast_ari_validate_channel_caller_id(json); | ||||
| 	} else | ||||
| 	if (strcmp("ChannelConnectedLine", discriminator) == 0) { | ||||
| 		return ast_ari_validate_channel_connected_line(json); | ||||
| 	} else | ||||
| 	if (strcmp("ChannelCreated", discriminator) == 0) { | ||||
| 		return ast_ari_validate_channel_created(json); | ||||
| 	} else | ||||
|   | ||||
| @@ -680,6 +680,24 @@ int ast_ari_validate_channel_caller_id(struct ast_json *json); | ||||
|  */ | ||||
| ari_validator ast_ari_validate_channel_caller_id_fn(void); | ||||
|  | ||||
| /*! | ||||
|  * \brief Validator for ChannelConnectedLine. | ||||
|  * | ||||
|  * Channel changed Connected Line. | ||||
|  * | ||||
|  * \param json JSON object to validate. | ||||
|  * \returns True (non-zero) if valid. | ||||
|  * \returns False (zero) if invalid. | ||||
|  */ | ||||
| int ast_ari_validate_channel_connected_line(struct ast_json *json); | ||||
|  | ||||
| /*! | ||||
|  * \brief Function pointer to ast_ari_validate_channel_connected_line(). | ||||
|  * | ||||
|  * See \ref ast_ari_model_validators.h for more details. | ||||
|  */ | ||||
| ari_validator ast_ari_validate_channel_connected_line_fn(void); | ||||
|  | ||||
| /*! | ||||
|  * \brief Validator for ChannelCreated. | ||||
|  * | ||||
| @@ -1330,6 +1348,11 @@ ari_validator ast_ari_validate_application_fn(void); | ||||
|  * - caller_presentation: int (required) | ||||
|  * - caller_presentation_txt: string (required) | ||||
|  * - channel: Channel (required) | ||||
|  * ChannelConnectedLine | ||||
|  * - type: string (required) | ||||
|  * - application: string (required) | ||||
|  * - timestamp: Date | ||||
|  * - channel: Channel (required) | ||||
|  * ChannelCreated | ||||
|  * - type: string (required) | ||||
|  * - application: string (required) | ||||
|   | ||||
| @@ -450,10 +450,38 @@ static struct ast_json *channel_callerid( | ||||
| 		"channel", json_channel); | ||||
| } | ||||
|  | ||||
| static struct ast_json *channel_connected_line( | ||||
| 	struct ast_channel_snapshot *old_snapshot, | ||||
| 	struct ast_channel_snapshot *new_snapshot, | ||||
| 	const struct timeval *tv) | ||||
| { | ||||
| 	struct ast_json *json_channel; | ||||
|  | ||||
| 	/* No ChannelConnectedLine event on cache clear or first event */ | ||||
| 	if (!old_snapshot || !new_snapshot) { | ||||
| 		return NULL; | ||||
| 	} | ||||
|  | ||||
| 	if (ast_channel_snapshot_connected_line_equal(old_snapshot, new_snapshot)) { | ||||
| 		return NULL; | ||||
| 	} | ||||
|  | ||||
| 	json_channel = ast_channel_snapshot_to_json(new_snapshot, stasis_app_get_sanitizer()); | ||||
| 	if (!json_channel) { | ||||
| 		return NULL; | ||||
| 	} | ||||
|  | ||||
| 	return ast_json_pack("{s: s, s: o, s: o}", | ||||
| 		"type", "ChannelConnectedLine", | ||||
| 		"timestamp", ast_json_timeval(*tv, NULL), | ||||
| 		"channel", json_channel); | ||||
| } | ||||
|  | ||||
| static channel_snapshot_monitor channel_monitors[] = { | ||||
| 	channel_state, | ||||
| 	channel_dialplan, | ||||
| 	channel_callerid, | ||||
| 	channel_connected_line, | ||||
| }; | ||||
|  | ||||
| static void sub_channel_update_handler(void *data, | ||||
|   | ||||
| @@ -165,7 +165,8 @@ | ||||
| 				"Dial", | ||||
| 				"StasisEnd", | ||||
| 				"StasisStart", | ||||
| 				"TextMessageReceived" | ||||
| 				"TextMessageReceived", | ||||
| 				"ChannelConnectedLine" | ||||
| 			] | ||||
| 		}, | ||||
| 		"DeviceStateChanged": { | ||||
| @@ -712,6 +713,17 @@ | ||||
| 					"type": "Endpoint" | ||||
| 				} | ||||
| 			} | ||||
| 		}, | ||||
| 		"ChannelConnectedLine": { | ||||
| 			"id": "ChannelConnectedLine", | ||||
| 			"description": "Channel changed Connected Line.", | ||||
| 			"properties": { | ||||
| 				"channel": { | ||||
| 					"required": true, | ||||
| 					"type": "Channel", | ||||
| 					"description": "The channel whose connected line has changed." | ||||
| 				} | ||||
| 			} | ||||
| 		} | ||||
| 	} | ||||
| } | ||||
|   | ||||
		Reference in New Issue
	
	Block a user