On Wed, Nov 9, 2022 at 11:38 AM <aster...@phreaknet.org> wrote: > On 10/21/2022 7:53 AM, Joshua C. Colp wrote: > > On Fri, Oct 21, 2022 at 8:29 AM <aster...@phreaknet.org > > <mailto:aster...@phreaknet.org>> wrote: > > > > On 10/21/2022 5:34 AM, Joshua C. Colp wrote: > > > On Thu, Oct 20, 2022 at 8:23 PM <aster...@phreaknet.org > > <mailto:aster...@phreaknet.org> > > > <mailto:aster...@phreaknet.org <mailto:aster...@phreaknet.org>>> > > wrote: > > > > > > Hi, all, > > > > > > Something I have been working on recently is adding > > support to > > > PJSIP for device feature key synchronization (the > > as-feature-event > > > Broadworks spec that many common IP phones, e.g. Polycom > > support) to > > > control server-side features from endpoints. It's using the > > PJSIP > > > pub/sub capabilities; I had to add the ability to execute a > > custom > > > module callback when a SUBSCRIBE is refreshed, but with that > > > addition, > > > it works as it's supposed to. > > > > > > > > > You should further elaborate on all of the server-side features you > > > expect to implement, if it extends beyond DND. > > > > The other one is Call Forwarding (Always/Busy/No Answer, with > > number of > > rings) > > > > > > > > I wanted to solicit some input on what an ideal way of > > triggering > > > updates should be. Currently we have hints, which actually work > > > reasonably all right for Do Not Disturb, which is simply a > > boolean > > > on/off, easily represented with a hint and custom device > > state for > > > DND. > > > The PJSIP module emits an AMI event, the user can process it > and > > > change > > > the device state if needed, which will trigger a NOTIFY to > > go out > > > to the > > > endpoint. > > > > > > > > > What user? An outside AMI application? An internal consumer in > > Asterisk? > > > > The administrator of the Asterisk system, who can add AMI logic to > > receive the event and then do something with it. > > The reason this is needed is the phone isn't turning DND on directly, > > for example. It's merely a request. The server can decide to not > > allow > > it, for example if that phone isn't allowed to toggle DND. The server > > will process it, and send it the updated status. This usually > > reflects > > what the phone wanted, but not necessarily. > > (I've elaborated on this more below) > > > > > > Okay, that's not the administrator of an Asterisk system. That's a > > developer using Asterisk who may be the administrator. Those are two > > separate things. As soon as you bring AMI into the mix then it's > > making a solution using Asterisk. That's not a wrong thing, but it's > > important to be clear in the audience. Many average users of Asterisk > > doesn't know or care about AMI, 'nor do they code for it. They may use > > additional solutions that utilize AMI but they themselves haven't the > > foggiest of the details. > > > > > > > > > > This sort of came up about 12 years ago[1]. The actual SIP > stuff > > > is not > > > complicated; it's the user interface to it that requires more > > > thought. > > > For call forwarding, there are more moving pieces and abusing > > > hints/custom device state for that is super clunky. You can't > > > communicate the call forwarding target, # of rings, etc. in > > a device > > > state, so additional hints are then needed for that. It > > works but > > > it's > > > super clunky and I don't think this is a great pipeline. > > > > > > > > > Okay, so this covers call forwarding as well. > > Yes. > > > > > > > > > I'm wondering if people have thoughts on what an ideal > mechanism > > > would > > > be for users, once they process a request to enable/disable > > a feature > > > from the phone, to communicate that to the PJSIP module. The > > problem > > > with abusing hints, especially for call forwarding, is it's > > not a > > > good > > > way to communicate details into the module. One option > > perhaps is to > > > have dialplan extensions, setup in a manner similar to use with > > > EVAL_EXTEN, where it returns the current value needed, as any > > > relevant > > > function, DB, ODBC, CURL, custom function, etc. could be used > to > > > retrieve the current feature value. The clunky part is more > > > signaling to > > > the PJSIP module that it needs to send the phone the updated > > > status (by > > > checking those extensions, for example). The device state > > callback > > > happens to be convenient for this kind of signaling but not > > really > > > appropriate here. It would be better to push the info into > > the module > > > directly rather than the signaling it and making it retrieve > the > > > updated > > > data in some arbitrary way. > > > > > > So with this in mind, I'm currently leaning in the direction > > of a > > > dialplan function/AMI action that could be used to set the > > > appropriate > > > info for a subscription, which would trigger the NOTIFY, and > > then > > > nothing would actually need to be added to the dialplan at all > > > (inasmuch > > > as hints and things of that nature). One d I think starting > > purely > > > from that perspective > > > > > > isadvantage of this is that > > > for every single update, unlike callbacks, we have to > > traverse the > > > entire list of subscriptions (though maybe that's not a big > > deal). > > > The > > > bigger problem is this is push only and the PJSIP module still > > > needs to > > > be able to "pull" feature statuses on demand, which is where > the > > > hint/lookup model is useful. A potential middle ground > > solution is > > > use > > > the dialplan function/AMI action to push only, but cache all of > > > this in > > > AstDB (as subscriptions themselves are), so that we can > > retrieve the > > > latest/most current value at any point if needed. Then we don't > > > need to > > > be concerned at all with how the user is managing state as > > that is > > > fully > > > decoupled, although obviously this would lead to a little > > > duplication/redundancy. Any thoughts? > > > > > > > > > You've thrown a lot of lower level implementation details at us > > and to > > > be quite honest it's overwhelming. There's no full user facing > > > examples of how it would all work, beyond the bits and pieces in > > your > > > text that we'd then have to deduce and after reading a few times it > > > doesn't feel very friendly. To start off with: Is this a > > developer API > > > and interface, or is this also meant for the common everyday > > user? I > > > would hope it's for the common everyday user, in which case it > > should > > > be approached from that perspective first with implementation > > details > > > following. > > > > Yes, it's for the common every day end user. A callback mechanism if > > used would be more of a development one but that would be more a > > means > > to an end. > > > > Here's an example of what I have in my dialplan right now, in the > > subscribe_context for the endpoint: > > exten => dnd_Polycom5,hint,Custom:${EXTEN} > > exten => callfwd_Polycom5,hint,Custom:${EXTEN} > > exten => callfwdalways_Polycom5,1,${FOOBAR(callforward,2135)} > > exten => callfwdbusy_Polycom5,1,${FOOBAR(callforwardbusy,2135)} > > exten => > > callfwdnoanswer_Polycom5,1,${FOOBAR(callforwardnoanswer,2135)} > > > > The user gets the AMI event, processes it with whatever processing is > > needed (e.g. checking that the DND feature is available for that > > line, > > setting it in AstDB, ODBC, or whatever is the source of truth for > > feature statuses), and then updates the relevant hints above. > > > > The module is currently hardcoded to use these extensions in the > > subscribe context: the prefix + the endpoint name. Obviously > > that's also > > inflexible. > > Right now, the first 2 extensions the user will set to signal the > > module > > to send an updated NOTIFY. The first hint by virtue of being binary > > contains the DND status itself, and the 3 bottom extensions are > > needed > > to retrieve the call forwarding numbers from the source of truth for > > these features. (Here, FOOBAR is a custom - but any arbitrary - > > dialplan > > function I have that retrieves the status). > > > > I bring this up only to show the current implementation and how > > hacky it > > is; I don't like this at all or think it's appropriate (except for > > DND, > > possibly). It was more a proof of concept of testing the > > underlying SIP > > technology. > > > > A better implementation might look like: > > > > User gets the AMI event and processes it as usual, and then simply > > does > > Set(PJSIP_DEVICE_FEATURE_STATE(PJSIP/Polycom1,donotdisturb)=enabled) > > or > > > > Set(PJSIP_DEVICE_FEATURE_STATE(PJSIP/Polycom1,callforwardingnoanswer)=8675309,4) > > > > (forward on no answer to 8675309 after 4 rings). > > > > Internally, PJSIP_DEVICE_FEATURE_STATE could also persist input to > > AstDB > > so it's available to the module. > > > > > As an everyday user I'd expect not to have to deal with AMI or > > complex > > > dialplan. I'd expect to be able to set and get the information from > > > the dialplan using dialplan functions (or a single function) so I > > > could use that in the dialplan, and have it "just work" with my > > phones > > > that support the feature. I'd expect it to persist across Asterisk > > > restarts. For example ${EXTENSION_DND(alice)} for retrieving DND > > > status of Alice, and if Asterisk restarted then that should stay > > the same. > > > > That's a good point. The problem is that means that Asterisk > > internally > > is the source of truth of DND, and that may not necessarily be what > > people want. For instance, that wouldn't meet my own requirements. > > The > > way that Broadworks works is the phone is merely requesting a certain > > disposition, but the server isn't under any obligation to carry it > > out. > > So I think there needs to be some mechanism for the user to be > > involved > > in that pipeline, to be able to deny something that a phone wants. > > Maybe > > the user doesn't have DND, maybe certain phones aren't allowed to > > toggle, whatever. Lots of people store their feature states in MySQL > > databases and use them for Asterisk clusters. Some systems might have > > specific requirements for that. So users should have flexibility to > > reject it. On some systems, maybe the same DND status is used for > > several lines and Asterisk internally would not have any idea > > about this. > > There are lots of different scenarios that are beyond what I think > > Asterisk itself should handle, hence the "two-part" process described > > above: the user (system admin) can do whatever needs to be done, and > > then just tell PJSIP what the new state is. PJSIP doesn't need to > > know > > or care about where feature states are actually stored or what the > > logic > > is or how they are mapped to endpoints. > > > > I do see your point though and I think it would be nice to have a > > "simple, default mode" where Asterisk will internally just "approve > > everything" that the phone wants, and users can use that if that > > suits > > their needs, but fundamentally I think users should be able to be > > involved in the decision pipeline if they want/need to. I'm not > > yet sure > > what that would look like: maybe a pjsip.conf option to emit AMI > > events > > rather than auto-handling them? And then the > > PJSIP_DEVICE_FEATURE_STATE > > function would have to be used to tell PJSIP what to do, and Asterisk > > itself would not be the source of truth for feature statuses in this > > case (but it would cache them as described above) (though in this > > case > > reading the PJSIP_DEVICE_FEATURE_STATE could still return the cached > > disposition) > > > > > > Okay, YOUR usage is based on an API interface for developers to allow > > external source of truth and logic. That's what it is. My response did > > not approach it from that perspective. > > > > I don't have thoughts on that aspect currently. It requires more time. > > The new architecture proposed (not using hints) has been working pretty > well for a few weeks. I'm using it in the more "developer" mode but the > other mode exists as well. The last hurdle is being able to send a > multipart XML response when necessary, since if more than one feature > needs to be sent to the device, the Broadworks spec outlines a multipart > response devices will accept. > > Right now I'm using a body_generator module in order to generate the > actual content for the NOTIFY, similar to how res_pjsip_exten_state and > res_pjsip_mwi do things. However the body generator only gets a pointer > to an ast_str, so there's no way for it to do anything PJSIP related > like multipart. I was thinking that one elegant option would be to have > a separate body generator for each of the features, and then > res_pjsip_pubsub would handle creating the multipart body. > > There is some stuff in res_pjsip_pubsub currently to handle multipart > subscriptions, for subscriptions that have "children". The individual > features are not "child subscriptions" in the right sense, but if they > were, then it might work within the constraints of the pubsub interface. > However, I know you suggested it would be preferable to handle any > multipart stuff in the module itself using the PJSIP multipart APIs, as > opposed to changing anything in res_pjsip_pubsub. > > Looking at the existing support for multipart in res_pjsip_pubsub, it > seems this is limited to subscriptions as discussed in RFC 4662, which > require a "Supported: eventlist" header in them, even if you define a > resource list in pjsip.conf. The Broadworks device feature sync > subscriptions do not include such a header in the SUBSCRIBE. So, the > subscription in question seems to be a single, childless subscription, > that nonetheless needs to send a multipart response, potentially. > > So, a couple questions, assuming my understanding of the above is correct: > > * Since it doesn't appear that res_pjsip_pubsub currently supports > multipart in the way that's needed here, do you think there's any > approach we could take that retains being able to use body generator > modules? I don't see how we can, unless res_pjsip_pubsub itself > supported it. The support it has is close, but not really what it > would need to be. Would it be reasonable to extend such > functionality to support this kind of subscription? i.e. not require > "Supported: eventlist" in order to be considered a resource list? > * Alternately, if we didn't want to modify res_pjsip_pubsub to support > this unconventional usage, perhaps the module itself could directly > add some "dummy" child subscriptions to itself, one for each > feature, so that one body generator could then be used for each of > them. ast_sip_subscription is an opaque structure though, so this > would require breaking some abstraction and using the internals of > ast_sip_subscription in the module, in order to be able to add > children to it. > * Assuming we don't want to do anything with pubsub children, would it > be fine/preferred to ditch the body generator altogether and do > everything in a single module? It just feels a bit clunkier this > way, since it'll likely duplicate a lot of what res_pjsip_pubsub is > doing internally for building NOTIFYs, in fact this would likely > require bypassing much of what res_pjsip_pubsub does in order to > generate the entire response itself. > * Is it even worth trying to support multipart responses for non > resource list subscriptions? Would sending up to 4 NOTIFYs instead > of a single multipart one be an "acceptable kludge", given the > requirements of res_pjsip_pubsub? > > All of the approaches listed seem a bit hacky to me, though in different > ways. Wondering if you think a particular approach is more promising > than the others... >
I don't have any further input, and it is unlikely I will have any for quite some time. I'm also not that familiar with the res_pjsip_pubsub RLS implementation which is what you are referring to and haven't looked at the underlying specification for your Broadsoft stuff. Someone else may have input. -- Joshua C. Colp Asterisk Project Lead Sangoma Technologies Check us out at www.sangoma.com and www.asterisk.org
-- _____________________________________________________________________ -- Bandwidth and Colocation Provided by http://www.api-digital.com -- asterisk-dev mailing list To UNSUBSCRIBE or update options visit: http://lists.digium.com/mailman/listinfo/asterisk-dev