summaryrefslogtreecommitdiff
path: root/res/res_pjsip/location.c
diff options
context:
space:
mode:
Diffstat (limited to 'res/res_pjsip/location.c')
-rw-r--r--res/res_pjsip/location.c59
1 files changed, 49 insertions, 10 deletions
diff --git a/res/res_pjsip/location.c b/res/res_pjsip/location.c
index 6213046e3..557aeb6b9 100644
--- a/res/res_pjsip/location.c
+++ b/res/res_pjsip/location.c
@@ -356,13 +356,12 @@ struct ast_sip_contact *ast_sip_location_retrieve_contact(const char *contact_na
return ast_sorcery_retrieve_by_id(ast_sip_get_sorcery(), "contact", contact_name);
}
-int ast_sip_location_add_contact_nolock(struct ast_sip_aor *aor, const char *uri,
- struct timeval expiration_time, const char *path_info, const char *user_agent,
- const char *via_addr, int via_port, const char *call_id,
- struct ast_sip_endpoint *endpoint)
+struct ast_sip_contact *ast_sip_location_create_contact(struct ast_sip_aor *aor,
+ const char *uri, struct timeval expiration_time, const char *path_info,
+ const char *user_agent, const char *via_addr, int via_port, const char *call_id,
+ int prune_on_boot, struct ast_sip_endpoint *endpoint)
{
struct ast_sip_contact *contact;
- int res;
char name[MAX_OBJECT_FIELD * 2 + 3];
char hash[33];
@@ -371,7 +370,7 @@ int ast_sip_location_add_contact_nolock(struct ast_sip_aor *aor, const char *uri
contact = ast_sorcery_alloc(ast_sip_get_sorcery(), "contact", name);
if (!contact) {
- return -1;
+ return NULL;
}
ast_string_field_set(contact, uri, uri);
@@ -405,14 +404,30 @@ int ast_sip_location_add_contact_nolock(struct ast_sip_aor *aor, const char *uri
}
contact->endpoint = ao2_bump(endpoint);
-
if (endpoint) {
ast_string_field_set(contact, endpoint_name, ast_sorcery_object_get_id(endpoint));
}
- res = ast_sorcery_create(ast_sip_get_sorcery(), contact);
- ao2_ref(contact, -1);
- return res;
+ contact->prune_on_boot = prune_on_boot;
+
+ if (ast_sorcery_create(ast_sip_get_sorcery(), contact)) {
+ ao2_ref(contact, -1);
+ return NULL;
+ }
+ return contact;
+}
+
+int ast_sip_location_add_contact_nolock(struct ast_sip_aor *aor, const char *uri,
+ struct timeval expiration_time, const char *path_info, const char *user_agent,
+ const char *via_addr, int via_port, const char *call_id,
+ struct ast_sip_endpoint *endpoint)
+{
+ struct ast_sip_contact *contact;
+
+ contact = ast_sip_location_create_contact(aor, uri, expiration_time, path_info,
+ user_agent, via_addr, via_port, call_id, 0, endpoint);
+ ao2_cleanup(contact);
+ return contact ? 0 : -1;
}
int ast_sip_location_add_contact(struct ast_sip_aor *aor, const char *uri,
@@ -441,6 +456,29 @@ int ast_sip_location_delete_contact(struct ast_sip_contact *contact)
return ast_sorcery_delete(ast_sip_get_sorcery(), contact);
}
+static int prune_boot_contacts_cb(void *obj, void *arg, int flags)
+{
+ struct ast_sip_contact *contact = obj;
+
+ if (contact->prune_on_boot) {
+ ast_sip_location_delete_contact(contact);
+ }
+
+ return 0;
+}
+
+void ast_sip_location_prune_boot_contacts(void)
+{
+ struct ao2_container *contacts;
+
+ contacts = ast_sorcery_retrieve_by_fields(ast_sip_get_sorcery(), "contact",
+ AST_RETRIEVE_FLAG_MULTIPLE | AST_RETRIEVE_FLAG_ALL, NULL);
+ if (contacts) {
+ ao2_callback(contacts, 0, prune_boot_contacts_cb, NULL);
+ ao2_ref(contacts, -1);
+ }
+}
+
/*! \brief Custom handler for translating from a string timeval to actual structure */
static int expiration_str2struct(const struct aco_option *opt, struct ast_variable *var, void *obj)
{
@@ -1221,6 +1259,7 @@ int ast_sip_initialize_sorcery_location(void)
ast_sorcery_object_field_register(sorcery, "contact", "via_addr", "", OPT_STRINGFIELD_T, 0, STRFLDSET(struct ast_sip_contact, via_addr));
ast_sorcery_object_field_register(sorcery, "contact", "via_port", "0", OPT_UINT_T, 0, FLDSET(struct ast_sip_contact, via_port));
ast_sorcery_object_field_register(sorcery, "contact", "call_id", "", OPT_STRINGFIELD_T, 0, STRFLDSET(struct ast_sip_contact, call_id));
+ ast_sorcery_object_field_register(sorcery, "contact", "prune_on_boot", "no", OPT_YESNO_T, 1, FLDSET(struct ast_sip_contact, prune_on_boot));
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));