mirror of
				https://github.com/asterisk/asterisk.git
				synced 2025-10-31 02:37:10 +00:00 
			
		
		
		
	Merge "res_pjsip_outbound_registration: Subscribe to network change events"
This commit is contained in:
		| @@ -180,12 +180,12 @@ | ||||
| 		<syntax> | ||||
| 			<xi:include xpointer="xpointer(/docs/manager[@name='Login']/syntax/parameter[@name='ActionID'])" /> | ||||
| 			<parameter name="Registration" required="true"> | ||||
| 				<para>The outbound registration to unregister.</para> | ||||
| 				<para>The outbound registration to unregister or '*all' to unregister them all.</para> | ||||
| 			</parameter> | ||||
| 		</syntax> | ||||
| 		<description> | ||||
| 			<para> | ||||
| 			Unregisters the specified outbound registration and stops future registration attempts. | ||||
| 			Unregisters the specified (or all) outbound registration(s) and stops future registration attempts. | ||||
| 			Call PJSIPRegister to start registration and schedule re-registrations according to configuration. | ||||
|             </para> | ||||
| 		</description> | ||||
| @@ -197,14 +197,13 @@ | ||||
| 		<syntax> | ||||
| 			<xi:include xpointer="xpointer(/docs/manager[@name='Login']/syntax/parameter[@name='ActionID'])" /> | ||||
| 			<parameter name="Registration" required="true"> | ||||
| 				<para>The outbound registration to register.</para> | ||||
| 				<para>The outbound registration to register or '*all' to register them all.</para> | ||||
| 			</parameter> | ||||
| 		</syntax> | ||||
| 		<description> | ||||
| 			<para> | ||||
| 			Unregisters the specified outbound registration then starts registration and schedules re-registrations | ||||
| 			Unregisters the specified (or all) outbound registration(s) then starts registration and schedules re-registrations | ||||
| 			according to configuration. | ||||
| 			future registrations. | ||||
|             </para> | ||||
| 		</description> | ||||
| 	</manager> | ||||
| @@ -379,6 +378,9 @@ static struct ast_serializer_shutdown_group *shutdown_group; | ||||
| #define DEFAULT_STATE_BUCKETS 53 | ||||
| static AO2_GLOBAL_OBJ_STATIC(current_states); | ||||
|  | ||||
| /*! subscription id for network change events */ | ||||
| static struct stasis_subscription *network_change_sub; | ||||
|  | ||||
| /*! \brief hashing function for state objects */ | ||||
| static int registration_state_hash(const void *obj, const int flags) | ||||
| { | ||||
| @@ -1469,6 +1471,26 @@ static int queue_register(struct sip_outbound_registration_state *state) | ||||
| 	return 0; | ||||
| } | ||||
|  | ||||
| static void unregister_all(void) | ||||
| { | ||||
| 	struct ao2_container *states; | ||||
|  | ||||
| 	states = ao2_global_obj_ref(current_states); | ||||
| 	if (!states) { | ||||
| 		return; | ||||
| 	} | ||||
|  | ||||
| 	/* Clean out all the states and let sorcery handle recreating the registrations */ | ||||
| 	ao2_callback(states, OBJ_UNLINK | OBJ_NODATA | OBJ_MULTIPLE, NULL, NULL); | ||||
| 	ao2_ref(states, -1); | ||||
| } | ||||
|  | ||||
| static void reregister_all(void) | ||||
| { | ||||
| 	unregister_all(); | ||||
| 	ast_sorcery_load_object(ast_sip_get_sorcery(), "registration"); | ||||
| } | ||||
|  | ||||
| static char *cli_complete_registration(const char *line, const char *word, | ||||
| 				       int pos, int state) | ||||
| { | ||||
| @@ -1484,6 +1506,10 @@ static char *cli_complete_registration(const char *line, const char *word, | ||||
| 	} | ||||
|  | ||||
| 	wordlen = strlen(word); | ||||
| 	if (wordlen == 0 && ++which > state) { | ||||
| 		return ast_strdup("*all"); | ||||
| 	} | ||||
|  | ||||
| 	registrations = ast_sorcery_retrieve_by_fields(ast_sip_get_sorcery(), "registration", | ||||
| 		AST_RETRIEVE_FLAG_MULTIPLE | AST_RETRIEVE_FLAG_ALL, NULL); | ||||
| 	if (!registrations) { | ||||
| @@ -1518,8 +1544,9 @@ static char *cli_unregister(struct ast_cli_entry *e, int cmd, struct ast_cli_arg | ||||
| 	case CLI_INIT: | ||||
| 		e->command = "pjsip send unregister"; | ||||
| 		e->usage = | ||||
| 			"Usage: pjsip send unregister <registration>\n" | ||||
| 			"       Unregisters the specified outbound registration and stops future registration attempts.\n"; | ||||
| 			"Usage: pjsip send unregister <registration> | *all\n" | ||||
| 			"       Unregisters the specified (or all) outbound registration(s) " | ||||
| 			"and stops future registration attempts.\n"; | ||||
| 		return NULL; | ||||
| 	case CLI_GENERATE: | ||||
| 		return cli_complete_registration(a->line, a->word, a->pos, a->n); | ||||
| @@ -1531,6 +1558,12 @@ static char *cli_unregister(struct ast_cli_entry *e, int cmd, struct ast_cli_arg | ||||
|  | ||||
| 	registration_name = a->argv[3]; | ||||
|  | ||||
| 	if (strcmp(registration_name, "*all") == 0) { | ||||
| 		unregister_all(); | ||||
| 		ast_cli(a->fd, "Unregister all queued\n"); | ||||
| 		return CLI_SUCCESS; | ||||
| 	} | ||||
|  | ||||
| 	state = get_state(registration_name); | ||||
| 	if (!state) { | ||||
| 		ast_cli(a->fd, "Unable to retrieve registration %s\n", registration_name); | ||||
| @@ -1554,9 +1587,9 @@ static char *cli_register(struct ast_cli_entry *e, int cmd, struct ast_cli_args | ||||
| 	case CLI_INIT: | ||||
| 		e->command = "pjsip send register"; | ||||
| 		e->usage = | ||||
| 			"Usage: pjsip send register <registration>\n" | ||||
| 			"       Unregisters the specified outbound " | ||||
| 			"registration then re-registers and re-schedules it.\n"; | ||||
| 			"Usage: pjsip send register <registration> | *all \n" | ||||
| 			"       Unregisters the specified (or all) outbound " | ||||
| 			"registration(s) then starts registration(s) and schedules re-registrations.\n"; | ||||
| 		return NULL; | ||||
| 	case CLI_GENERATE: | ||||
| 		return cli_complete_registration(a->line, a->word, a->pos, a->n); | ||||
| @@ -1568,6 +1601,12 @@ static char *cli_register(struct ast_cli_entry *e, int cmd, struct ast_cli_args | ||||
|  | ||||
| 	registration_name = a->argv[3]; | ||||
|  | ||||
| 	if (strcmp(registration_name, "*all") == 0) { | ||||
| 		reregister_all(); | ||||
| 		ast_cli(a->fd, "Re-register all queued\n"); | ||||
| 		return CLI_SUCCESS; | ||||
| 	} | ||||
|  | ||||
| 	state = get_state(registration_name); | ||||
| 	if (!state) { | ||||
| 		ast_cli(a->fd, "Unable to retrieve registration %s\n", registration_name); | ||||
| @@ -1597,6 +1636,12 @@ static int ami_unregister(struct mansession *s, const struct message *m) | ||||
| 		return 0; | ||||
| 	} | ||||
|  | ||||
| 	if (strcmp(registration_name, "*all") == 0) { | ||||
| 		unregister_all(); | ||||
| 		astman_send_ack(s, m, "Unregistrations queued."); | ||||
| 		return 0; | ||||
| 	} | ||||
|  | ||||
| 	state = get_state(registration_name); | ||||
| 	if (!state) { | ||||
| 		astman_send_error(s, m, "Unable to retrieve registration entry\n"); | ||||
| @@ -1623,6 +1668,12 @@ static int ami_register(struct mansession *s, const struct message *m) | ||||
| 		return 0; | ||||
| 	} | ||||
|  | ||||
| 	if (strcmp(registration_name, "*all") == 0) { | ||||
| 		reregister_all(); | ||||
| 		astman_send_ack(s, m, "Reregistrations queued."); | ||||
| 		return 0; | ||||
| 	} | ||||
|  | ||||
| 	state = get_state(registration_name); | ||||
| 	if (!state) { | ||||
| 		astman_send_error(s, m, "Unable to retrieve registration entry\n"); | ||||
| @@ -1798,10 +1849,6 @@ static int cli_print_body(void *obj, void *arg, int flags) | ||||
|  | ||||
| 	ast_assert(context->output_buffer != NULL); | ||||
|  | ||||
| 	if (!state) { | ||||
| 		return 0; | ||||
| 	} | ||||
|  | ||||
| 	ast_str_append(&context->output_buffer, 0, " %-s/%-*.*s  %-16s  %-16s\n", | ||||
| 		id, | ||||
| 		(int) (REGISTRATION_URI_FIELD_LEN - strlen(id)), | ||||
| @@ -1810,8 +1857,8 @@ static int cli_print_body(void *obj, void *arg, int flags) | ||||
| 		AST_VECTOR_SIZE(®istration->outbound_auths) | ||||
| 			? AST_VECTOR_GET(®istration->outbound_auths, 0) | ||||
| 			: "n/a", | ||||
| 		sip_outbound_registration_status_str(state->client_state->status)); | ||||
| 	ao2_ref(state, -1); | ||||
| 		(state ? sip_outbound_registration_status_str(state->client_state->status) : "Unregistered")); | ||||
| 	ao2_cleanup(state); | ||||
|  | ||||
| 	if (context->show_details | ||||
| 		|| (context->show_details_only_level_0 && context->indent_level == 0)) { | ||||
| @@ -1971,10 +2018,23 @@ static const struct ast_sorcery_observer registration_observer = { | ||||
| 	.deleted = registration_deleted_observer, | ||||
| }; | ||||
|  | ||||
| static void network_change_stasis_cb(void *data, struct stasis_subscription *sub, struct stasis_message *message) | ||||
| { | ||||
| 	/* This callback is only concerned with network change messages from the system topic. */ | ||||
| 	if (stasis_message_type(message) != ast_network_change_type()) { | ||||
| 		return; | ||||
| 	} | ||||
| 	ast_debug(3, "Received network change event\n"); | ||||
|  | ||||
| 	reregister_all(); | ||||
| } | ||||
|  | ||||
| static int unload_module(void) | ||||
| { | ||||
| 	int remaining; | ||||
|  | ||||
| 	network_change_sub = stasis_unsubscribe_and_join(network_change_sub); | ||||
|  | ||||
| 	ast_manager_unregister("PJSIPShowRegistrationsOutbound"); | ||||
| 	ast_manager_unregister("PJSIPUnregister"); | ||||
| 	ast_manager_unregister("PJSIPRegister"); | ||||
| @@ -2112,6 +2172,9 @@ static int load_module(void) | ||||
| 	/* Load configuration objects */ | ||||
| 	ast_sorcery_load_object(ast_sip_get_sorcery(), "registration"); | ||||
|  | ||||
| 	network_change_sub = stasis_subscribe(ast_system_topic(), | ||||
| 		network_change_stasis_cb, NULL); | ||||
|  | ||||
| 	return AST_MODULE_LOAD_SUCCESS; | ||||
| } | ||||
|  | ||||
|   | ||||
		Reference in New Issue
	
	Block a user