mirror of
				https://github.com/asterisk/asterisk.git
				synced 2025-10-31 02:37:10 +00:00 
			
		
		
		
	Add 'bitflags'-style information elements to event framework
This patch add a new payload type for information elements, a set of bit flags. The payload is transported as a 32-bit unsigned integer but when matching is performed between events and subscribers, the matching is done by using a bitwise AND instead of numeric value comparison. Review: http://reviewboard.asterisk.org/r/242/ git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@191919 65c4cc65-6c06-0410-ace0-fbb531ad65f3
This commit is contained in:
		| @@ -156,6 +156,20 @@ void ast_event_sub_destroy(struct ast_event_sub *sub); | ||||
| int ast_event_sub_append_ie_uint(struct ast_event_sub *sub, | ||||
| 	enum ast_event_ie_type ie_type, uint32_t uint); | ||||
|  | ||||
| /*! | ||||
|  * \brief Append a bitflags parameter to a subscription | ||||
|  * | ||||
|  * \param sub the dynamic subscription allocated with ast_event_subscribe_new() | ||||
|  * \param ie_type the information element type for the parameter | ||||
|  * \param flags the flags that must be present in the event to match this subscription | ||||
|  * | ||||
|  * \retval 0 success | ||||
|  * \retval non-zero failure | ||||
|  * \since 1.6.3 | ||||
|  */ | ||||
| int ast_event_sub_append_ie_bitflags(struct ast_event_sub *sub, | ||||
| 	enum ast_event_ie_type ie_type, uint32_t flags); | ||||
|  | ||||
| /*! | ||||
|  * \brief Append a string parameter to a subscription | ||||
|  * | ||||
| @@ -445,6 +459,24 @@ int ast_event_append_ie_str(struct ast_event **event, enum ast_event_ie_type ie_ | ||||
| int ast_event_append_ie_uint(struct ast_event **event, enum ast_event_ie_type ie_type, | ||||
| 	uint32_t data); | ||||
|  | ||||
| /*! | ||||
|  * \brief Append an information element that has a bitflags payload | ||||
|  * | ||||
|  * \param event the event that the IE will be appended to | ||||
|  * \param ie_type the type of IE to append | ||||
|  * \param flags the flags that are the payload of the IE | ||||
|  * | ||||
|  * \retval 0 success | ||||
|  * \retval -1 failure | ||||
|  * \since 1.6.3 | ||||
|  * | ||||
|  * The pointer to the event will get updated with the new location for the event | ||||
|  * that now contains the appended information element.  If the re-allocation of | ||||
|  * the memory for this event fails, it will be set to NULL. | ||||
|  */ | ||||
| int ast_event_append_ie_bitflags(struct ast_event **event, enum ast_event_ie_type ie_type, | ||||
| 	uint32_t bitflags); | ||||
|  | ||||
| /*! | ||||
|  * \brief Append an information element that has a raw payload | ||||
|  * | ||||
| @@ -475,6 +507,18 @@ int ast_event_append_ie_raw(struct ast_event **event, enum ast_event_ie_type ie_ | ||||
|  */ | ||||
| uint32_t ast_event_get_ie_uint(const struct ast_event *event, enum ast_event_ie_type ie_type); | ||||
|  | ||||
| /*! | ||||
|  * \brief Get the value of an information element that has a bitflags payload | ||||
|  * | ||||
|  * \param event The event to get the IE from | ||||
|  * \param ie_type the type of information element to retrieve | ||||
|  * | ||||
|  * \return This returns the payload of the information element with the given type. | ||||
|  *         However, an IE with a payload of 0, and the case where no IE is found | ||||
|  *         yield the same return value. | ||||
|  */ | ||||
| uint32_t ast_event_get_ie_bitflags(const struct ast_event *event, enum ast_event_ie_type ie_type); | ||||
|  | ||||
| /*! | ||||
|  * \brief Get the value of an information element that has a string payload | ||||
|  * | ||||
| @@ -614,7 +658,7 @@ int ast_event_iterator_next(struct ast_event_iterator *iterator); | ||||
| enum ast_event_ie_type ast_event_iterator_get_ie_type(struct ast_event_iterator *iterator); | ||||
|  | ||||
| /*! | ||||
|  * \brief Get the value of the current IE in the ierator as an integer payload | ||||
|  * \brief Get the value of the current IE in the iterator as an integer payload | ||||
|  * | ||||
|  * \param iterator The iterator instance | ||||
|  * | ||||
| @@ -622,6 +666,15 @@ enum ast_event_ie_type ast_event_iterator_get_ie_type(struct ast_event_iterator | ||||
|  */ | ||||
| uint32_t ast_event_iterator_get_ie_uint(struct ast_event_iterator *iterator); | ||||
|  | ||||
| /*! | ||||
|  * \brief Get the value of the current IE in the iterator as a bitflags payload | ||||
|  * | ||||
|  * \param iterator The iterator instance | ||||
|  * | ||||
|  * \return This returns the payload of the information element as bitflags. | ||||
|  */ | ||||
| uint32_t ast_event_iterator_get_ie_bitflags(struct ast_event_iterator *iterator); | ||||
|  | ||||
| /*! | ||||
|  * \brief Get the value of the current IE in the iterator as a string payload | ||||
|  * | ||||
|   | ||||
| @@ -137,6 +137,8 @@ enum ast_event_ie_pltype { | ||||
| 	AST_EVENT_IE_PLTYPE_STR, | ||||
| 	/*! Raw data, compared with memcmp */ | ||||
| 	AST_EVENT_IE_PLTYPE_RAW, | ||||
| 	/*! Bit flags (unsigned integer, compared using boolean logic) */ | ||||
| 	AST_EVENT_IE_PLTYPE_BITFLAGS, | ||||
| }; | ||||
|  | ||||
| /*! | ||||
|   | ||||
							
								
								
									
										108
									
								
								main/event.c
									
									
									
									
									
								
							
							
						
						
									
										108
									
								
								main/event.c
									
									
									
									
									
								
							| @@ -311,6 +311,7 @@ static void ast_event_ie_val_destroy(struct ast_event_ie_val *ie_val) | ||||
| 		ast_free(ie_val->payload.raw); | ||||
| 		break; | ||||
| 	case AST_EVENT_IE_PLTYPE_UINT: | ||||
| 	case AST_EVENT_IE_PLTYPE_BITFLAGS: | ||||
| 	case AST_EVENT_IE_PLTYPE_EXISTS: | ||||
| 	case AST_EVENT_IE_PLTYPE_UNKNOWN: | ||||
| 		break; | ||||
| @@ -347,6 +348,9 @@ enum ast_event_subscriber_res ast_event_check_subscriber(enum ast_event_type typ | ||||
| 		case AST_EVENT_IE_PLTYPE_UINT: | ||||
| 			ie_value->payload.uint = va_arg(ap, uint32_t); | ||||
| 			break; | ||||
| 		case AST_EVENT_IE_PLTYPE_BITFLAGS: | ||||
| 			ie_value->payload.uint = va_arg(ap, uint32_t); | ||||
| 			break; | ||||
| 		case AST_EVENT_IE_PLTYPE_STR: | ||||
| 			ie_value->payload.str = va_arg(ap, const char *); | ||||
| 			break; | ||||
| @@ -392,6 +396,12 @@ enum ast_event_subscriber_res ast_event_check_subscriber(enum ast_event_type typ | ||||
| 			case AST_EVENT_IE_PLTYPE_UINT: | ||||
| 				break_out = (ie_val->payload.uint != sub_ie_val->payload.uint); | ||||
| 				break; | ||||
| 			case AST_EVENT_IE_PLTYPE_BITFLAGS: | ||||
| 				/* if the subscriber has requested *any* of the bitflags we are providing, | ||||
| 				 * then it's a match | ||||
| 				 */ | ||||
| 				break_out = (ie_val->payload.uint & sub_ie_val->payload.uint); | ||||
| 				break; | ||||
| 			case AST_EVENT_IE_PLTYPE_STR: | ||||
| 				break_out = strcmp(ie_val->payload.str, sub_ie_val->payload.str); | ||||
| 				break; | ||||
| @@ -436,14 +446,26 @@ enum ast_event_subscriber_res ast_event_check_subscriber(enum ast_event_type typ | ||||
| static int match_ie_val(const struct ast_event *event, | ||||
| 		const struct ast_event_ie_val *ie_val, const struct ast_event *event2) | ||||
| { | ||||
| 	if (ie_val->ie_pltype == AST_EVENT_IE_PLTYPE_UINT) { | ||||
| 	switch (ie_val->ie_pltype) { | ||||
| 	case AST_EVENT_IE_PLTYPE_UINT: | ||||
| 	{ | ||||
| 		uint32_t val = event2 ? ast_event_get_ie_uint(event2, ie_val->ie_type) : ie_val->payload.uint; | ||||
| 		if (val == ast_event_get_ie_uint(event, ie_val->ie_type)) | ||||
| 			return 1; | ||||
| 		return 0; | ||||
|  | ||||
| 		return (val == ast_event_get_ie_uint(event, ie_val->ie_type)) ? 1 : 0; | ||||
| 	} | ||||
|  | ||||
| 	if (ie_val->ie_pltype == AST_EVENT_IE_PLTYPE_STR) { | ||||
| 	case AST_EVENT_IE_PLTYPE_BITFLAGS: | ||||
| 	{ | ||||
| 		uint32_t flags = event2 ? ast_event_get_ie_uint(event2, ie_val->ie_type) : ie_val->payload.uint; | ||||
|  | ||||
| 		/* if the subscriber has requested *any* of the bitflags that this event provides, | ||||
| 		 * then it's a match | ||||
| 		 */ | ||||
| 		return (flags & ast_event_get_ie_bitflags(event, ie_val->ie_type)) ? 1 : 0; | ||||
| 	} | ||||
|  | ||||
| 	case AST_EVENT_IE_PLTYPE_STR: | ||||
| 	{ | ||||
| 		const char *str; | ||||
| 		uint32_t hash; | ||||
|  | ||||
| @@ -460,16 +482,19 @@ static int match_ie_val(const struct ast_event *event, | ||||
| 		return 0; | ||||
| 	} | ||||
|  | ||||
| 	if (ie_val->ie_pltype == AST_EVENT_IE_PLTYPE_RAW) { | ||||
| 	case AST_EVENT_IE_PLTYPE_RAW: | ||||
| 	{ | ||||
| 		const void *buf = event2 ? ast_event_get_ie_raw(event2, ie_val->ie_type) : ie_val->payload.raw; | ||||
| 		if (buf && !memcmp(buf, ast_event_get_ie_raw(event, ie_val->ie_type), ie_val->raw_datalen)) | ||||
| 			return 1; | ||||
| 		return 0; | ||||
|  | ||||
| 		return (buf && !memcmp(buf, ast_event_get_ie_raw(event, ie_val->ie_type), ie_val->raw_datalen)) ? 1 : 0; | ||||
| 	} | ||||
|  | ||||
| 	if (ie_val->ie_pltype == AST_EVENT_IE_PLTYPE_EXISTS) { | ||||
| 		if (ast_event_get_ie_raw(event, ie_val->ie_type)) | ||||
| 			return 1; | ||||
| 	case AST_EVENT_IE_PLTYPE_EXISTS: | ||||
| 	{ | ||||
| 		return ast_event_get_ie_raw(event, ie_val->ie_type) ? 1 : 0; | ||||
| 	} | ||||
|  | ||||
| 	case AST_EVENT_IE_PLTYPE_UNKNOWN: | ||||
| 		return 0; | ||||
| 	} | ||||
|  | ||||
| @@ -527,6 +552,9 @@ static struct ast_event *gen_sub_event(struct ast_event_sub *sub) | ||||
| 		case AST_EVENT_IE_PLTYPE_UINT: | ||||
| 			ast_event_append_ie_uint(&event, ie_val->ie_type, ie_val->payload.uint); | ||||
| 			break; | ||||
| 		case AST_EVENT_IE_PLTYPE_BITFLAGS: | ||||
| 			ast_event_append_ie_bitflags(&event, ie_val->ie_type, ie_val->payload.uint); | ||||
| 			break; | ||||
| 		case AST_EVENT_IE_PLTYPE_STR: | ||||
| 			ast_event_append_ie_str(&event, ie_val->ie_type, ie_val->payload.str); | ||||
| 			break; | ||||
| @@ -625,6 +653,26 @@ int ast_event_sub_append_ie_uint(struct ast_event_sub *sub, | ||||
| 	return 0; | ||||
| } | ||||
|  | ||||
| int ast_event_sub_append_ie_bitflags(struct ast_event_sub *sub, | ||||
| 	enum ast_event_ie_type ie_type, uint32_t flags) | ||||
| { | ||||
| 	struct ast_event_ie_val *ie_val; | ||||
|  | ||||
| 	if (ie_type < 0 || ie_type > AST_EVENT_IE_MAX) | ||||
| 		return -1; | ||||
|  | ||||
| 	if (!(ie_val = ast_calloc(1, sizeof(*ie_val)))) | ||||
| 		return -1; | ||||
|  | ||||
| 	ie_val->ie_type = ie_type; | ||||
| 	ie_val->payload.uint = flags; | ||||
| 	ie_val->ie_pltype = AST_EVENT_IE_PLTYPE_BITFLAGS; | ||||
|  | ||||
| 	AST_LIST_INSERT_TAIL(&sub->ie_vals, ie_val, entry); | ||||
|  | ||||
| 	return 0; | ||||
| } | ||||
|  | ||||
| int ast_event_sub_append_ie_exists(struct ast_event_sub *sub, | ||||
| 	enum ast_event_ie_type ie_type) | ||||
| { | ||||
| @@ -753,6 +801,12 @@ struct ast_event_sub *ast_event_subscribe(enum ast_event_type type, ast_event_cb | ||||
| 			ast_event_sub_append_ie_uint(sub, ie_type, unsigned_int); | ||||
| 			break; | ||||
| 		} | ||||
| 		case AST_EVENT_IE_PLTYPE_BITFLAGS: | ||||
| 		{ | ||||
| 			uint32_t unsigned_int = va_arg(ap, uint32_t); | ||||
| 			ast_event_sub_append_ie_bitflags(sub, ie_type, unsigned_int); | ||||
| 			break; | ||||
| 		} | ||||
| 		case AST_EVENT_IE_PLTYPE_STR: | ||||
| 		{ | ||||
| 			const char *str = va_arg(ap, const char *); | ||||
| @@ -839,6 +893,11 @@ uint32_t ast_event_iterator_get_ie_uint(struct ast_event_iterator *iterator) | ||||
| 	return ntohl(get_unaligned_uint32(iterator->ie->ie_payload)); | ||||
| } | ||||
|  | ||||
| uint32_t ast_event_iterator_get_ie_bitflags(struct ast_event_iterator *iterator) | ||||
| { | ||||
| 	return ntohl(get_unaligned_uint32(iterator->ie->ie_payload)); | ||||
| } | ||||
|  | ||||
| const char *ast_event_iterator_get_ie_str(struct ast_event_iterator *iterator) | ||||
| { | ||||
| 	const struct ast_event_ie_str_payload *str_payload; | ||||
| @@ -867,6 +926,15 @@ uint32_t ast_event_get_ie_uint(const struct ast_event *event, enum ast_event_ie_ | ||||
| 	return ie_val ? ntohl(get_unaligned_uint32(ie_val)) : 0; | ||||
| } | ||||
|  | ||||
| uint32_t ast_event_get_ie_bitflags(const struct ast_event *event, enum ast_event_ie_type ie_type) | ||||
| { | ||||
| 	const uint32_t *ie_val; | ||||
|  | ||||
| 	ie_val = ast_event_get_ie_raw(event, ie_type); | ||||
|  | ||||
| 	return ie_val ? ntohl(get_unaligned_uint32(ie_val)) : 0; | ||||
| } | ||||
|  | ||||
| uint32_t ast_event_get_ie_str_hash(const struct ast_event *event, enum ast_event_ie_type ie_type) | ||||
| { | ||||
| 	const struct ast_event_ie_str_payload *str_payload; | ||||
| @@ -921,6 +989,13 @@ int ast_event_append_ie_uint(struct ast_event **event, enum ast_event_ie_type ie | ||||
| 	return ast_event_append_ie_raw(event, ie_type, &data, sizeof(data)); | ||||
| } | ||||
|  | ||||
| int ast_event_append_ie_bitflags(struct ast_event **event, enum ast_event_ie_type ie_type, | ||||
| 	uint32_t flags) | ||||
| { | ||||
| 	flags = htonl(flags); | ||||
| 	return ast_event_append_ie_raw(event, ie_type, &flags, sizeof(flags)); | ||||
| } | ||||
|  | ||||
| int ast_event_append_ie_raw(struct ast_event **event, enum ast_event_ie_type ie_type, | ||||
| 	const void *data, size_t data_len) | ||||
| { | ||||
| @@ -974,6 +1049,9 @@ struct ast_event *ast_event_new(enum ast_event_type type, ...) | ||||
| 		case AST_EVENT_IE_PLTYPE_UINT: | ||||
| 			ie_value->payload.uint = va_arg(ap, uint32_t); | ||||
| 			break; | ||||
| 		case AST_EVENT_IE_PLTYPE_BITFLAGS: | ||||
| 			ie_value->payload.uint = va_arg(ap, uint32_t); | ||||
| 			break; | ||||
| 		case AST_EVENT_IE_PLTYPE_STR: | ||||
| 			ie_value->payload.str = va_arg(ap, const char *); | ||||
| 			break; | ||||
| @@ -1014,6 +1092,9 @@ struct ast_event *ast_event_new(enum ast_event_type type, ...) | ||||
| 		case AST_EVENT_IE_PLTYPE_UINT: | ||||
| 			ast_event_append_ie_uint(&event, ie_val->ie_type, ie_val->payload.uint); | ||||
| 			break; | ||||
| 		case AST_EVENT_IE_PLTYPE_BITFLAGS: | ||||
| 			ast_event_append_ie_bitflags(&event, ie_val->ie_type, ie_val->payload.uint); | ||||
| 			break; | ||||
| 		case AST_EVENT_IE_PLTYPE_RAW: | ||||
| 			ast_event_append_ie_raw(&event, ie_val->ie_type, | ||||
| 					ie_val->payload.raw, ie_val->raw_datalen); | ||||
| @@ -1108,6 +1189,9 @@ struct ast_event *ast_event_get_cached(enum ast_event_type type, ...) | ||||
| 		case AST_EVENT_IE_PLTYPE_UINT: | ||||
| 			ast_event_append_ie_uint(&cache_arg_event, ie_type, va_arg(ap, uint32_t)); | ||||
| 			break; | ||||
| 		case AST_EVENT_IE_PLTYPE_BITFLAGS: | ||||
| 			ast_event_append_ie_bitflags(&cache_arg_event, ie_type, va_arg(ap, uint32_t)); | ||||
| 			break; | ||||
| 		case AST_EVENT_IE_PLTYPE_STR: | ||||
| 			ast_event_append_ie_str(&cache_arg_event, ie_type, va_arg(ap, const char *)); | ||||
| 			break; | ||||
|   | ||||
		Reference in New Issue
	
	Block a user