示例#1
0
int ast_sip_initialize_sorcery_qualify(void)
{
	struct ast_sorcery *sorcery = ast_sip_get_sorcery();

	/* initialize sorcery ast_sip_contact_status resource */
	ast_sorcery_apply_default(sorcery, CONTACT_STATUS, "memory", NULL);

	if (ast_sorcery_internal_object_register(sorcery, CONTACT_STATUS,
					contact_status_alloc, NULL, NULL)) {
		ast_log(LOG_ERROR, "Unable to register ast_sip_contact_status in sorcery\n");
		return -1;
	}

	snprintf(status_value_unknown, sizeof(status_value_unknown), "%u", UNKNOWN);
	ast_sorcery_object_field_register_nodoc(sorcery, CONTACT_STATUS, "last_status",
		status_value_unknown, OPT_UINT_T, 1, FLDSET(struct ast_sip_contact_status, last_status));
	snprintf(status_value_created, sizeof(status_value_created), "%u", CREATED);
	ast_sorcery_object_field_register_nodoc(sorcery, CONTACT_STATUS, "status",
		status_value_created, OPT_UINT_T, 1, FLDSET(struct ast_sip_contact_status, status));
	ast_sorcery_object_field_register_custom_nodoc(sorcery, CONTACT_STATUS, "rtt_start",
		"0.0", rtt_start_handler, rtt_start_to_str, NULL, 0, 0);
	ast_sorcery_object_field_register_nodoc(sorcery, CONTACT_STATUS, "rtt",
		"0", OPT_UINT_T, 1, FLDSET(struct ast_sip_contact_status, rtt));

	return 0;
}
示例#2
0
/*! \brief Initialize sorcery with transport support */
int ast_sip_initialize_sorcery_transport(struct ast_sorcery *sorcery)
{
	ast_sorcery_apply_default(sorcery, "transport", "config", "pjsip.conf,criteria=type=transport");

	if (ast_sorcery_object_register_no_reload(sorcery, "transport", transport_alloc, NULL, transport_apply)) {
		return -1;
	}

	ast_sorcery_object_field_register(sorcery, "transport", "type", "", OPT_NOOP_T, 0, 0);
	ast_sorcery_object_field_register_custom(sorcery, "transport", "protocol", "udp", transport_protocol_handler, NULL, 0, 0);
	ast_sorcery_object_field_register_custom(sorcery, "transport", "bind", "", transport_bind_handler, NULL, 0, 0);
	ast_sorcery_object_field_register(sorcery, "transport", "async_operations", "1", OPT_UINT_T, 0, FLDSET(struct ast_sip_transport, async_operations));
	ast_sorcery_object_field_register(sorcery, "transport", "ca_list_file", "", OPT_STRINGFIELD_T, 0, STRFLDSET(struct ast_sip_transport, ca_list_file));
	ast_sorcery_object_field_register(sorcery, "transport", "cert_file", "", OPT_STRINGFIELD_T, 0, STRFLDSET(struct ast_sip_transport, cert_file));
	ast_sorcery_object_field_register(sorcery, "transport", "privkey_file", "", OPT_STRINGFIELD_T, 0, STRFLDSET(struct ast_sip_transport, privkey_file));
	ast_sorcery_object_field_register(sorcery, "transport", "password", "", OPT_STRINGFIELD_T, 0, STRFLDSET(struct ast_sip_transport, password));
	ast_sorcery_object_field_register(sorcery, "transport", "external_signaling_address", "", OPT_STRINGFIELD_T, 0, STRFLDSET(struct ast_sip_transport, external_signaling_address));
	ast_sorcery_object_field_register(sorcery, "transport", "external_signaling_port", "0", OPT_UINT_T, PARSE_IN_RANGE, FLDSET(struct ast_sip_transport, external_signaling_port), 0, 65535);
	ast_sorcery_object_field_register(sorcery, "transport", "external_media_address", "", OPT_STRINGFIELD_T, 0, STRFLDSET(struct ast_sip_transport, external_media_address));
	ast_sorcery_object_field_register(sorcery, "transport", "domain", "", OPT_STRINGFIELD_T, 0, STRFLDSET(struct ast_sip_transport, domain));
	ast_sorcery_object_field_register_custom(sorcery, "transport", "verify_server", "", transport_tls_bool_handler, NULL, 0, 0);
	ast_sorcery_object_field_register_custom(sorcery, "transport", "verify_client", "", transport_tls_bool_handler, NULL, 0, 0);
	ast_sorcery_object_field_register_custom(sorcery, "transport", "require_client_cert", "", transport_tls_bool_handler, NULL, 0, 0);
	ast_sorcery_object_field_register_custom(sorcery, "transport", "method", "", transport_tls_method_handler, NULL, 0, 0);
	ast_sorcery_object_field_register_custom(sorcery, "transport", "cipher", "", transport_tls_cipher_handler, NULL, 0, 0);
	ast_sorcery_object_field_register_custom(sorcery, "transport", "localnet", "", transport_localnet_handler, NULL, 0, 0);
	ast_sorcery_object_field_register(sorcery, "transport", "tos", "0", OPT_UINT_T, 0, FLDSET(struct ast_sip_transport, tos));
	ast_sorcery_object_field_register(sorcery, "transport", "cos", "0", OPT_UINT_T, 0, FLDSET(struct ast_sip_transport, cos));

	return 0;
}
示例#3
0
/*!
 * \internal
 * \brief Initialize sorcery for external MWI.
 * \since 12.1.0
 *
 * \retval 0 on success.
 * \retval -1 on error.
 */
static int mwi_sorcery_init(void)
{
	int res;

	mwi_sorcery = ast_sorcery_open();
	if (!mwi_sorcery) {
		ast_log(LOG_ERROR, "MWI external: Sorcery failed to open.\n");
		return -1;
	}

	/* Map the external MWI wizards. */
	if (ast_sorcery_apply_default(mwi_sorcery, MWI_MAILBOX_TYPE, "astdb",
			MWI_ASTDB_PREFIX) == AST_SORCERY_APPLY_FAIL) {
		ast_log(LOG_ERROR, "MWI external: Sorcery could not setup wizards.\n");
		return -1;
	}

	res = ast_sorcery_object_register(mwi_sorcery, MWI_MAILBOX_TYPE,
		mwi_sorcery_object_alloc, NULL, NULL);
	if (res) {
		ast_log(LOG_ERROR, "MWI external: Sorcery could not register object type '%s'.\n",
			MWI_MAILBOX_TYPE);
		return -1;
	}

	/* Define the MWI_MAILBOX_TYPE object fields. */
	res |= ast_sorcery_object_field_register_nodoc(mwi_sorcery, MWI_MAILBOX_TYPE,
		"msgs_new", "0", OPT_UINT_T, 0, FLDSET(struct ast_mwi_mailbox_object, msgs_new));
	res |= ast_sorcery_object_field_register_nodoc(mwi_sorcery, MWI_MAILBOX_TYPE,
		"msgs_old", "0", OPT_UINT_T, 0, FLDSET(struct ast_mwi_mailbox_object, msgs_old));
	return res ? -1 : 0;
}
示例#4
0
static int load_module(void)
{
	CHECK_PJSIP_MODULE_LOADED();

	ast_sorcery_apply_config(ast_sip_get_sorcery(), SIP_SORCERY_ACL_TYPE);
	ast_sorcery_apply_default(ast_sip_get_sorcery(), SIP_SORCERY_ACL_TYPE,
				  "config", "pjsip.conf,criteria=type=acl");

	if (ast_sorcery_object_register(ast_sip_get_sorcery(), SIP_SORCERY_ACL_TYPE,
					acl_alloc, NULL, NULL)) {

		ast_log(LOG_ERROR, "Failed to register SIP %s object with sorcery\n",
			SIP_SORCERY_ACL_TYPE);
		return AST_MODULE_LOAD_DECLINE;
	}

	ast_sorcery_object_field_register(ast_sip_get_sorcery(), SIP_SORCERY_ACL_TYPE, "type", "", OPT_NOOP_T, 0, 0);
	ast_sorcery_object_field_register_custom(ast_sip_get_sorcery(), SIP_SORCERY_ACL_TYPE, "permit", "", acl_handler, NULL, NULL, 0, 0);
	ast_sorcery_object_field_register_custom(ast_sip_get_sorcery(), SIP_SORCERY_ACL_TYPE, "deny", "", acl_handler, NULL, NULL, 0, 0);
	ast_sorcery_object_field_register_custom(ast_sip_get_sorcery(), SIP_SORCERY_ACL_TYPE, "acl", "", acl_handler, NULL, NULL, 0, 0);
	ast_sorcery_object_field_register_custom(ast_sip_get_sorcery(), SIP_SORCERY_ACL_TYPE, "contact_permit", "", acl_handler, NULL, NULL, 0, 0);
	ast_sorcery_object_field_register_custom(ast_sip_get_sorcery(), SIP_SORCERY_ACL_TYPE, "contact_deny", "", acl_handler, NULL, NULL, 0, 0);
	ast_sorcery_object_field_register_custom(ast_sip_get_sorcery(), SIP_SORCERY_ACL_TYPE, "contact_acl", "", acl_handler, NULL, NULL, 0, 0);

	ast_sorcery_load_object(ast_sip_get_sorcery(), SIP_SORCERY_ACL_TYPE);

	ast_sip_register_service(&acl_module);
	return AST_MODULE_LOAD_SUCCESS;
}
示例#5
0
int respoke_app_initialize(void)
{
	struct ast_sorcery *sorcery = respoke_get_sorcery();

	ast_sorcery_apply_default(sorcery, RESPOKE_APP, "config",
				  "respoke.conf,criteria=type=app");

	if (ast_sorcery_internal_object_register(
		    sorcery, RESPOKE_APP, respoke_app_alloc,
		    NULL, respoke_app_apply)) {
		return -1;
	}

	/* These are purposely marked as nodoc as documentation will
	   not be included with the running Asterisk */
	ast_sorcery_object_field_register_nodoc(
		sorcery, RESPOKE_APP, "type", "", OPT_NOOP_T, 0, 0);
	ast_sorcery_object_field_register_nodoc(
		sorcery, RESPOKE_APP, "app_secret", "", OPT_STRINGFIELD_T, 0,
		STRFLDSET(struct respoke_app, secret));

	ast_sorcery_reload_object(sorcery, RESPOKE_APP);

	return 0;
}
示例#6
0
/*! \brief Initialize sorcery with auth support */
int ast_sip_initialize_sorcery_auth(void)
{
	struct ast_sorcery *sorcery = ast_sip_get_sorcery();

	ast_sorcery_apply_default(sorcery, SIP_SORCERY_AUTH_TYPE, "config", "pjsip.conf,criteria=type=auth");

	if (ast_sorcery_object_register(sorcery, SIP_SORCERY_AUTH_TYPE, auth_alloc, NULL, auth_apply)) {
		return -1;
	}

	ast_sorcery_object_field_register(sorcery, SIP_SORCERY_AUTH_TYPE, "type", "",
			OPT_NOOP_T, 0, 0);
	ast_sorcery_object_field_register(sorcery, SIP_SORCERY_AUTH_TYPE, "username",
			"", OPT_STRINGFIELD_T, 0, STRFLDSET(struct ast_sip_auth, auth_user));
	ast_sorcery_object_field_register(sorcery, SIP_SORCERY_AUTH_TYPE, "password",
			"", OPT_STRINGFIELD_T, 0, STRFLDSET(struct ast_sip_auth, auth_pass));
	ast_sorcery_object_field_register(sorcery, SIP_SORCERY_AUTH_TYPE, "md5_cred",
			"", OPT_STRINGFIELD_T, 0, STRFLDSET(struct ast_sip_auth, md5_creds));
	ast_sorcery_object_field_register(sorcery, SIP_SORCERY_AUTH_TYPE, "realm",
			"", OPT_STRINGFIELD_T, 0, STRFLDSET(struct ast_sip_auth, realm));
	ast_sorcery_object_field_register(sorcery, SIP_SORCERY_AUTH_TYPE, "nonce_lifetime",
			"32", OPT_UINT_T, 0, FLDSET(struct ast_sip_auth, nonce_lifetime));
	ast_sorcery_object_field_register_custom(sorcery, SIP_SORCERY_AUTH_TYPE, "auth_type",
			"userpass", auth_type_handler, auth_type_to_str, NULL, 0, 0);

	ast_sip_register_endpoint_formatter(&endpoint_auth_formatter);

	cli_formatter = ao2_alloc(sizeof(struct ast_sip_cli_formatter_entry), NULL);
	if (!cli_formatter) {
		ast_log(LOG_ERROR, "Unable to allocate memory for cli formatter\n");
		return -1;
	}
	cli_formatter->name = SIP_SORCERY_AUTH_TYPE;
	cli_formatter->print_header = cli_print_header;
	cli_formatter->print_body = cli_print_body;
	cli_formatter->get_container = cli_get_container;
	cli_formatter->iterate = cli_iterator;
	cli_formatter->get_id = ast_sorcery_object_get_id;
	cli_formatter->retrieve_by_id = cli_retrieve_by_id;

	ast_sip_register_cli_formatter(cli_formatter);
	ast_cli_register_multiple(cli_commands, ARRAY_LEN(cli_commands));

	if (ast_manager_register_xml("PJSIPShowAuths", EVENT_FLAG_SYSTEM, ami_show_auths)) {
		return -1;
	}

	return 0;
}
示例#7
0
/*! \brief Initialize sorcery with domain alias support */
int ast_sip_initialize_sorcery_domain_alias(struct ast_sorcery *sorcery)
{
	ast_sorcery_apply_default(sorcery, SIP_SORCERY_DOMAIN_ALIAS_TYPE, "config", "pjsip.conf,criteria=type=domain_alias");

	if (ast_sorcery_object_register(sorcery, SIP_SORCERY_DOMAIN_ALIAS_TYPE, domain_alias_alloc, NULL, NULL)) {
		return -1;
	}

	ast_sorcery_object_field_register(sorcery, SIP_SORCERY_DOMAIN_ALIAS_TYPE, "type", "",
			OPT_NOOP_T, 0, 0);
	ast_sorcery_object_field_register(sorcery, SIP_SORCERY_DOMAIN_ALIAS_TYPE, "domain",
			"", OPT_STRINGFIELD_T, 0, STRFLDSET(struct ast_sip_domain_alias, domain));

	return 0;
}
示例#8
0
static struct ast_sorcery *alloc_and_initialize_sorcery(void)
{
	struct ast_sorcery *sorcery;

	if (!(sorcery = ast_sorcery_open())) {
		return NULL;
	}

	if ((ast_sorcery_apply_default(sorcery, "test", "astdb", "test") != AST_SORCERY_APPLY_SUCCESS) ||
		ast_sorcery_internal_object_register(sorcery, "test", test_sorcery_object_alloc, NULL, NULL)) {
		ast_sorcery_unref(sorcery);
		return NULL;
	}

	ast_sorcery_object_field_register_nodoc(sorcery, "test", "bob", "5", OPT_UINT_T, 0, FLDSET(struct test_sorcery_object, bob));
	ast_sorcery_object_field_register_nodoc(sorcery, "test", "joe", "10", OPT_UINT_T, 0, FLDSET(struct test_sorcery_object, joe));

	return sorcery;
}
示例#9
0
static struct ast_sorcery *alloc_and_initialize_sorcery(void)
{
	struct ast_sorcery *sorcery;

	if (!(sorcery = ast_sorcery_open())) {
		return NULL;
	}

	if (ast_sorcery_apply_default(sorcery, "test", "realtime", "sorcery_realtime_test") ||
		ast_sorcery_internal_object_register(sorcery, "test", test_sorcery_object_alloc, NULL, NULL) ||
		!(realtime_objects = ast_config_new())) {
		ast_sorcery_unref(sorcery);
		return NULL;
	}

	ast_sorcery_object_field_register_nodoc(sorcery, "test", "bob", "5", OPT_UINT_T, 0, FLDSET(struct test_sorcery_object, bob));
	ast_sorcery_object_field_register_nodoc(sorcery, "test", "joe", "10", OPT_UINT_T, 0, FLDSET(struct test_sorcery_object, joe));

	return sorcery;
}
示例#10
0
int ast_sip_initialize_sorcery_qualify(void)
{
	struct ast_sorcery *sorcery = ast_sip_get_sorcery();

	/* initialize sorcery ast_sip_contact_status resource */
	ast_sorcery_apply_default(sorcery, CONTACT_STATUS, "memory", NULL);

	if (ast_sorcery_internal_object_register(sorcery, CONTACT_STATUS,
					contact_status_alloc, NULL, NULL)) {
		ast_log(LOG_ERROR, "Unable to register ast_sip_contact_status in sorcery\n");
		return -1;
	}

	ast_sorcery_object_field_register_nodoc(sorcery, CONTACT_STATUS, "rtt", "0", OPT_UINT_T,
					  1, FLDSET(struct ast_sip_contact_status, status));
	ast_sorcery_object_field_register_nodoc(sorcery, CONTACT_STATUS, "rtt", "0", OPT_UINT_T,
					  1, FLDSET(struct ast_sip_contact_status, rtt));

	return 0;
}
示例#11
0
/*! \brief Initialize sorcery with location support */
int ast_sip_initialize_sorcery_location(void)
{
	struct ast_sorcery *sorcery = ast_sip_get_sorcery();
	int i;

	ast_sorcery_apply_default(sorcery, "contact", "astdb", "registrar");
	ast_sorcery_apply_default(sorcery, "aor", "config", "pjsip.conf,criteria=type=aor");

	if (ast_sorcery_object_register(sorcery, "contact", contact_alloc, NULL, contact_apply_handler) ||
		ast_sorcery_object_register(sorcery, "aor", aor_alloc, NULL, NULL)) {
		return -1;
	}

	ast_sorcery_observer_add(sorcery, "aor", &aor_observer);

	ast_sorcery_object_field_register(sorcery, "contact", "type", "", OPT_NOOP_T, 0, 0);
	ast_sorcery_object_field_register(sorcery, "contact", "uri", "", OPT_STRINGFIELD_T, 0, STRFLDSET(struct ast_sip_contact, uri));
	ast_sorcery_object_field_register(sorcery, "contact", "path", "", OPT_STRINGFIELD_T, 0, STRFLDSET(struct ast_sip_contact, path));
	ast_sorcery_object_field_register_custom(sorcery, "contact", "expiration_time", "", expiration_str2struct, expiration_struct2str, NULL, 0, 0);
	ast_sorcery_object_field_register(sorcery, "contact", "qualify_frequency", 0, OPT_UINT_T,
		PARSE_IN_RANGE, FLDSET(struct ast_sip_contact, qualify_frequency), 0, 86400);
	ast_sorcery_object_field_register(sorcery, "contact", "qualify_timeout", "3.0", OPT_DOUBLE_T, 0, FLDSET(struct ast_sip_contact, qualify_timeout));
	ast_sorcery_object_field_register(sorcery, "contact", "outbound_proxy", "", OPT_STRINGFIELD_T, 0, STRFLDSET(struct ast_sip_contact, outbound_proxy));
	ast_sorcery_object_field_register(sorcery, "contact", "user_agent", "", OPT_STRINGFIELD_T, 0, STRFLDSET(struct ast_sip_contact, user_agent));

	ast_sorcery_object_field_register(sorcery, "aor", "type", "", OPT_NOOP_T, 0, 0);
	ast_sorcery_object_field_register(sorcery, "aor", "minimum_expiration", "60", OPT_UINT_T, 0, FLDSET(struct ast_sip_aor, minimum_expiration));
	ast_sorcery_object_field_register(sorcery, "aor", "maximum_expiration", "7200", OPT_UINT_T, 0, FLDSET(struct ast_sip_aor, maximum_expiration));
	ast_sorcery_object_field_register(sorcery, "aor", "default_expiration", "3600", OPT_UINT_T, 0, FLDSET(struct ast_sip_aor, default_expiration));
	ast_sorcery_object_field_register(sorcery, "aor", "qualify_frequency", 0, OPT_UINT_T, PARSE_IN_RANGE, FLDSET(struct ast_sip_aor, qualify_frequency), 0, 86400);
	ast_sorcery_object_field_register(sorcery, "aor", "qualify_timeout", "3.0", OPT_DOUBLE_T, 0, FLDSET(struct ast_sip_aor, qualify_timeout));
	ast_sorcery_object_field_register(sorcery, "aor", "authenticate_qualify", "no", OPT_BOOL_T, 1, FLDSET(struct ast_sip_aor, authenticate_qualify));
	ast_sorcery_object_field_register(sorcery, "aor", "max_contacts", "0", OPT_UINT_T, 0, FLDSET(struct ast_sip_aor, max_contacts));
	ast_sorcery_object_field_register(sorcery, "aor", "remove_existing", "no", OPT_BOOL_T, 1, FLDSET(struct ast_sip_aor, remove_existing));
	ast_sorcery_object_field_register_custom(sorcery, "aor", "contact", "", permanent_uri_handler, contacts_to_str, contacts_to_var_list, 0, 0);
	ast_sorcery_object_field_register(sorcery, "aor", "mailboxes", "", OPT_STRINGFIELD_T, 0, STRFLDSET(struct ast_sip_aor, mailboxes));
	ast_sorcery_object_field_register(sorcery, "aor", "outbound_proxy", "", OPT_STRINGFIELD_T, 0, STRFLDSET(struct ast_sip_aor, outbound_proxy));
	ast_sorcery_object_field_register(sorcery, "aor", "support_path", "no", OPT_BOOL_T, 1, FLDSET(struct ast_sip_aor, support_path));

	internal_sip_register_endpoint_formatter(&endpoint_aor_formatter);

	contact_formatter = ao2_alloc(sizeof(struct ast_sip_cli_formatter_entry), NULL);
	if (!contact_formatter) {
		ast_log(LOG_ERROR, "Unable to allocate memory for contact_formatter\n");
		return -1;
	}
	contact_formatter->name = "contact";
	contact_formatter->print_header = cli_contact_print_header;
	contact_formatter->print_body = cli_contact_print_body;
	contact_formatter->get_container = cli_contact_get_container;
	contact_formatter->iterate = cli_contact_iterate;
	contact_formatter->get_id = cli_contact_get_id;
	contact_formatter->retrieve_by_id = cli_contact_retrieve_by_id;

	aor_formatter = ao2_alloc(sizeof(struct ast_sip_cli_formatter_entry), NULL);
	if (!aor_formatter) {
		ast_log(LOG_ERROR, "Unable to allocate memory for aor_formatter\n");
		return -1;
	}
	aor_formatter->name = "aor";
	aor_formatter->print_header = cli_aor_print_header;
	aor_formatter->print_body = cli_aor_print_body;
	aor_formatter->get_container = cli_aor_get_container;
	aor_formatter->iterate = cli_aor_iterate;
	aor_formatter->get_id = cli_aor_get_id;
	aor_formatter->retrieve_by_id = cli_aor_retrieve_by_id;

	ast_sip_register_cli_formatter(contact_formatter);
	ast_sip_register_cli_formatter(aor_formatter);
	ast_cli_register_multiple(cli_commands, ARRAY_LEN(cli_commands));

	/*
	 * Reset StatsD gauges in case we didn't shut down cleanly.
	 * Note that this must done here, as contacts will create the contact_status
	 * object before PJSIP options handling is initialized.
	 */
	for (i = 0; i <= REMOVED; i++) {
		ast_statsd_log_full_va("PJSIP.contacts.states.%s", AST_STATSD_GAUGE, 0, 1.0, ast_sip_get_contact_status_label(i));
	}

	return 0;
}
示例#12
0
/*! \brief Initialize sorcery with location support */
int ast_sip_initialize_sorcery_location(void)
{
	struct ast_sorcery *sorcery = ast_sip_get_sorcery();
	ast_sorcery_apply_default(sorcery, "contact", "astdb", "registrar");
	ast_sorcery_apply_default(sorcery, "aor", "config", "pjsip.conf,criteria=type=aor");

	if (ast_sorcery_object_register(sorcery, "contact", contact_alloc, NULL, NULL) ||
		ast_sorcery_object_register(sorcery, "aor", aor_alloc, NULL, NULL)) {
		return -1;
	}

	ast_sorcery_object_field_register(sorcery, "contact", "type", "", OPT_NOOP_T, 0, 0);
	ast_sorcery_object_field_register(sorcery, "contact", "uri", "", OPT_STRINGFIELD_T, 0, STRFLDSET(struct ast_sip_contact, uri));
	ast_sorcery_object_field_register(sorcery, "contact", "path", "", OPT_STRINGFIELD_T, 0, STRFLDSET(struct ast_sip_contact, path));
	ast_sorcery_object_field_register_custom(sorcery, "contact", "expiration_time", "", expiration_str2struct, expiration_struct2str, NULL, 0, 0);
	ast_sorcery_object_field_register(sorcery, "contact", "qualify_frequency", 0, OPT_UINT_T,
					  PARSE_IN_RANGE, FLDSET(struct ast_sip_contact, qualify_frequency), 0, 86400);
	ast_sorcery_object_field_register(sorcery, "contact", "outbound_proxy", "", OPT_STRINGFIELD_T, 0, STRFLDSET(struct ast_sip_contact, outbound_proxy));
	ast_sorcery_object_field_register(sorcery, "contact", "user_agent", "", OPT_STRINGFIELD_T, 0, STRFLDSET(struct ast_sip_contact, user_agent));

	ast_sorcery_object_field_register(sorcery, "aor", "type", "", OPT_NOOP_T, 0, 0);
	ast_sorcery_object_field_register(sorcery, "aor", "minimum_expiration", "60", OPT_UINT_T, 0, FLDSET(struct ast_sip_aor, minimum_expiration));
	ast_sorcery_object_field_register(sorcery, "aor", "maximum_expiration", "7200", OPT_UINT_T, 0, FLDSET(struct ast_sip_aor, maximum_expiration));
	ast_sorcery_object_field_register(sorcery, "aor", "default_expiration", "3600", OPT_UINT_T, 0, FLDSET(struct ast_sip_aor, default_expiration));
	ast_sorcery_object_field_register(sorcery, "aor", "qualify_frequency", 0, OPT_UINT_T, PARSE_IN_RANGE, FLDSET(struct ast_sip_aor, qualify_frequency), 0, 86400);
	ast_sorcery_object_field_register(sorcery, "aor", "authenticate_qualify", "no", OPT_BOOL_T, 1, FLDSET(struct ast_sip_aor, authenticate_qualify));
	ast_sorcery_object_field_register(sorcery, "aor", "max_contacts", "0", OPT_UINT_T, 0, FLDSET(struct ast_sip_aor, max_contacts));
	ast_sorcery_object_field_register(sorcery, "aor", "remove_existing", "no", OPT_BOOL_T, 1, FLDSET(struct ast_sip_aor, remove_existing));
	ast_sorcery_object_field_register_custom(sorcery, "aor", "contact", "", permanent_uri_handler, contacts_to_str, contacts_to_var_list, 0, 0);
	ast_sorcery_object_field_register(sorcery, "aor", "mailboxes", "", OPT_STRINGFIELD_T, 0, STRFLDSET(struct ast_sip_aor, mailboxes));
	ast_sorcery_object_field_register(sorcery, "aor", "outbound_proxy", "", OPT_STRINGFIELD_T, 0, STRFLDSET(struct ast_sip_aor, outbound_proxy));
	ast_sorcery_object_field_register(sorcery, "aor", "support_path", "no", OPT_BOOL_T, 1, FLDSET(struct ast_sip_aor, support_path));

	internal_sip_register_endpoint_formatter(&endpoint_aor_formatter);

	contact_formatter = ao2_alloc(sizeof(struct ast_sip_cli_formatter_entry), NULL);
	if (!contact_formatter) {
		ast_log(LOG_ERROR, "Unable to allocate memory for contact_formatter\n");
		return -1;
	}
	contact_formatter->name = "contact";
	contact_formatter->print_header = cli_contact_print_header;
	contact_formatter->print_body = cli_contact_print_body;
	contact_formatter->get_container = cli_contact_get_container;
	contact_formatter->iterate = cli_contact_iterate;
	contact_formatter->get_id = cli_contact_get_id;
	contact_formatter->retrieve_by_id = cli_contact_retrieve_by_id;

	aor_formatter = ao2_alloc(sizeof(struct ast_sip_cli_formatter_entry), NULL);
	if (!aor_formatter) {
		ast_log(LOG_ERROR, "Unable to allocate memory for aor_formatter\n");
		return -1;
	}
	aor_formatter->name = "aor";
	aor_formatter->print_header = cli_aor_print_header;
	aor_formatter->print_body = cli_aor_print_body;
	aor_formatter->get_container = cli_aor_get_container;
	aor_formatter->iterate = cli_aor_iterate;
	aor_formatter->get_id = cli_aor_get_id;
	aor_formatter->retrieve_by_id = cli_aor_retrieve_by_id;

	ast_sip_register_cli_formatter(contact_formatter);
	ast_sip_register_cli_formatter(aor_formatter);
	ast_cli_register_multiple(cli_commands, ARRAY_LEN(cli_commands));

	return 0;
}