Skip to content
GitLab
Explore
Sign in
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
10b36298
Commit
10b36298
authored
10 years ago
by
Mark Michelson
Committed by
Gerrit Code Review
10 years ago
Browse files
Options
Downloads
Plain Diff
Merge "res_pjsip_mwi: Send unsolicited MWI NOTIFY on startup and when endpoint registers."
parents
46950d69
190fa4f3
Branches
Branches containing commit
Tags
Tags containing commit
No related merge requests found
Changes
1
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
res/res_pjsip_mwi.c
+115
-6
115 additions, 6 deletions
res/res_pjsip_mwi.c
with
115 additions
and
6 deletions
res/res_pjsip_mwi.c
+
115
−
6
View file @
10b36298
...
...
@@ -100,12 +100,14 @@ struct mwi_stasis_subscription {
*/
struct
mwi_subscription
{
/*! Container of \ref mwi_stasis_subscription structures.
* A single MWI subscription may be for
e
multiple mailboxes, thus
* A single MWI subscription may be for multiple mailboxes, thus
* requiring multiple stasis subscriptions
*/
struct
ao2_container
*
stasis_subs
;
/*! The SIP subscription. Unsolicited MWI does not use this */
struct
ast_sip_subscription
*
sip_sub
;
/*! AORs we should react to for unsolicited MWI NOTIFY */
char
*
aors
;
/*! Is the MWI solicited (i.e. Initiated with an external SUBSCRIBE) ? */
unsigned
int
is_solicited
;
/*! Identifier for the subscription.
...
...
@@ -196,6 +198,7 @@ static void mwi_subscription_destructor(void *obj)
ast_debug
(
3
,
"Destroying MWI subscription for endpoint %s
\n
"
,
sub
->
id
);
ao2_cleanup
(
sub
->
sip_sub
);
ao2_cleanup
(
sub
->
stasis_subs
);
ast_free
(
sub
->
aors
);
}
static
struct
mwi_subscription
*
mwi_subscription_alloc
(
struct
ast_sip_endpoint
*
endpoint
,
...
...
@@ -232,6 +235,14 @@ static struct mwi_subscription *mwi_subscription_alloc(struct ast_sip_endpoint *
}
sub
->
is_solicited
=
is_solicited
;
if
(
!
is_solicited
&&
!
ast_strlen_zero
(
endpoint
->
aors
))
{
sub
->
aors
=
ast_strdup
(
endpoint
->
aors
);
if
(
!
sub
->
aors
)
{
ao2_ref
(
sub
,
-
1
);
return
NULL
;
}
}
ast_debug
(
3
,
"Created %s MWI subscription for endpoint %s
\n
"
,
is_solicited
?
"solicited"
:
"unsolicited"
,
sub
->
id
);
return
sub
;
...
...
@@ -796,21 +807,32 @@ static int serialized_cleanup(void *userdata)
return
0
;
}
static
int
send_notify
(
void
*
obj
,
void
*
arg
,
int
flags
)
{
struct
mwi_subscription
*
mwi_sub
=
obj
;
struct
ast_taskprocessor
*
serializer
=
mwi_sub
->
is_solicited
?
ast_sip_subscription_get_serializer
(
mwi_sub
->
sip_sub
)
:
NULL
;
if
(
ast_sip_push_task
(
serializer
,
serialized_notify
,
ao2_bump
(
mwi_sub
)))
{
ao2_ref
(
mwi_sub
,
-
1
);
}
return
0
;
}
static
void
mwi_stasis_cb
(
void
*
userdata
,
struct
stasis_subscription
*
sub
,
struct
stasis_message
*
msg
)
{
struct
mwi_subscription
*
mwi_sub
=
userdata
;
if
(
stasis_subscription_final_message
(
sub
,
msg
))
{
ao2_ref
(
mwi_sub
,
+
1
);
ast_sip_push_task
(
NULL
,
serialized_cleanup
,
mwi_sub
);
if
(
ast_sip_push_task
(
NULL
,
serialized_cleanup
,
ao2_bump
(
mwi_sub
)))
{
ao2_ref
(
mwi_sub
,
-
1
);
}
return
;
}
if
(
ast_mwi_state_type
()
==
stasis_message_type
(
msg
))
{
struct
ast_taskprocessor
*
serializer
=
mwi_sub
->
is_solicited
?
ast_sip_subscription_get_serializer
(
mwi_sub
->
sip_sub
)
:
NULL
;
ao2_ref
(
mwi_sub
,
+
1
);
ast_sip_push_task
(
serializer
,
serialized_notify
,
mwi_sub
);
send_notify
(
mwi_sub
,
NULL
,
0
);
}
}
...
...
@@ -858,6 +880,7 @@ static int unsubscribe(void *obj, void *arg, int flags)
struct
mwi_subscription
*
mwi_sub
=
obj
;
ao2_callback
(
mwi_sub
->
stasis_subs
,
OBJ_UNLINK
|
OBJ_NODATA
|
OBJ_MULTIPLE
,
unsubscribe_stasis
,
NULL
);
return
CMP_MATCH
;
}
...
...
@@ -887,6 +910,83 @@ static void create_mwi_subscriptions(void)
ao2_ref
(
mwi_subscriptions
,
-
1
);
}
/*! \brief Function called to send MWI NOTIFY on any unsolicited mailboxes relating to this AOR */
static
int
send_contact_notify
(
void
*
obj
,
void
*
arg
,
int
flags
)
{
struct
mwi_subscription
*
mwi_sub
=
obj
;
const
char
*
aor
=
arg
;
if
(
!
mwi_sub
->
aors
||
!
strstr
(
mwi_sub
->
aors
,
aor
))
{
return
0
;
}
if
(
ast_sip_push_task
(
NULL
,
serialized_notify
,
ao2_bump
(
mwi_sub
)))
{
ao2_ref
(
mwi_sub
,
-
1
);
}
return
0
;
}
/*! \brief Function called when a contact is created or updated */
static
void
mwi_contact_changed_observer
(
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
)
{
return
;
}
aor
=
strsep
(
&
id
,
";@"
);
ao2_callback
(
mwi_subscriptions
,
OBJ_NODATA
,
send_contact_notify
,
aor
);
ao2_ref
(
mwi_subscriptions
,
-
1
);
}
/*! \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
,
};
/*! \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
);
return
0
;
}
/*! \brief Event callback which fires initial unsolicited MWI NOTIFY messages when we're fully booted */
static
void
mwi_startup_event_cb
(
void
*
data
,
struct
stasis_subscription
*
sub
,
struct
stasis_message
*
message
)
{
struct
ast_json_payload
*
payload
;
const
char
*
type
;
if
(
stasis_message_type
(
message
)
!=
ast_manager_get_generic_type
())
{
return
;
}
payload
=
stasis_message_data
(
message
);
type
=
ast_json_string_get
(
ast_json_object_get
(
payload
->
json
,
"type"
));
if
(
strcmp
(
type
,
"FullyBooted"
))
{
return
;
}
ast_sip_push_task
(
NULL
,
send_initial_notify_all
,
NULL
);
stasis_unsubscribe
(
sub
);
}
static
int
reload
(
void
)
{
create_mwi_subscriptions
();
...
...
@@ -901,6 +1001,14 @@ static int load_module(void)
return
AST_MODULE_LOAD_DECLINE
;
}
create_mwi_subscriptions
();
ast_sorcery_observer_add
(
ast_sip_get_sorcery
(),
"contact"
,
&
mwi_contact_observer
);
if
(
ast_test_flag
(
&
ast_options
,
AST_OPT_FLAG_FULLY_BOOTED
))
{
ast_sip_push_task
(
NULL
,
send_initial_notify_all
,
NULL
);
}
else
{
stasis_subscribe_pool
(
ast_manager_get_topic
(),
mwi_startup_event_cb
,
NULL
);
}
return
AST_MODULE_LOAD_SUCCESS
;
}
...
...
@@ -910,6 +1018,7 @@ static int unload_module(void)
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
);
}
ast_sip_unregister_subscription_handler
(
&
mwi_handler
);
return
0
;
...
...
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