Skip to end of metadata
Go to start of metadata

As explained on the parent page, the current pubsub API in res_pjsip_pubsub does not abstract away the underlying PJSIP implementation. This page details the current problems and how they should be fixed.

Tweaks to ast_sip_subscription

ast_sip_subscription currently assumes that all subscriptions align with an actual SUBSCRIBE dialog within PJSIP, like the following:

simple_subscription

With RLS, ast_sip_subscription needs to be able to form a tree of subscriptions, with a "real" list subscription at the root of the tree and "virtual" leaf subscriptions, like the following:

complex_sip_subscriptions

Subscription handlers may no longer be able to directly send NOTIFYs on one of their ast_sip_subscriptions because the subscription does not directly correlate to a real SIP subscription. This means that anything the subscription handlers were doing previously where they would reach across the res_pjsip_pubsub layer into PJSIP will no longer be valid.

Internal changes

There will be many internal changes that get made as part of RLS work, but the only change that needs to be made is to alter the ast_sip_subscription structure so it may more easily conform to the drawing above.

The following will need to be removed from the ast_list_subscription structure:

With the division between real and virtual subscriptions, it makes no sense for virtual subscriptions to have a pointer to a pjsip_evsub. Instead, having a pointer to the parent subscription makes much more sense. Real subscriptions should still have a pointer to the PJSIP subscription, though. A union works well for this. Given the tree-like structure of ast_sip_subscription, appropriate fields need to be added to support this. As a final change, since users of the pubsub API will need access to the data, the name of the subscribed resource will need to be added to the structure.

General API changes

The biggest removals from the API are the following:

Those two functions assume that the subscription has a corresponding PJSIP subscription. However, users of the pubsub API can no longer make such an assumption since the subscription they interact with may be virtual. The main uses of these two functions by subscription handlers were as follows:

  • Getting the pjsip_evsub in order to transmit a NOTIFY request.
  • Getting the pjsip_evsub in order to accept an inbound SUBSCRIBE request.
  • Getting the pjsip_evsub to get the current subscription state.
  • Getting the pjsip_evsub to terminate a subscription on an inbound SUBSCRIBE request.
  • Getting the pjsip_dialog to get local and remote information.

In order to satisfy previously-required functionality, new calls will be added to the pubsub API to replace the old functionality. Each of these API calls, when initially written, will propagate up the tree of subscriptions, resulting in similar operations to what were previously being done.

You'll notice that there is no function to get the current subscription state. This is because state can be determined by the core pubsub API in most cases or can be determined based on the operation being performed. For instance, if ast_sip_subscription_terminate is called by a notifier, then the pubsub core will rightly set the subscription state as "terminated".

Subscriber-side API additions will be required in addition, but those changes are being saved for the larger-scale Outbound Subscriptions task to be accomplished later.

Changes to notifier usage

The ast_sip_subscription_handler structure will also need to be altered to rid itself of PJSIP-specific structures. Specifically, the following callbacks will need to be altered:

All of these currently contain a pjsip_rx_data structure as a parameter. A notifier no longer can can operate on a pjsip_rx_data structure since the subscription as a whole may not pertain to the list member that the notifier is handling. In practice, a notifier should never need an entire SIP request to operate on; they care about the resource that is being subscribed to. Given that notifiers will not be directly responding to SIP requests, it means that the API can be made easier to use for notifiers. Also, since edits are being made in this area, a long-standing personal desire to separate subscribers and notifiers can be done here.

The biggest change is the one being made to the new_subscribe callback. Previously, this callback required the notifier to respond to the SIP SUBSCRIBE, then create an ast_sip_subscription structure, send an initial NOTIFY request, and then return the created ast_sip_subscription. The callback has been simplified greatly. Now, the notifier returns a response code for the pubsub core to send in response to the SUBSCRIBE request. If the response is a 200-class response, then the pubsub core will create the ast_sip_subscription itself, then immediately call back into the notifier with the notify_required callback in order to send the initial NOTIFY. At first, this appears to give a disadvantage over the previous version since the notifier will not have access to the ast_sip_subscription structure in the new_subscribe callback. However, since the notify_required callback is guranteed to be immediately called into with AST_SIP_SUBSCRIPTION_NOTIFY_REASON_STARTED as the reason, the notifier can use that opportunity to do anything that requires the subscription, such as setting up the underlying stasis subscription or adding datastores.

The notify_required callback tells the notifier that it needs to generate a NOTIFY. The reason lets the notifier know why the NOTIFY is needed. Because one of the reasons is AST_SIP_SUBSCRIPTION_NOTIFY_REASON_TERMINATED there is no reason to have a separate subscription_terminated callback for notifiers.

Note that the old notify_response callback is completely gone now. Notifiers do not have any need to know what the response to their NOTIFY was. The pubsub core can handle off-nominal paths, to include asking the notifier to try sending again or terminating the subscription.

Changes to subscriber usage

More in-depth subscriber usage changes may happen at a later date; however, a prerequisite is to make sure that inadequate subscriber callbacks in the ast_sip_subscription_handler structure are abstracted. The old subscriber-specific callbacks need to be converted not to use PJSIP-specific structures. Here are the parts that need conversion:

Here is the revised version:

ast_sip_create_subscription is now only used by subscribers; notifiers have no need to create subscriptions themselves. As such, in addition to creating the ast_sip_subscription structure, it will also send out the initial SUBSCRIBE request to the specified resource at the specified endpoint.

As was noted with notifiers earlier, ast_sip_subscription_handler is being replaced by separate notifier and subscriber structures. The subscriber structure has a few major changes. refresh_subscription has been removed since the pubsub core will handle it. notify_request has been altered to be state_change now. Instead of being given the entire NOTIFY request, the subscriber is given the relevant body from the NOTIFY request as well as the subscription state. If the state is PJSIP_EVSUB_STATE_TERMINATED then the subscriber can know that the subscription has been terminated. Because of this, there is no need for a subscription_terminated callback.

Changes to publish handler usage

Publisher changes are similar to notifier changes. Here are the areas where publication handling needs to be altered:

Here is the revised edition:

Like with the notifier, the new_publication callback is being simplified just to be an indicator if the PUBLISH should be accepted or not. The pubsub core will take care of creating the publication and will then immediately call into the publication_state_change callback to relay the actual PUBLISH body to the handler. publish_refresh and publish_termination are not needed since the publication_state_change covers their functionality.

  • No labels