Skip to content
GitLab
Explore
Sign in
Register
Primary navigation
Search or go to…
Project
A
asterisk
Manage
Activity
Members
Labels
Plan
Issues
Issue boards
Milestones
Wiki
Code
Merge requests
Repository
Branches
Commits
Tags
Repository graph
Compare revisions
Snippets
Build
Pipelines
Jobs
Pipeline schedules
Artifacts
Deploy
Releases
Container Registry
Model registry
Operate
Environments
Monitor
Incidents
Analyze
Value stream analytics
Contributor analytics
CI/CD analytics
Repository analytics
Issue analytics
Model experiments
Help
Help
Support
GitLab documentation
Compare GitLab plans
Community forum
Contribute to GitLab
Provide feedback
Terms and privacy
Keyboard shortcuts
?
Snippets
Groups
Projects
Show more breadcrumbs
Voice
asterisk
Commits
3f1fe836
Commit
3f1fe836
authored
9 years ago
by
Mark Michelson
Committed by
Gerrit Code Review
9 years ago
Browse files
Options
Downloads
Plain Diff
Merge "res_pjsip_mwi: Set up unsolicited MWI upon registration."
parents
6fffef78
7846f734
No related branches found
Branches containing commit
No related tags found
Tags containing commit
No related merge requests found
Changes
4
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
include/asterisk/res_pjsip.h
+5
-1
5 additions, 1 deletion
include/asterisk/res_pjsip.h
res/res_pjsip/location.c
+5
-1
5 additions, 1 deletion
res/res_pjsip/location.c
res/res_pjsip_mwi.c
+113
-63
113 additions, 63 deletions
res/res_pjsip_mwi.c
res/res_pjsip_registrar.c
+1
-1
1 addition, 1 deletion
res/res_pjsip_registrar.c
with
124 additions
and
66 deletions
include/asterisk/res_pjsip.h
+
5
−
1
View file @
3f1fe836
...
...
@@ -168,6 +168,8 @@ struct ast_sip_contact {
int
authenticate_qualify
;
/*! Qualify timeout. 0 is diabled. */
double
qualify_timeout
;
/*! Endpoint that added the contact, only available in observers */
struct
ast_sip_endpoint
*
endpoint
;
};
#define CONTACT_STATUS "contact_status"
...
...
@@ -952,12 +954,14 @@ struct ast_sip_contact *ast_sip_location_retrieve_contact(const char *contact_na
* \param expiration_time Optional expiration time of the contact
* \param path_info Path information
* \param user_agent User-Agent header from REGISTER request
* \param endpoint The endpoint that resulted in the contact being added
*
* \retval -1 failure
* \retval 0 success
*/
int
ast_sip_location_add_contact
(
struct
ast_sip_aor
*
aor
,
const
char
*
uri
,
struct
timeval
expiration_time
,
const
char
*
path_info
,
const
char
*
user_agent
);
struct
timeval
expiration_time
,
const
char
*
path_info
,
const
char
*
user_agent
,
struct
ast_sip_endpoint
*
endpoint
);
/*!
* \brief Update a contact
...
...
This diff is collapsed.
Click to expand it.
res/res_pjsip/location.c
+
5
−
1
View file @
3f1fe836
...
...
@@ -53,6 +53,7 @@ static void contact_destroy(void *obj)
struct
ast_sip_contact
*
contact
=
obj
;
ast_string_field_free_memory
(
contact
);
ao2_cleanup
(
contact
->
endpoint
);
}
/*! \brief Allocator for contact */
...
...
@@ -228,7 +229,8 @@ struct ast_sip_contact *ast_sip_location_retrieve_contact(const char *contact_na
}
int
ast_sip_location_add_contact
(
struct
ast_sip_aor
*
aor
,
const
char
*
uri
,
struct
timeval
expiration_time
,
const
char
*
path_info
,
const
char
*
user_agent
)
struct
timeval
expiration_time
,
const
char
*
path_info
,
const
char
*
user_agent
,
struct
ast_sip_endpoint
*
endpoint
)
{
char
name
[
MAX_OBJECT_FIELD
*
2
+
3
];
RAII_VAR
(
struct
ast_sip_contact
*
,
contact
,
NULL
,
ao2_cleanup
);
...
...
@@ -256,6 +258,8 @@ int ast_sip_location_add_contact(struct ast_sip_aor *aor, const char *uri,
ast_string_field_set
(
contact
,
user_agent
,
user_agent
);
}
contact
->
endpoint
=
ao2_bump
(
endpoint
);
return
ast_sorcery_create
(
ast_sip_get_sorcery
(),
contact
);
}
...
...
This diff is collapsed.
Click to expand it.
res/res_pjsip_mwi.c
+
113
−
63
View file @
3f1fe836
...
...
@@ -40,7 +40,7 @@
#include
"asterisk/app.h"
struct
mwi_subscription
;
AO2_GLOBAL_OBJ_STATIC
(
unsolicited_mwi
)
;
static
struct
ao2_container
*
unsolicited_mwi
;
#define STASIS_BUCKETS 13
#define MWI_BUCKETS 53
...
...
@@ -297,7 +297,7 @@ static int mwi_sub_cmp(void *obj, void *arg, int flags)
static
int
get_message_count
(
void
*
obj
,
void
*
arg
,
int
flags
)
{
RAII_VAR
(
struct
stasis_message
*
,
msg
,
NULL
,
ao2_cleanup
)
;
struct
stasis_message
*
msg
;
struct
mwi_stasis_subscription
*
mwi_stasis
=
obj
;
struct
ast_sip_message_accumulator
*
counter
=
arg
;
struct
ast_mwi_state
*
mwi_state
;
...
...
@@ -310,6 +310,9 @@ static int get_message_count(void *obj, void *arg, int flags)
mwi_state
=
stasis_message_data
(
msg
);
counter
->
old_msgs
+=
mwi_state
->
old_msgs
;
counter
->
new_msgs
+=
mwi_state
->
new_msgs
;
ao2_ref
(
msg
,
-
1
);
return
0
;
}
...
...
@@ -479,22 +482,24 @@ static int unsubscribe_stasis(void *obj, void *arg, int flags)
static
void
mwi_subscription_shutdown
(
struct
ast_sip_subscription
*
sub
)
{
struct
mwi_subscription
*
mwi_sub
;
RAII_VAR
(
struct
ast_datastore
*
,
mwi_datastore
,
ast_sip_subscription_get_datastore
(
sub
,
MWI_DATASTORE
),
ao2_cleanup
);
struct
ast_datastore
*
mwi_datastore
;
mwi_datastore
=
ast_sip_subscription_get_datastore
(
sub
,
MWI_DATASTORE
);
if
(
!
mwi_datastore
)
{
return
;
}
mwi_sub
=
mwi_datastore
->
data
;
ao2_callback
(
mwi_sub
->
stasis_subs
,
OBJ_UNLINK
|
OBJ_NODATA
|
OBJ_MULTIPLE
,
unsubscribe_stasis
,
NULL
);
ao2_ref
(
mwi_datastore
,
-
1
);
}
static
struct
ast_datastore_info
mwi_ds_info
=
{
};
static
int
add_mwi_datastore
(
struct
mwi_subscription
*
sub
)
{
RAII_VAR
(
struct
ast_datastore
*
,
mwi_datastore
,
NULL
,
ao2_cleanup
)
;
struct
ast_datastore
*
mwi_datastore
;
mwi_datastore
=
ast_sip_subscription_alloc_datastore
(
&
mwi_ds_info
,
MWI_DATASTORE
);
if
(
!
mwi_datastore
)
{
...
...
@@ -503,6 +508,7 @@ static int add_mwi_datastore(struct mwi_subscription *sub)
mwi_datastore
->
data
=
sub
;
ast_sip_subscription_add_datastore
(
sub
->
sip_sub
,
mwi_datastore
);
ao2_ref
(
mwi_datastore
,
-
1
);
return
0
;
}
...
...
@@ -517,18 +523,12 @@ static int add_mwi_datastore(struct mwi_subscription *sub)
static
int
endpoint_receives_unsolicited_mwi_for_mailbox
(
struct
ast_sip_endpoint
*
endpoint
,
const
char
*
mailbox
)
{
struct
ao2_container
*
unsolicited
=
ao2_global_obj_ref
(
unsolicited_mwi
);
struct
ao2_iterator
*
mwi_subs
;
struct
mwi_subscription
*
mwi_sub
;
const
char
*
endpoint_id
=
ast_sorcery_object_get_id
(
endpoint
);
int
ret
=
0
;
if
(
!
unsolicited
)
{
return
0
;
}
mwi_subs
=
ao2_find
(
unsolicited
,
endpoint_id
,
OBJ_SEARCH_KEY
|
OBJ_MULTIPLE
);
ao2_cleanup
(
unsolicited
);
mwi_subs
=
ao2_find
(
unsolicited_mwi
,
endpoint_id
,
OBJ_SEARCH_KEY
|
OBJ_MULTIPLE
);
if
(
!
mwi_subs
)
{
return
0
;
...
...
@@ -597,11 +597,15 @@ static int mwi_on_aor(void *obj, void *arg, int flags)
mailboxes
=
ast_strdupa
(
aor
->
mailboxes
);
while
((
mailbox
=
strsep
(
&
mailboxes
,
","
)))
{
RAII_VAR
(
struct
mwi_stasis_subscription
*
,
mwi_stasis_sub
,
mwi_stasis_subscription_alloc
(
mailbox
,
sub
),
ao2_cleanup
);
if
(
mwi_stasis_sub
)
{
ao2_link
(
sub
->
stasis_subs
,
mwi_stasis_sub
);
struct
mwi_stasis_subscription
*
mwi_stasis_sub
;
mwi_stasis_sub
=
mwi_stasis_subscription_alloc
(
mailbox
,
sub
);
if
(
!
mwi_stasis_sub
)
{
continue
;
}
ao2_link
(
sub
->
stasis_subs
,
mwi_stasis_sub
);
ao2_ref
(
mwi_stasis_sub
,
-
1
);
}
return
0
;
...
...
@@ -768,9 +772,9 @@ static void mwi_to_ami(struct ast_sip_subscription *sub,
struct
ast_str
**
buf
)
{
struct
mwi_subscription
*
mwi_sub
;
RAII_VAR
(
struct
ast_datastore
*
,
mwi_datastore
,
ast_sip_subscription_get_datastore
(
sub
,
MWI_DATASTORE
),
ao2_cleanup
);
struct
ast_datastore
*
mwi_datastore
;
mwi_datastore
=
ast_sip_subscription_get_datastore
(
sub
,
MWI_DATASTORE
);
if
(
!
mwi_datastore
)
{
return
;
}
...
...
@@ -781,6 +785,8 @@ static void mwi_to_ami(struct ast_sip_subscription *sub,
ast_str_append
(
buf
,
0
,
"Mailboxes: "
);
mwi_subscription_mailboxes_str
(
mwi_sub
->
stasis_subs
,
buf
);
ast_str_append
(
buf
,
0
,
"
\r\n
"
);
ao2_ref
(
mwi_datastore
,
-
1
);
}
static
int
serialized_notify
(
void
*
userdata
)
...
...
@@ -840,14 +846,38 @@ static int create_mwi_subscriptions_for_endpoint(void *obj, void *arg, int flags
{
RAII_VAR
(
struct
mwi_subscription
*
,
aggregate_sub
,
NULL
,
ao2_cleanup
);
struct
ast_sip_endpoint
*
endpoint
=
obj
;
struct
ao2_container
*
mwi_subscriptions
=
arg
;
char
*
mailboxes
;
char
*
mailbox
;
char
*
endpoint_aors
,
*
aor_name
,
*
mailboxes
,
*
mailbox
;
struct
ao2_container
*
contacts
=
NULL
;
if
(
ast_strlen_zero
(
endpoint
->
subscription
.
mwi
.
mailboxes
))
{
return
0
;
}
endpoint_aors
=
ast_strdupa
(
endpoint
->
aors
);
while
((
aor_name
=
strsep
(
&
endpoint_aors
,
","
)))
{
RAII_VAR
(
struct
ast_sip_aor
*
,
aor
,
ast_sip_location_retrieve_aor
(
aor_name
),
ao2_cleanup
);
if
(
!
aor
)
{
continue
;
}
contacts
=
ast_sip_location_retrieve_aor_contacts
(
aor
);
if
(
!
contacts
||
(
ao2_container_count
(
contacts
)
==
0
))
{
ao2_cleanup
(
contacts
);
contacts
=
NULL
;
continue
;
}
break
;
}
if
(
!
contacts
)
{
return
0
;
}
ao2_ref
(
contacts
,
-
1
);
if
(
endpoint
->
subscription
.
mwi
.
aggregate
)
{
aggregate_sub
=
mwi_subscription_alloc
(
endpoint
,
0
,
NULL
);
if
(
!
aggregate_sub
)
{
...
...
@@ -859,18 +889,20 @@ static int create_mwi_subscriptions_for_endpoint(void *obj, void *arg, int flags
while
((
mailbox
=
strsep
(
&
mailboxes
,
","
)))
{
struct
mwi_subscription
*
sub
=
aggregate_sub
?:
mwi_subscription_alloc
(
endpoint
,
0
,
NULL
);
RAII_VAR
(
struct
mwi_stasis_subscription
*
,
mwi_stasis_sub
,
mwi_stasis_subscription_alloc
(
mailbox
,
sub
),
ao2_cleanup
);
struct
mwi_stasis_subscription
*
mwi_stasis_sub
;
mwi_stasis_sub
=
mwi_stasis_subscription_alloc
(
mailbox
,
sub
);
if
(
mwi_stasis_sub
)
{
ao2_link
(
sub
->
stasis_subs
,
mwi_stasis_sub
);
ao2_ref
(
mwi_stasis_sub
,
-
1
);
}
if
(
!
aggregate_sub
)
{
ao2_link
(
mwi_subscriptions
,
sub
);
ao2_
cleanup
(
sub
);
if
(
!
aggregate_sub
&&
sub
)
{
ao2_link
_flags
(
unsolicited_mwi
,
sub
,
OBJ_NOLOCK
);
ao2_
ref
(
sub
,
-
1
);
}
}
if
(
aggregate_sub
)
{
ao2_link
(
mwi_subscriptions
,
aggregate_sub
);
ao2_link
_flags
(
unsolicited_mwi
,
aggregate_sub
,
OBJ_NOLOCK
);
}
return
0
;
}
...
...
@@ -886,13 +918,11 @@ static int unsubscribe(void *obj, void *arg, int flags)
static
void
create_mwi_subscriptions
(
void
)
{
struct
ao2_container
*
mwi_subscriptions
=
ao2_container_alloc
(
MWI_BUCKETS
,
mwi_sub_hash
,
mwi_sub_cmp
);
RAII_VAR
(
struct
ao2_container
*
,
old_mwi_subscriptions
,
ao2_global_obj_ref
(
unsolicited_mwi
),
ao2_cleanup
);
RAII_VAR
(
struct
ao2_container
*
,
endpoints
,
ast_sorcery_retrieve_by_fields
(
ast_sip_get_sorcery
(),
"endpoint"
,
AST_RETRIEVE_FLAG_MULTIPLE
|
AST_RETRIEVE_FLAG_ALL
,
NULL
),
ao2_cleanup
);
struct
ao2_container
*
endpoints
;
if
(
!
mwi_subscriptions
)
{
endpoints
=
ast_sorcery_retrieve_by_fields
(
ast_sip_get_sorcery
(),
"endpoint"
,
AST_RETRIEVE_FLAG_MULTIPLE
|
AST_RETRIEVE_FLAG_ALL
,
NULL
);
if
(
!
endpoints
)
{
return
;
}
...
...
@@ -902,12 +932,12 @@ static void create_mwi_subscriptions(void)
* and resubscribing, up-to-date mailbox state will be sent out to the endpoint when the
* new stasis subscription is established
*/
if
(
old_mwi_subscriptions
)
{
ao2_callback
(
old_mwi_subscriptions
,
OBJ_UNLINK
|
OBJ_NODATA
|
OBJ_MULTIPLE
,
unsubscribe
,
NULL
);
}
ao2_
callback
(
endpoints
,
OBJ_NODATA
,
create_mwi_subscriptions_for_endpoint
,
mwi_subscriptions
);
ao2_global_obj_replace_unref
(
unsolicited_mwi
,
mwi_subscriptions
);
ao2_ref
(
mwi_subscription
s
,
-
1
);
ao2_lock
(
unsolicited_mwi
);
ao2_callback
(
unsolicited_mwi
,
OBJ_NOLOCK
|
OBJ_UNLINK
|
OBJ_NODATA
|
OBJ_MULTIPLE
,
unsubscribe
,
NULL
);
ao2_callback
(
endpoints
,
OBJ_NODATA
,
create_mwi_subscriptions_for_endpoint
,
NULL
);
ao2_
unlock
(
unsolicited_mwi
);
ao2_ref
(
endpoint
s
,
-
1
);
}
/*! \brief Function called to send MWI NOTIFY on any unsolicited mailboxes relating to this AOR */
...
...
@@ -927,40 +957,56 @@ static int send_contact_notify(void *obj, void *arg, int flags)
return
0
;
}
/*! \brief Function called when a contact is created or updated */
static
void
mwi_contact_changed_observer
(
const
void
*
object
)
/*! \brief Function called when a contact is updated */
static
void
mwi_contact_updated
(
const
void
*
object
)
{
char
*
id
=
ast_strdupa
(
ast_sorcery_object_get_id
(
object
)),
*
aor
=
NULL
;
struct
ao2_container
*
mwi_subscriptions
=
ao2_global_obj_ref
(
unsolicited_mwi
);
if
(
!
mwi_subscriptions
)
{
aor
=
strsep
(
&
id
,
";@"
);
ao2_callback
(
unsolicited_mwi
,
OBJ_NODATA
,
send_contact_notify
,
aor
);
}
/*! \brief Function called when a contact is added */
static
void
mwi_contact_added
(
const
void
*
object
)
{
const
struct
ast_sip_contact
*
contact
=
object
;
struct
ao2_iterator
*
mwi_subs
;
struct
mwi_subscription
*
mwi_sub
;
const
char
*
endpoint_id
=
ast_sorcery_object_get_id
(
contact
->
endpoint
);
if
(
ast_strlen_zero
(
contact
->
endpoint
->
subscription
.
mwi
.
mailboxes
))
{
return
;
}
aor
=
strsep
(
&
id
,
";@"
);
ao2_lock
(
unsolicited_mwi
);
mwi_subs
=
ao2_find
(
unsolicited_mwi
,
endpoint_id
,
OBJ_SEARCH_KEY
|
OBJ_MULTIPLE
|
OBJ_NOLOCK
|
OBJ_UNLINK
);
ao2_callback
(
mwi_subscriptions
,
OBJ_NODATA
,
send_contact_notify
,
aor
);
ao2_ref
(
mwi_subscriptions
,
-
1
);
if
(
mwi_subs
)
{
for
(;
(
mwi_sub
=
ao2_iterator_next
(
mwi_subs
));
ao2_cleanup
(
mwi_sub
))
{
unsubscribe
(
mwi_sub
,
NULL
,
0
);
}
ao2_iterator_destroy
(
mwi_subs
);
}
create_mwi_subscriptions_for_endpoint
(
contact
->
endpoint
,
NULL
,
0
);
ao2_unlock
(
unsolicited_mwi
);
mwi_contact_updated
(
object
);
}
/*! \brief Observer for contacts so unsolicited MWI is sent when a contact changes */
static
const
struct
ast_sorcery_observer
mwi_contact_observer
=
{
.
created
=
mwi_contact_
changed_observer
,
.
updated
=
mwi_contact_
changed_observer
,
.
created
=
mwi_contact_
added
,
.
updated
=
mwi_contact_
updated
,
};
/*! \brief Task invoked to send initial MWI NOTIFY for unsolicited */
static
int
send_initial_notify_all
(
void
*
obj
)
{
struct
ao2_container
*
mwi_subscriptions
=
ao2_global_obj_ref
(
unsolicited_mwi
);
if
(
!
mwi_subscriptions
)
{
return
0
;
}
ao2_callback
(
mwi_subscriptions
,
OBJ_NODATA
,
send_notify
,
NULL
);
ao2_ref
(
mwi_subscriptions
,
-
1
);
ao2_callback
(
unsolicited_mwi
,
OBJ_NODATA
,
send_notify
,
NULL
);
return
0
;
}
...
...
@@ -1000,6 +1046,13 @@ static int load_module(void)
if
(
ast_sip_register_subscription_handler
(
&
mwi_handler
))
{
return
AST_MODULE_LOAD_DECLINE
;
}
unsolicited_mwi
=
ao2_container_alloc
(
MWI_BUCKETS
,
mwi_sub_hash
,
mwi_sub_cmp
);
if
(
!
unsolicited_mwi
)
{
ast_sip_unregister_subscription_handler
(
&
mwi_handler
);
return
AST_MODULE_LOAD_DECLINE
;
}
create_mwi_subscriptions
();
ast_sorcery_observer_add
(
ast_sip_get_sorcery
(),
"contact"
,
&
mwi_contact_observer
);
...
...
@@ -1014,12 +1067,9 @@ static int load_module(void)
static
int
unload_module
(
void
)
{
RAII_VAR
(
struct
ao2_container
*
,
mwi_subscriptions
,
ao2_global_obj_ref
(
unsolicited_mwi
),
ao2_cleanup
);
if
(
mwi_subscriptions
)
{
ao2_callback
(
mwi_subscriptions
,
OBJ_UNLINK
|
OBJ_NODATA
|
OBJ_MULTIPLE
,
unsubscribe
,
NULL
);
ao2_global_obj_release
(
unsolicited_mwi
);
ast_sorcery_observer_remove
(
ast_sip_get_sorcery
(),
"contact"
,
&
mwi_contact_observer
);
}
ao2_callback
(
unsolicited_mwi
,
OBJ_UNLINK
|
OBJ_NODATA
|
OBJ_MULTIPLE
,
unsubscribe
,
NULL
);
ao2_ref
(
unsolicited_mwi
,
-
1
);
ast_sorcery_observer_remove
(
ast_sip_get_sorcery
(),
"contact"
,
&
mwi_contact_observer
);
ast_sip_unregister_subscription_handler
(
&
mwi_handler
);
return
0
;
}
...
...
This diff is collapsed.
Click to expand it.
res/res_pjsip_registrar.c
+
1
−
1
View file @
3f1fe836
...
...
@@ -500,7 +500,7 @@ static int rx_task(void *data)
if
(
ast_sip_location_add_contact
(
task_data
->
aor
,
contact_uri
,
ast_tvadd
(
ast_tvnow
(),
ast_samp2tv
(
expiration
,
1
)),
path_str
?
ast_str_buffer
(
path_str
)
:
NULL
,
user_agent
))
{
user_agent
,
task_data
->
endpoint
))
{
ast_log
(
LOG_ERROR
,
"Unable to bind contact '%s' to AOR '%s'
\n
"
,
contact_uri
,
aor_name
);
continue
;
...
...
This diff is collapsed.
Click to expand it.
Preview
0%
Loading
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Save comment
Cancel
Please
register
or
sign in
to comment