<html>
<head>
    <base href="https://wiki.asterisk.org/wiki">
            <link rel="stylesheet" href="/wiki/s/2033/1/7/_/styles/combined.css?spaceKey=TOP&amp;forWysiwyg=true" type="text/css">
    </head>
<body style="background: white;" bgcolor="white" class="email-body">
<div id="pageContent">
<div id="notificationFormat">
<div class="wiki-content">
<div class="email">
    <h2><a href="https://wiki.asterisk.org/wiki/display/TOP/Subscription+Support">Subscription Support</a></h2>
    <h4>Page <b>edited</b> by             <a href="https://wiki.asterisk.org/wiki/display/~mmichelson">Mark Michelson</a>
    </h4>
        <br/>
                         <h4>Changes (29)</h4>
                                 
    
<div id="page-diffs">
                    <table class="diff" cellpadding="0" cellspacing="0">
    
            <tr><td class="diff-snipped" >...<br></td></tr>
            <tr><td class="diff-unchanged" >This page is a work in progress. <br>{warning} <br></td></tr>
            <tr><td class="diff-deleted-lines" style="color:#999;background-color:#fdd;text-decoration:line-through;"> <br></td></tr>
            <tr><td class="diff-added-lines" style="background-color: #dfd;">h1. Concept <br></td></tr>
            <tr><td class="diff-unchanged" >Subscriptions in AsteriskSCF may come in many flavors. One obvious one would be SIP subscriptions as defined in [RFC 3265|http://www.ietf.org/rfc/rfc3265.txt]. However, subscriptions may be started via other protocols or via administration. Therefore, subscription support needs to be written in such a way that it is protocol-agnostic. While Asterisk SCF needs to be able to understand protocol-specific methods of subscribing to resources, it is not within the scope of Asterisk SCF to make decisions regarding such matters. With this in mind, the majority of session-oriented protocols that support subscriptions of some sort will make use of a listener interface in order to make it known what is happening. <br> <br></td></tr>
            <tr><td class="diff-snipped" >...<br></td></tr>
            <tr><td class="diff-unchanged" >If a subscription is accepted, then the listener that accepted the subscription will notify the Asterisk SCF component responsible for communicating with the subscriber his ID such that any further events regarding the subscription can be directed to the appropriate listener. <br> <br></td></tr>
            <tr><td class="diff-changed-lines" >At the basis of all of this is the subscription itself. There is no such thing as an all-encompassing subscription class since all subscriptions will have data that is specific to the subscription type. However, there are certain attributes present in all subscription <span class="diff-changed-words">types<span class="diff-added-chars"style="background-color: #dfd;">, and they are represented in a SubscriptionData class</span>.</span> <br></td></tr>
            <tr><td class="diff-unchanged" > <br>{newcode:language=slice} <br></td></tr>
            <tr><td class="diff-changed-lines" >class <span class="diff-changed-words">Subscription<span class="diff-added-chars"style="background-color: #dfd;">Data</span></span> <br></td></tr>
            <tr><td class="diff-unchanged" >{ <br>    int expiration; <br>    string addressee; <br>    string sender; <br></td></tr>
            <tr><td class="diff-added-lines" style="background-color: #dfd;">    SubscriptionState state; <br></td></tr>
            <tr><td class="diff-unchanged" >    //XXX To be continued <br>}; <br>{newcode} <br> <br></td></tr>
            <tr><td class="diff-changed-lines" >Note that a subscription type is not listed. This is because specific types of subscriptions should be defined as derivations of the <span class="diff-changed-words">Subscription<span class="diff-added-chars"style="background-color: #dfd;">Data</span></span> class. <br></td></tr>
            <tr><td class="diff-deleted-lines" style="color:#999;background-color:#fdd;text-decoration:line-through;"> <br></td></tr>
            <tr><td class="diff-added-lines" style="background-color: #dfd;">h1. Inbound Subscriptions <br></td></tr>
            <tr><td class="diff-unchanged" >{newcode:language=slice} <br></td></tr>
            <tr><td class="diff-changed-lines" >interface <span class="diff-changed-words"><span class="diff-added-chars"style="background-color: #dfd;">Inbound</span>SubscriptionListener</span> <br></td></tr>
            <tr><td class="diff-unchanged" >{ <br></td></tr>
            <tr><td class="diff-deleted-lines" style="color:#999;background-color:#fdd;text-decoration:line-through;">    bool requested(Subscription sub, out SubscriptionListener Listener); <br>    void renewed(Subscription sub); <br>    void terminated(Subscription sub); <br></td></tr>
            <tr><td class="diff-added-lines" style="background-color: #dfd;">    void requested(InboundSubscription *sub); <br>    void renewed(InboundSubscription *sub); <br>    void terminated(InboundSubscription *sub); <br></td></tr>
            <tr><td class="diff-unchanged" >}; <br>{newcode} <br> <br></td></tr>
            <tr><td class="diff-changed-lines" >This is fairly straightforward. The &quot;requested&quot; method will be called when an entity has requested a subscription to a service and the &quot;terminated&quot; method will be called when an entity ends a subscription. The <span class="diff-deleted-words"style="color:#999;background-color:#fdd;text-decoration:line-through;">out parameter of the &quot;requested&quot; method is in case a different listener than the one that was called into is to handle the subscription. The</span> &quot;renewed&quot; method is called mostly as an informational means to let the listener know that the subscriber has renewed his subscription. <br></td></tr>
            <tr><td class="diff-unchanged" > <br>The listener must also be able to communicate with the subscriber. The means of doing this will be in a subclass of Subscription class, InboundSubscription. <br> <br>{newcode:language=slice} <br></td></tr>
            <tr><td class="diff-deleted-lines" style="color:#999;background-color:#fdd;text-decoration:line-through;">class InboundSubscription extends Subscription <br></td></tr>
            <tr><td class="diff-added-lines" style="background-color: #dfd;">class InboundSubscription <br></td></tr>
            <tr><td class="diff-unchanged" >{ <br></td></tr>
            <tr><td class="diff-deleted-lines" style="color:#999;background-color:#fdd;text-decoration:line-through;">    void accept(); <br></td></tr>
            <tr><td class="diff-added-lines" style="background-color: #dfd;">    void accept(InboundSubscriptionListener *listener); <br></td></tr>
            <tr><td class="diff-unchanged" >    void deny(SubscriptionReason reason); <br>    void terminate(); <br>    void notify(SubscriptionState state); <br></td></tr>
            <tr><td class="diff-added-lines" style="background-color: #dfd;">    void addListeners(InboundSubscriptionListenerSeq listeners); <br>    void removeListeners(InboundSubscriptionListenerSeq listeners); <br>    SubscriptionData data; <br></td></tr>
            <tr><td class="diff-unchanged" >}; <br>{newcode} <br> <br></td></tr>
            <tr><td class="diff-changed-lines" >The &quot;accept&quot; and &quot;reject&quot; methods are used to respond to a subscription request either positively or negatively. The <span class="diff-added-words"style="background-color: #dfd;">&quot;accept&quot; method has an InboundSubscriptionListener parameter that indicates the listener to which the subscriber should send any updates from the subscriber. The</span> &quot;terminate&quot; method is a method for a listener to end a subscription. The &quot;notify&quot; method is used to indicate to the subscriber that the subscription state has been updated. <span class="diff-added-words"style="background-color: #dfd;">&quot;addListeners&quot; and &quot;removeListeners&quot; provides methods by which more components may listen for events on the subscription. The &quot;data&quot; member contains the data pertaining to the subscription.</span> Note the introduction of two new types here. SubscriptionReason is a means of allowing for the listener to notify the subscriber of why his request has been rejected. This can be used by SIP, as an example, to compose the appropriate 4xx or 5xx message in response to the incoming SUBSCRIBE. SubscriptionReason will be a class that will consist of an enum of common reasons a subscription is not allowed (e.g. The addressee cannot be identified, the subscriber is not allowed to subscribe to a particular resource). In addition, there may be subclasses of SubscriptionReason to account for reasons that may pertain to specific types of subscriptions. SubscriptionState is an abstract class whose subclasses will pertain to specific types of subscriptions. These subclasses will likely contain methods such that state can be converted into the format that the subscriber&#39;s protocol will understand. <br></td></tr>
            <tr><td class="diff-deleted-lines" style="color:#999;background-color:#fdd;text-decoration:line-through;"> <br></td></tr>
            <tr><td class="diff-added-lines" style="background-color: #dfd;">h1. Outbound Subscriptions <br></td></tr>
            <tr><td class="diff-unchanged" >What we have so far allows for Asterisk SCF to communicate with an outside subscriber. But what about if an Asterisk SCF component wishes to subscribe to an outside entity? First off, AsteriskSCF will require the ability to take appropriate actions, such as subscribing, as well as renewing and canceling subscriptions. In other words, the items that the subscription listener listens for need to have corresponding actions that Asterisk SCF can itself make. For this, we have another subclass of Subscription, OutboundSubscription. <br> <br>{newcode:language=slice} <br></td></tr>
            <tr><td class="diff-deleted-lines" style="color:#999;background-color:#fdd;text-decoration:line-through;">class OutboundSubscription extends Subscription <br></td></tr>
            <tr><td class="diff-added-lines" style="background-color: #dfd;">class OutboundSubscription <br></td></tr>
            <tr><td class="diff-unchanged" >{ <br></td></tr>
            <tr><td class="diff-deleted-lines" style="color:#999;background-color:#fdd;text-decoration:line-through;">    void request(); <br></td></tr>
            <tr><td class="diff-added-lines" style="background-color: #dfd;">    void request(OutboundSubscriptionListener *listener); <br></td></tr>
            <tr><td class="diff-unchanged" >    void renew(); <br></td></tr>
            <tr><td class="diff-changed-lines" >void <span class="diff-deleted-words"style="color:#999;background-color:#fdd;text-decoration:line-through;">cancel();</span> <span class="diff-added-words"style="background-color: #dfd;">terminate();</span> <br></td></tr>
            <tr><td class="diff-added-lines" style="background-color: #dfd;">    void addListeners(OutboundSubscriptionListenerSeq listeners); <br>    void removeListeners(OutboundSubscriptionListenerSeq listeners); <br>    SubscriptionData data; <br></td></tr>
            <tr><td class="diff-changed-lines" ><span class="diff-deleted-words"style="color:#999;background-color:#fdd;text-decoration:line-through;">}</span> <span class="diff-added-words"style="background-color: #dfd;">};</span> <br></td></tr>
            <tr><td class="diff-unchanged" >{newcode} <br> <br></td></tr>
            <tr><td class="diff-changed-lines" >The &quot;request&quot; method will be used to send an outbound subscription. The &quot;renew&quot; method will be used to renew a previously accepted subscription. The <span class="diff-deleted-words"style="color:#999;background-color:#fdd;text-decoration:line-through;">&quot;cancel&quot;</span> <span class="diff-added-words"style="background-color: #dfd;">&quot;terminate&quot;</span> method is used to end a subscription. <br></td></tr>
            <tr><td class="diff-added-lines" style="background-color: #dfd;">Once a subscription is sent out, Asterisk SCF will need a way of knowing about whether the subscription was accepted or rejected, as well as knowing when changes have been made to the state of the outbound subscription. For this, we have the OutboundSubscriptionListener class. <br> <br>{newcode:language=slice} <br>class OutboundSubscriptionListener <br>{ <br>    void accepted(OutboundSubscription *sub); <br>    void denied(OutboundSubscription *sub, SubscriptionReason reason); <br>    void terminated(OutboundSubscription *sub); <br>    void notified(OutboundSubscription *sub, SubscriptionState state); <br>}; <br>{newcode} <br> <br>As you can see, this is pretty much the passive version of the InboundSubscription items. &quot;accepted&quot; and &quot;denied&quot; are called in order to let Asterisk SCF know if an outbound subscription has been accepted or rejected. Rejection includes a reason why the subscription was rejected. &quot;terminated&quot; is called if the entity to which we are subscribing terminates the subscription. <br>h1. Simple Examples <br>So let&#39;s consider a typical sequence of events: <br> <br>1. Bob sends a SIP SUBSCRIBE to Asterisk SCF for Alice&#39;s presence. <br>2. Asterisk SCF receives the incoming SUBSCRIBE. <br>3. The SIP subscription component recognizes the event type and creates an appropriate SubscriptionData object. Perhaps in this case it is a SipPresenceSubscriptionData object. <br>4. The SIP subscription component places this SubscriptionData object inside an InboundSubscription object. <br>5. The SIP subscription component begins querying its InboundSubscription listeners using the InboundSubscriptionListener::requested() method. <br>6. One of the listeners recognizes that he is responsible for knowing Alice&#39;s presence and thus responds with the InboundSubscription::accept() method. <br>7. The SIP subscription component sends a 200 OK to Bob. <br> <br>At this point, the SIP subscription component has a listener proxy to send updates to if Bob decides to renew or terminate his subscription to Alice&#39;s presence. Meanwhile, the component responsible for reporting Alice&#39;s presence has an InboundSubscription proxy by which it may send state updates or terminate the subscription. This is a simple one-way subscription into Asterisk SCF with no additional listeners. <br> <br>Now let&#39;s modify the situation a bit. In the new situation, a listener doesn&#39;t simply respond with success to the inbound subscription, but rather it sends an outbound subscription out and responds to the inbound subscription based on the success of the outbound one. Steps 1-5 are the same as before. <br> <br>6. One of the listeners creates an OutboundSubscription object with appropriate data set and calls its request() method. <br>7. The SIP subscription component sends an outbound SUBSCRIBE. <br>8. At some point, the SIP subscription component receives a 200 OK for the outbound SUBSCRIBE. <br>9. The SIP subscription component then uses the OutboundSubscriptionListener that was passed in the request() method to call the accepted() method. <br>10. The OutboundSubscriptionListener then calls InboundSubscription::accept(). <br>11. The SIP subscription component sends a 200 OK to Bob. <br> <br>At this point, Asterisk SCF serves as a subscription bridge, so to speak, between Bob and Alice. Notifications from Alice are intercepted by Asterisk SCF, and they can be sent out to Bob. If Bob, Alice, or Asterisk SCF decides to end the subscriptions, it can be done. <br> <br>h1. Lingering Questions: <br>{warning} <br>Even though I have now started typing potential questions to answer, I need to go through a round of proofreading, etc. of the above proposal. So please don&#39;t answer these yet. <br>{warning} <br>1. In the above example, the SIP component has a preexisting set of InboundSubscriptionListeners to send requests to. Where does this come from? <br>2. Should there be a distinction made between InboundSubscriptionListeners that actually have the ability to make decisions based on an incoming subscription request and those that simply listen passively for events on subscriptions? My initial thought is that to the component calling the listener methods, he&#39;s not really going to care one way or the other, and so a distinction shouldn&#39;t be made. But from the viewpoint of usability and clarity, a distinction may help. <br>3. I&#39;ve constructed these APIs with separate call and response methods as opposed to using two-way methods. Any reason to consider changing this? <br>4. Is having SubscriptionState as a member of SubscriptionData a wise choice? The main use of this as I see it, is that if a listener adds itself to a subscription late, then when given the SubscriptionData, the listener also knows the current state of the subscription. <br>5. I&#39;ve put addListeners() and removeListeners() methods to InboundSubscription and OutboundSubscription, but I don&#39;t know exactly how a new listener is supposed to be able to actually add itself in the first place. How would a potential listener receive the subscription object so that it could add itself as a listener? The only thing I can think of at the moment would be that an IceStorm topic is created such that any established subscriptions would be reported to listeners of the topic, and those who receive events on the topic could then add themselves as listeners to subscriptions. Perhaps such IceStorm listening could be the solution to question 1 as well... <br>6. Are there any suggestions for cosmetic improvement (e.g. class/method name changes)? <br></td></tr>
    
            </table>
    </div>                            <h4>Full Content</h4>
                    <div class="notificationGreySide">
        <div class='panelMacro'><table class='warningMacro'><colgroup><col width='24'><col></colgroup><tr><td valign='top'><img src="/wiki/images/icons/emoticons/forbidden.gif" width="16" height="16" align="absmiddle" alt="" border="0"></td><td><b>Under Construction</b><br />This page is a work in progress.</td></tr></table></div>
<h1><a name="SubscriptionSupport-Concept"></a>Concept</h1>
<p>Subscriptions in AsteriskSCF may come in many flavors. One obvious one would be SIP subscriptions as defined in <a href="http://www.ietf.org/rfc/rfc3265.txt" class="external-link" rel="nofollow">RFC 3265</a>. However, subscriptions may be started via other protocols or via administration. Therefore, subscription support needs to be written in such a way that it is protocol-agnostic. While Asterisk SCF needs to be able to understand protocol-specific methods of subscribing to resources, it is not within the scope of Asterisk SCF to make decisions regarding such matters. With this in mind, the majority of session-oriented protocols that support subscriptions of some sort will make use of a listener interface in order to make it known what is happening.</p>

<p>A typical new subscription request can be seen as such:<br/>
1. Subscription request arrives at Asterisk SCF (SIP SUBSCRIBE would be an example)<br/>
2. The component that receives the subscription request broadcasts the new subscription to listeners.<br/>
3. A listener (or more than one?) can process the details of the subscription and decide what action to take.<br/>
4. The listener (or perhaps another entity that the listener has handed responsibility to) tells the original component how to respond.</p>

<p>If a subscription is accepted, then the listener that accepted the subscription will notify the Asterisk SCF component responsible for communicating with the subscriber his ID such that any further events regarding the subscription can be directed to the appropriate listener.</p>

<p>At the basis of all of this is the subscription itself. There is no such thing as an all-encompassing subscription class since all subscriptions will have data that is specific to the subscription type. However, there are certain attributes present in all subscription types, and they are represented in a SubscriptionData class.</p>

<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<script type="syntaxhighlighter" class="toolbar: false; theme: Confluence; brush: java; gutter: false"><![CDATA[
class SubscriptionData
{
    int expiration;
    string addressee;
    string sender;
    SubscriptionState state;
    //XXX To be continued
};
]]></script>
</div></div>

<p>Note that a subscription type is not listed. This is because specific types of subscriptions should be defined as derivations of the SubscriptionData class.</p>
<h1><a name="SubscriptionSupport-InboundSubscriptions"></a>Inbound Subscriptions</h1>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<script type="syntaxhighlighter" class="toolbar: false; theme: Confluence; brush: java; gutter: false"><![CDATA[
interface InboundSubscriptionListener
{
    void requested(InboundSubscription *sub);
    void renewed(InboundSubscription *sub);
    void terminated(InboundSubscription *sub);
};
]]></script>
</div></div>

<p>This is fairly straightforward. The "requested" method will be called when an entity has requested a subscription to a service and the "terminated" method will be called when an entity ends a subscription. The "renewed" method is called mostly as an informational means to let the listener know that the subscriber has renewed his subscription.</p>

<p>The listener must also be able to communicate with the subscriber. The means of doing this will be in a subclass of Subscription class, InboundSubscription.</p>

<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<script type="syntaxhighlighter" class="toolbar: false; theme: Confluence; brush: java; gutter: false"><![CDATA[
class InboundSubscription
{
    void accept(InboundSubscriptionListener *listener);
    void deny(SubscriptionReason reason);
    void terminate();
    void notify(SubscriptionState state);
    void addListeners(InboundSubscriptionListenerSeq listeners);
    void removeListeners(InboundSubscriptionListenerSeq listeners);
    SubscriptionData data;
};
]]></script>
</div></div>

<p>The "accept" and "reject" methods are used to respond to a subscription request either positively or negatively. The "accept" method has an InboundSubscriptionListener parameter that indicates the listener to which the subscriber should send any updates from the subscriber. The "terminate" method is a method for a listener to end a subscription. The "notify" method is used to indicate to the subscriber that the subscription state has been updated. "addListeners" and "removeListeners" provides methods by which more components may listen for events on the subscription. The "data" member contains the data pertaining to the subscription. Note the introduction of two new types here. SubscriptionReason is a means of allowing for the listener to notify the subscriber of why his request has been rejected. This can be used by SIP, as an example, to compose the appropriate 4xx or 5xx message in response to the incoming SUBSCRIBE. SubscriptionReason will be a class that will consist of an enum of common reasons a subscription is not allowed (e.g. The addressee cannot be identified, the subscriber is not allowed to subscribe to a particular resource). In addition, there may be subclasses of SubscriptionReason to account for reasons that may pertain to specific types of subscriptions. SubscriptionState is an abstract class whose subclasses will pertain to specific types of subscriptions. These subclasses will likely contain methods such that state can be converted into the format that the subscriber's protocol will understand.</p>
<h1><a name="SubscriptionSupport-OutboundSubscriptions"></a>Outbound Subscriptions</h1>
<p>What we have so far allows for Asterisk SCF to communicate with an outside subscriber. But what about if an Asterisk SCF component wishes to subscribe to an outside entity? First off, AsteriskSCF will require the ability to take appropriate actions, such as subscribing, as well as renewing and canceling subscriptions. In other words, the items that the subscription listener listens for need to have corresponding actions that Asterisk SCF can itself make. For this, we have another subclass of Subscription, OutboundSubscription.</p>

<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<script type="syntaxhighlighter" class="toolbar: false; theme: Confluence; brush: java; gutter: false"><![CDATA[
class OutboundSubscription
{
    void request(OutboundSubscriptionListener *listener);
    void renew();
    void terminate();
    void addListeners(OutboundSubscriptionListenerSeq listeners);
    void removeListeners(OutboundSubscriptionListenerSeq listeners);
    SubscriptionData data;
};
]]></script>
</div></div>

<p>The "request" method will be used to send an outbound subscription. The "renew" method will be used to renew a previously accepted subscription. The "terminate" method is used to end a subscription.<br/>
Once a subscription is sent out, Asterisk SCF will need a way of knowing about whether the subscription was accepted or rejected, as well as knowing when changes have been made to the state of the outbound subscription. For this, we have the OutboundSubscriptionListener class.</p>

<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<script type="syntaxhighlighter" class="toolbar: false; theme: Confluence; brush: java; gutter: false"><![CDATA[
class OutboundSubscriptionListener
{
    void accepted(OutboundSubscription *sub);
    void denied(OutboundSubscription *sub, SubscriptionReason reason);
    void terminated(OutboundSubscription *sub);
    void notified(OutboundSubscription *sub, SubscriptionState state);
};
]]></script>
</div></div>

<p>As you can see, this is pretty much the passive version of the InboundSubscription items. "accepted" and "denied" are called in order to let Asterisk SCF know if an outbound subscription has been accepted or rejected. Rejection includes a reason why the subscription was rejected. "terminated" is called if the entity to which we are subscribing terminates the subscription.</p>
<h1><a name="SubscriptionSupport-SimpleExamples"></a>Simple Examples</h1>
<p>So let's consider a typical sequence of events:</p>

<p>1. Bob sends a SIP SUBSCRIBE to Asterisk SCF for Alice's presence.<br/>
2. Asterisk SCF receives the incoming SUBSCRIBE.<br/>
3. The SIP subscription component recognizes the event type and creates an appropriate SubscriptionData object. Perhaps in this case it is a SipPresenceSubscriptionData object.<br/>
4. The SIP subscription component places this SubscriptionData object inside an InboundSubscription object.<br/>
5. The SIP subscription component begins querying its InboundSubscription listeners using the InboundSubscriptionListener::requested() method.<br/>
6. One of the listeners recognizes that he is responsible for knowing Alice's presence and thus responds with the InboundSubscription::accept() method.<br/>
7. The SIP subscription component sends a 200 OK to Bob.</p>

<p>At this point, the SIP subscription component has a listener proxy to send updates to if Bob decides to renew or terminate his subscription to Alice's presence. Meanwhile, the component responsible for reporting Alice's presence has an InboundSubscription proxy by which it may send state updates or terminate the subscription. This is a simple one-way subscription into Asterisk SCF with no additional listeners.</p>

<p>Now let's modify the situation a bit. In the new situation, a listener doesn't simply respond with success to the inbound subscription, but rather it sends an outbound subscription out and responds to the inbound subscription based on the success of the outbound one. Steps 1-5 are the same as before.</p>

<p>6. One of the listeners creates an OutboundSubscription object with appropriate data set and calls its request() method.<br/>
7. The SIP subscription component sends an outbound SUBSCRIBE.<br/>
8. At some point, the SIP subscription component receives a 200 OK for the outbound SUBSCRIBE.<br/>
9. The SIP subscription component then uses the OutboundSubscriptionListener that was passed in the request() method to call the accepted() method.<br/>
10. The OutboundSubscriptionListener then calls InboundSubscription::accept().<br/>
11. The SIP subscription component sends a 200 OK to Bob.</p>

<p>At this point, Asterisk SCF serves as a subscription bridge, so to speak, between Bob and Alice. Notifications from Alice are intercepted by Asterisk SCF, and they can be sent out to Bob. If Bob, Alice, or Asterisk SCF decides to end the subscriptions, it can be done.</p>

<h1><a name="SubscriptionSupport-LingeringQuestions%3A"></a>Lingering Questions:</h1>
<div class='panelMacro'><table class='warningMacro'><colgroup><col width='24'><col></colgroup><tr><td valign='top'><img src="/wiki/images/icons/emoticons/forbidden.gif" width="16" height="16" align="absmiddle" alt="" border="0"></td><td>Even though I have now started typing potential questions to answer, I need to go through a round of proofreading, etc. of the above proposal. So please don't answer these yet.</td></tr></table></div>
<p>1. In the above example, the SIP component has a preexisting set of InboundSubscriptionListeners to send requests to. Where does this come from?<br/>
2. Should there be a distinction made between InboundSubscriptionListeners that actually have the ability to make decisions based on an incoming subscription request and those that simply listen passively for events on subscriptions? My initial thought is that to the component calling the listener methods, he's not really going to care one way or the other, and so a distinction shouldn't be made. But from the viewpoint of usability and clarity, a distinction may help.<br/>
3. I've constructed these APIs with separate call and response methods as opposed to using two-way methods. Any reason to consider changing this?<br/>
4. Is having SubscriptionState as a member of SubscriptionData a wise choice? The main use of this as I see it, is that if a listener adds itself to a subscription late, then when given the SubscriptionData, the listener also knows the current state of the subscription.<br/>
5. I've put addListeners() and removeListeners() methods to InboundSubscription and OutboundSubscription, but I don't know exactly how a new listener is supposed to be able to actually add itself in the first place. How would a potential listener receive the subscription object so that it could add itself as a listener? The only thing I can think of at the moment would be that an IceStorm topic is created such that any established subscriptions would be reported to listeners of the topic, and those who receive events on the topic could then add themselves as listeners to subscriptions. Perhaps such IceStorm listening could be the solution to question 1 as well...<br/>
6. Are there any suggestions for cosmetic improvement (e.g. class/method name changes)?</p>
    </div>
        <div id="commentsSection" class="wiki-content pageSection">
        <div style="float: right;">
            <a href="https://wiki.asterisk.org/wiki/users/viewnotifications.action" class="grey">Change Notification Preferences</a>
        </div>
        <a href="https://wiki.asterisk.org/wiki/display/TOP/Subscription+Support">View Online</a>
        |
        <a href="https://wiki.asterisk.org/wiki/pages/diffpagesbyversion.action?pageId=9568785&revisedVersion=4&originalVersion=3">View Changes</a>
                |
        <a href="https://wiki.asterisk.org/wiki/display/TOP/Subscription+Support?showComments=true&amp;showCommentArea=true#addcomment">Add Comment</a>
            </div>
</div>
</div>
</div>
</div>
</body>
</html>