<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /> 
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0" /> 
<base href="https://wiki.asterisk.org/wiki" /> 
<title>Message Title</title>  
<style type="text/css">@media only screen and (max-device-width: 480px) {.mobile-only {
        width: auto !important;
        height: auto !important;
        overflow: visible !important;
        line-height: normal !important;
        font-size: inherit !important;
        mso-hide: all;
}

.desktop-only {
        display: none !important;
}

/* iPhone 3GS fix for unwanted 20px right margin */
body { min-width: 100% !important; padding: 0; margin: 0; }

#center-content-table { max-width: none; !important; }
#header-pattern-container { padding: 10px 10px 10px 10px !important; line-height: 20px !important; }
#header-avatar-image-container { padding-right: 8px !important; }
#email-content-container { padding: 0 !important; }
.mobile-expand { border-radius: 0 !important; border-left: 0 !important; border-right: 0 !important; padding-left: 26px !important;}
.mobile-resize-text { font-size: 16px !important; line-height: 22px !important; }
#page-title-pattern-header { font-size: 20px !important; line-height: 28px !important; }
#page-title-pattern-icon-image-container-cell { padding-top: 7px !important; }
#inline-user-pattern { display: block !important; }
#inline-user-pattern-avatar { padding-top: 3px !important; }
.contextual-area-pattern { border-bottom: 1px solid #ccc !important; padding: 15px 10px 0 10px !important;}
.users-involved-pattern-column-table { width: 100% !important;  }
.users-involved-pattern-avatar-table-cell { padding: 3px 5px 5px 0 !important; }
.users-involved-pattern-column-container { padding-right: 0 !important; }
.contextual-excerpt-pattern, #users-involved-pattern { border: 0 !important; }

/** Aui Typography upsized for mobile **/
#content-excerpt-pattern-container, #contextual-excerpt-pattern-text-container { font-size: 16px !important; line-height: 22px !important; }
#content-excerpt-pattern-container h1, #contextual-excerpt-pattern-text-container h1 { font-size: 24px !important; line-height: 28px !important; }
#content-excerpt-pattern-container h2, #contextual-excerpt-pattern-text-container h2 { font-size: 20px !important; line-height: 28px !important; }
#content-excerpt-pattern-container h3, #contextual-excerpt-pattern-text-container h3 { font-size: 18px !important; line-height: 24px !important; }
#content-excerpt-pattern-container h4, #contextual-excerpt-pattern-text-container h4 { font-size: 16px !important; line-height: 22px !important; }
#content-excerpt-pattern-container h5, #contextual-excerpt-pattern-text-container h5 { font-size: 14px !important; line-height: 20px !important; }
#content-excerpt-pattern-container h6, #contextual-excerpt-pattern-text-container h6 { font-size: 14px !important; line-height: 20px !important; }
.user-mention { line-height: 18px !important; }
/** Aui Typography end **/

/* Show appropriate footer logo on mobile, display links vertically */
#footer-pattern { padding: 15px 10px !important; }
#footer-pattern-logo-desktop-container { padding: 0 !important; }
#footer-pattern-logo-desktop { width: 0 !important; height: 0 !important; }
#footer-pattern-logo-mobile {
    padding-top: 10px !important;
    width: 30px !important;
    height: 27px !important;
    display: inline !important;
}
#footer-pattern-text {
    display: block !important;
}
#footer-pattern-links-container { line-height: 0 !important;}
.footer-pattern-links.mobile-resize-text,
.footer-pattern-links.mobile-resize-text,
#footer-pattern-text.mobile-resize-text,
#footer-pattern-links-container.no-footer-links {
    font-size: 14px !important;
    line-height: 20px !important;
}
.footer-link { display: block !important; }
#footer-pattern-links-container table { display: inline-block !important; float: none !important; }
#footer-pattern-links-container, #footer-pattern-text { text-align: center !important; }
#footer-pattern-links { padding-bottom: 5px !important; }

/** Team Calendar overrides, these should be removed when notifications are updated in Team Calendars. For now CSS
    overrides are being used because the structure of the content can't change without rereleasing the plugin */
.mail-calendar-container .day-header + table tr td:first-child {
    vertical-align: top !important;
    padding-top: 5px !important;
}}
@media (min-width: 900px) {#center-content-table { width: 900px; }}
@media all {#outlook a {padding:0;} /* Force Outlook to provide a "view in browser" menu link. */
/* Prevent Webkit and Windows Mobile platforms from changing default font sizes.*/
body{-webkit-text-size-adjust:100%; -ms-text-size-adjust:100%;}
.ExternalClass {width:100%;} /* Force Hotmail to display emails at full width */
#background-table {margin:0; padding:0; width:100% !important; }
/* Needed to override highlighting on date and time links in iOS */
.grey a {color: #707070; text-decoration: none; }}
</style> 
</head>
<body>
<table id="background-table" cellpadding="0" cellspacing="0" width="100%" style="border-collapse: collapse; mso-table-lspace: 0pt; mso-table-rspace: 0pt; color: #333; background-color: #f5f5f5"> 
<tbody> 
<tr> 
<td id="header-pattern-container" style="padding: 0px; border-collapse: collapse; padding: 10px 20px"> 
<table id="header-pattern" cellspacing="0" cellpadding="0" border="0" style="border-collapse: collapse; mso-table-lspace: 0pt; mso-table-rspace: 0pt; color: #333"> 
<tbody> 
<tr> 
<td id="header-avatar-image-container" valign="top" style="padding: 0px; border-collapse: collapse; vertical-align: top; width: 32px; padding-right: 9px"><a href="https://wiki.asterisk.org/wiki/display/~mmichelson?src=email" style="color: #3b73af; text-decoration: none"><img id="header-avatar-image" class="image_fix" src="cid:avatar_99ed0aa29d6f204db4785296f8170422" height="32" width="32" border="0" style="border-radius: 3px; vertical-align: top" /></a></td>
<td id="header-text-container" valign="middle" style="padding: 0px; border-collapse: collapse; vertical-align: middle; font-family: Arial, sans-serif; font-size: 14px; line-height: 20px; mso-line-height-rule: exactly; mso-text-raise: 1px">Mark Michelson <strong>edited</strong> a page</td> 
</tr> 
</tbody> 
</table> </td> 
</tr> 
<!-- End Header pattern --> 
<tr> 
<td id="email-content-container" style="padding: 0px; border-collapse: collapse; padding: 0 20px"> 
<table id="email-content-table" cellspacing="0" cellpadding="0" border="0" width="100%" style="border-collapse: collapse; mso-table-lspace: 0pt; mso-table-rspace: 0pt; color: #333; border-spacing: 0; border-collapse: separate"> 
<tbody> 
<tr> 
<td class="email-content-rounded-top mobile-expand" style="padding: 0px; border-collapse: collapse; color: #fff; padding: 0 15px 0 16px; height: 15px; background-color: #fff; border-left: 1px solid #ccc; border-top: 1px solid #ccc; border-right: 1px solid #ccc; border-bottom: 0; border-top-right-radius: 5px; border-top-left-radius: 5px"> </td> 
</tr> 
<tr> 
<td class="email-content-main mobile-expand" style="padding: 0px; border-collapse: collapse; border-left: 1px solid #ccc; border-right: 1px solid #ccc; border-top: 0; border-bottom: 0; padding: 0 15px 15px 16px; background-color: #fff"> 
<table id="page-title-pattern" cellspacing="0" cellpadding="0" border="0" width="100%" style="border-collapse: collapse; mso-table-lspace: 0pt; mso-table-rspace: 0pt; color: #333"> 
<tbody> 
<tr> 
<td id="page-title-pattern-icon-image-container" valign="top" style="padding: 0px; border-collapse: collapse; width: 16px; vertical-align: top"> 
<table cellspacing="0" cellpadding="0" border="0" style="border-collapse: collapse; mso-table-lspace: 0pt; mso-table-rspace: 0pt; color: #333"> 
<tbody> 
<tr> 
<td id="page-title-pattern-icon-image-container-cell" style="padding: 0px; border-collapse: collapse; width: 16px; padding: 9px 8px 0px 0px; mso-text-raise: 5px; mso-line-height-rule: exactly"><a href="https://wiki.asterisk.org/wiki/display/AST/PJSIP+Subscription+Abstraction+Plan?src=email" title="page icon" style="vertical-align: top;; color: #3b73af; text-decoration: none"><img style="vertical-align: top; display: block;" src="cid:page-icon" alt="page icon" title="page icon" height="16" width="16" border="0" /></a></td> 
</tr> 
</tbody> 
</table> </td>
<td style="vertical-align: top;; padding: 0px; border-collapse: collapse; padding-right: 5px; font-size: 20px; line-height: 30px; mso-line-height-rule: exactly" id="page-title-pattern-header-container"><span id="page-title-pattern-header" style="font-family: Arial, sans-serif; padding: 0; font-size: 20px; line-height: 30px; mso-text-raise: 2px; mso-line-height-rule: exactly; vertical-align: middle"><a href="https://wiki.asterisk.org/wiki/display/AST/PJSIP+Subscription+Abstraction+Plan?src=email" title="PJSIP Subscription Abstraction Plan" style="color: #3b73af; text-decoration: none">PJSIP Subscription Abstraction Plan</a></span></td> 
</tr> 
</tbody> 
</table> </td> 
</tr> 
<tr> 
<td class="email-content-main mobile-expand" style="padding: 0px; border-collapse: collapse; border-left: 1px solid #ccc; border-right: 1px solid #ccc; border-top: 0; border-bottom: 0; padding: 0 15px 15px 16px; background-color: #fff"> 
<table class="content-excerpt-pattern" cellspacing="0" cellpadding="0" border="0" width="100%" style="border-collapse: collapse; mso-table-lspace: 0pt; mso-table-rspace: 0pt; color: #333; font-family: Arial, sans-serif; font-size: 14px; line-height: 20px; mso-line-height-rule: exactly; mso-text-raise: 1px"> 
<tbody> 
<tr> 
<td class="content-excerpt-pattern-container mobile-resize-text " style="padding: 0px; border-collapse: collapse; padding: 0 0 0 24px"> <p class="diff-context-placeholder" style="margin: 10px 0 0 0; margin-top: 0">...</p> 
<table class="diff-macro diff-block-context" style="background-color: #f0f0f0;border: 1px solid #dddddd;margin: 10px 1px;padding: 0 2px 2px;width: 100%;; border-collapse: collapse; mso-table-lspace: 0pt; mso-table-rspace: 0pt; color: #333"> 
<thead> 
<tr> 
<th class="diff-macro-title" style="background-color: transparent; text-align: left; font-weight: normal;padding: 5px;"><span class="icon macro-placeholder-icon" style="background-color: ;line-height: 20px;"><img src="https://wiki.asterisk.org/wiki/s/en_GB-1988229788/4732/f543bd9a3bbc12daed85f6f5e5cba84282599932.48/_/plugins/servlet/confluence/placeholder/macro-icon?name=code" style="padding-right: 5px; vertical-align: text-bottom;" /> </span>Code Block</th> 
</tr> 
</thead> 
<tbody> 
<tr> 
<td class="diff-macro-body" style="background-color: #fff;border: 1px solid #dddddd;padding: 10px;; padding: 0px; border-collapse: collapse"> <pre style="margin: 10px 0 0 0; margin-top: 0"> enum sip_subscription_type {
    SIP_SUBSCRIPTION_REAL,
    SIP_SUBSCRIPTION_VIRTUAL,
}; 
 
struct ast_sip_subscription {
    /*! Indicator if subscription is real or virtual */
    enum sip_subscription_type type;
    union {
        /*! Real subscriptions point to a PJSIP subscription */
        pjsip_evsub *evsub;
        /*! Virtual subscriptions point to a parent Asterisk subscription */
        struct ast_sip_subscription *parent;
    };
    /*! Pointer to next sibling subscription */
    AST_LIST_ENTRY(ast_sip_subscription) list;
    /*! List of child subscriptions */
    AST_LIST_HEAD(,ast_sip_subscription) children;
}; </pre> </td> 
</tr> 
</tbody> 
</table> <p class="diff-block-target" style="margin: 10px 0 0 0"> <span class="diff-html-removed" id="removed-diff-0" style="font-size: 100%; background-color: #ffe7e7; text-decoration: line-through;"> </span> </p> <h1 id="PJSIPSubscriptionAbstractionPlan-GeneralAPIchanges" class="diff-block-context" style="margin: 10px 0 0 0; font-size: 24px; font-weight: normal; line-height: 30px; margin: 40px 0 0 0">General API changes</h1> <p class="diff-block-context" style="margin: 10px 0 0 0">The biggest removals from the API the following:</p> <p class="diff-context-placeholder" style="margin: 10px 0 0 0">...</p> <p class="diff-block-target" style="margin: 10px 0 0 0">In order to satisfy previously-required functionality, new API calls will be added to the pubsub API to replace the old functionality<span class="diff-html-removed" id="removed-diff-1" style="font-size: 100%; background-color: #ffe7e7; text-decoration: line-through;">:</span><span class="diff-html-added" id="added-diff-0" style="font-size: 100%; background-color: #ddfade;">. Each of these APIs, when initially written, will propagate up the tree of subscriptions, resulting in similar operations to what were previously being done.</span> </p> 
<table class="diff-macro diff-block-target diff-block-context" style="background-color: #f0f0f0;border: 1px solid #dddddd;margin: 10px 1px;padding: 0 2px 2px;width: 100%;; border-collapse: collapse; mso-table-lspace: 0pt; mso-table-rspace: 0pt; color: #333"> 
<thead> 
<tr> 
<th class="diff-macro-title" style="background-color: transparent; text-align: left; font-weight: normal;padding: 5px;"><span class="icon macro-placeholder-icon" style="background-color: ;line-height: 20px;"><img src="https://wiki.asterisk.org/wiki/s/en_GB-1988229788/4732/f543bd9a3bbc12daed85f6f5e5cba84282599932.48/_/plugins/servlet/confluence/placeholder/macro-icon?name=code" style="padding-right: 5px; vertical-align: text-bottom;" /> </span>Code Block</th> 
</tr> 
</thead> 
<tbody> 
<tr> 
<td class="diff-macro-body" style="background-color: #fff;border: 1px solid #dddddd;padding: 10px;; padding: 0px; border-collapse: collapse"> <pre style="margin: 10px 0 0 0; margin-top: 0">/*! Notify a SIP subscription of a state change.
 * This will create a SIP NOTIFY request, send the notify_data to
 * a body generator, and then send the NOTIFY request out.
 */
int ast_sip_subscription_notify(struct ast_sip_subscription *sub, void *notify_data);
 
/*! Reject an incoming SIP SUBSCRIBE request.
 * This will send the specified response to the SUBSCRIBE. If a
 * NULL reason is specified, then default reason text will be used.
 */
void ast_sip_subscription_reject(struct ast_sip_subscription *sub, int response, const char *reason);
 
/*! Accept an incoming SIP SUBSCRIBE request with a 200 OK. */
void ast_sip_subscription_accept(struct ast_sip_subscription *sub);
 
/*! Retrieve the local URI for this subscription */
void ast_sip_subscription_get_local_uri(struct ast_sip_subscription *sub, char *buf, size_t size);
 
/*! Retrive the remote URI for this subscription */
void ast_sip_subscription_get_remote_uri(struct ast_sip_subscription *sub, char *buf, size_t size);
 
/*! Terminate an active SIP subscription<span class="diff-html-added" id="added-diff-1" style="font-size: 100%; background-color: #ddfade;">.</span> */<span class="diff-html-added" id="added-diff-2" style="font-size: 100%; background-color: #ddfade;">
void ast_sip_subscription_terminate(struct ast_sip_subscripiton *sub);
 
</span>
</pre> </td> 
</tr> 
</tbody> 
</table> <p class="diff-block-target diff-block-context" style="margin: 10px 0 0 0">You'll notice that there is no function to get the current subscription state. This is because <span class="diff-html-removed" id="removed-diff-2" style="font-size: 100%; background-color: #ffe7e7; text-decoration: line-through;">it is unnecessar</span> </p> <h1 id="PJSIPSubscriptionAbstractionPlan-Changestonotifierusage" class="diff-block-target diff-block-context" style="margin: 10px 0 0 0; font-size: 24px; font-weight: normal; line-height: 30px; margin: 40px 0 0 0"> <span class="diff-html-removed" style="font-size: 100%; background-color: #ffe7e7; text-decoration: line-through;">Changes to notifier usage</span> </h1> <h1 id="PJSIPSubscriptionAbstractionPlan-Changestosubscriberusage" class="diff-block-target diff-block-context" style="margin: 10px 0 0 0; font-size: 24px; font-weight: normal; line-height: 30px; margin: 40px 0 0 0"> <span class="diff-html-removed" style="font-size: 100%; background-color: #ffe7e7; text-decoration: line-through;">Changes to subscriber usage</span> </h1> <h1 id="PJSIPSubscriptionAbstractionPlan-Changestopublisherusage" class="diff-block-target diff-block-context" style="margin: 10px 0 0 0; font-size: 24px; font-weight: normal; line-height: 30px; margin: 40px 0 0 0"> <span class="diff-html-removed" style="font-size: 100%; background-color: #ffe7e7; text-decoration: line-through;">Changes to publisher usage</span> </h1> <p class="diff-block-target diff-block-context" style="margin: 10px 0 0 0"> <span class="diff-html-added" id="added-diff-3" style="font-size: 100%; background-color: #ddfade;">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 </span><code style="font-family: monospace"><span class="diff-html-added" style="font-size: 100%; background-color: #ddfade;">ast_sip_subscription_terminate</span></code><span class="diff-html-added" style="font-size: 100%; background-color: #ddfade;"> is called by a notifier, then the pubsub core will rightly set the subscription state as "terminated".</span> </p> <p class="diff-block-target diff-block-context" style="margin: 10px 0 0 0"> <span class="diff-html-added" style="font-size: 100%; background-color: #ddfade;">Subscriber-side API additions will be required in addition, but those changes are being saved for the larger-scale <link>Outbound Subscriptions<link> task to be accomplished later.</span> </p> <h1 id="PJSIPSubscriptionAbstractionPlan-Changestonotifierusage" class="diff-block-target diff-block-context" style="margin: 10px 0 0 0; font-size: 24px; font-weight: normal; line-height: 30px; margin: 40px 0 0 0"> <span class="diff-html-added" style="font-size: 100%; background-color: #ddfade;">Changes to notifier usage</span> </h1> <p class="diff-block-target diff-block-context" style="margin: 10px 0 0 0"> <span class="diff-html-added" style="font-size: 100%; background-color: #ddfade;">The </span><code style="font-family: monospace"><span class="diff-html-added" style="font-size: 100%; background-color: #ddfade;">ast_sip_subscription_handler</span></code><span class="diff-html-added" style="font-size: 100%; background-color: #ddfade;"> structure will also need to be altered to rid itself of PJSIP-specific structures. Specifically, the following callbacks will need to be altered:</span> </p> 
<table class="diff-macro diff-html-added diff-block-target diff-block-context" style="background-color: #f0f0f0;border: 1px solid #dddddd;margin: 10px 1px;padding: 0 2px 2px;width: 100%;background-color: #ddfade;border-color: #93c49f;; border-collapse: collapse; mso-table-lspace: 0pt; mso-table-rspace: 0pt; color: #333"> 
<thead> 
<tr> 
<th class="diff-macro-title" style="background-color: transparent; text-align: left; font-weight: normal;padding: 5px;"><span class="diff-html-added" style="font-size: 100%; background-color: #ddfade;"><span class="icon macro-placeholder-icon" style="background-color: ;line-height: 20px;"><img src="https://wiki.asterisk.org/wiki/s/en_GB-1988229788/4732/f543bd9a3bbc12daed85f6f5e5cba84282599932.48/_/plugins/servlet/confluence/placeholder/macro-icon?name=code" style="padding-right: 5px; vertical-align: text-bottom;" /> </span>Code Block</span></th> 
</tr> 
</thead> 
<tbody> 
<tr> 
<td class="diff-macro-body" style="background-color: #fff;border: 1px solid #dddddd;padding: 10px;; padding: 0px; border-collapse: collapse"> <pre style="margin: 10px 0 0 0; margin-top: 0">
<span class="diff-html-added" style="font-size: 100%; background-color: #ddfade;">struct ast_sip_subscription_handler {
    struct ast_sip_subscription *(*new_subscribe)(struct ast_sip_endpoint *endpoint,
            pjsip_rx_data *rdata);
    void (*resubscribe)(struct ast_sip_subscription *sub,
            pjsip_rx_data *rdata, struct ast_sip_subscription_response_data *response_data);
    void (*subscription_terminated)(struct ast_sip_subscription *sub, pjsip_rx_data *rdata);
    void (*notify_response)(struct ast_sip_subscription *sub, pjsip_rx_data *rdata);
};</span>
</pre> </td> 
</tr> 
</tbody> 
</table> <p class="diff-block-target diff-block-context" style="margin: 10px 0 0 0"> <span class="diff-html-added" style="font-size: 100%; background-color: #ddfade;">All of these currently contain a </span><code style="font-family: monospace"><span class="diff-html-added" style="font-size: 100%; background-color: #ddfade;">pjsip_rx_data</span></code><span class="diff-html-added" style="font-size: 100%; background-color: #ddfade;"> structure as a parameter. A notifier no longer can can operate on a </span><code style="font-family: monospace"><span class="diff-html-added" style="font-size: 100%; background-color: #ddfade;">pjsip_rx_data</span></code><span class="diff-html-added" style="font-size: 100%; background-color: #ddfade;"> 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. What they care about is the resource that is being subscribed to. Given that notifiers will not be directly responding to SIP requests any longer, 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.</span> </p> 
<table class="diff-macro diff-html-added diff-block-target diff-block-context" style="background-color: #f0f0f0;border: 1px solid #dddddd;margin: 10px 1px;padding: 0 2px 2px;width: 100%;background-color: #ddfade;border-color: #93c49f;; border-collapse: collapse; mso-table-lspace: 0pt; mso-table-rspace: 0pt; color: #333"> 
<thead> 
<tr> 
<th class="diff-macro-title" style="background-color: transparent; text-align: left; font-weight: normal;padding: 5px;"><span class="diff-html-added" style="font-size: 100%; background-color: #ddfade;"><span class="icon macro-placeholder-icon" style="background-color: ;line-height: 20px;"><img src="https://wiki.asterisk.org/wiki/s/en_GB-1988229788/4732/f543bd9a3bbc12daed85f6f5e5cba84282599932.48/_/plugins/servlet/confluence/placeholder/macro-icon?name=code" style="padding-right: 5px; vertical-align: text-bottom;" /> </span>Code Block</span></th> 
</tr> 
</thead> 
<tbody> 
<tr> 
<td class="diff-macro-body" style="background-color: #fff;border: 1px solid #dddddd;padding: 10px;; padding: 0px; border-collapse: collapse"> <pre style="margin: 10px 0 0 0; margin-top: 0">
<span class="diff-html-added" style="font-size: 100%; background-color: #ddfade;">enum ast_sip_subscription_notify_reason {
    /*! Initial NOTIFY for subscription */
    AST_SIP_SUBSCRIPTION_NOTIFY_REASON_STARTED,
    /*! Subscription has been renewed */
    AST_SIP_SUBSCRIPTION_NOTIFY_REASON_RENEWED,
    /*! Subscription is being terminated */
    AST_SIP_SUBSCRIPTION_NOTIFY_REASON_TERMINATED,
    /*! Other unspecified reason */
    AST_SIP_SUBSCRIPTION_NOTIFY_REASON_OTHER
};
 
struct ast_sip_subscription_notifier {
    /*! Return the response code for the incoming SUBSCRIBE request */
    int (*new_subscribe)(struct ast_sip_endpoint *endpoint, const char *resource);
    /*! Subscription is in need of a NOTIFY */
    void (notify_required)(struct ast_sip_subscription *sub, enum ast_sip_subscription_notify_reason reason);
};
 
/*! Get the name of a subscribed resource */
const char *ast_sip_subscription_get_resource_name(struct ast_sip_subscription *sub);</span>
</pre> </td> 
</tr> 
</tbody> 
</table> <p class="diff-block-target diff-block-context" style="margin: 10px 0 0 0"> <span class="diff-html-added" style="font-size: 100%; background-color: #ddfade;">The biggest change is the one being made to the </span><code style="line-height: 1.4285715;; font-family: monospace"><span class="diff-html-added" style="font-size: 100%; background-color: #ddfade;">new_subscribe</span></code><span class="diff-html-added" style="font-size: 100%; background-color: #ddfade;"> callback. Previously, this callback required the notifier to respond to the SIP SUBSCRIBE, then create an </span><code style="line-height: 1.4285715;; font-family: monospace"><span class="diff-html-added" style="font-size: 100%; background-color: #ddfade;">ast_sip_subscription</span></code><span class="diff-html-added" style="font-size: 100%; background-color: #ddfade;"> structure, then send an initial NOTIFY request. The callback would return the created </span><code style="line-height: 1.4285715;; font-family: monospace"><span class="diff-html-added" style="font-size: 100%; background-color: #ddfade;">ast_sip_subscription</span></code><span class="diff-html-added" style="font-size: 100%; background-color: #ddfade;"> structure. The callback has been simplified greatly. Now, the notifier simply returns a response code for the pubsub core to send to the SUBSCRIBE request. If the response is a 200-class response, then the pubsub core will create the </span><code style="line-height: 1.4285715;; font-family: monospace"><span class="diff-html-added" style="font-size: 100%; background-color: #ddfade;">ast_sip_subscription</span></code><span class="diff-html-added" style="font-size: 100%; background-color: #ddfade;"> itself, then immediately call back into the notifier with the </span><code style="line-height: 1.4285715;; font-family: monospace"><span class="diff-html-added" style="font-size: 100%; background-color: #ddfade;">notify_required</span></code><span class="diff-html-added" style="font-size: 100%; background-color: #ddfade;"> callback in order to send the initial NOTIFY. At first, this appears to give a disadvantage over the previous incarnation since the notifier will not have access to the </span><code style="line-height: 1.4285715;; font-family: monospace"><span class="diff-html-added" style="font-size: 100%; background-color: #ddfade;">ast_sip_subscription</span></code><span class="diff-html-added" style="font-size: 100%; background-color: #ddfade;"> structure in the </span><code style="line-height: 1.4285715;; font-family: monospace"><span class="diff-html-added" style="font-size: 100%; background-color: #ddfade;">new_subscribe</span></code><span class="diff-html-added" style="font-size: 100%; background-color: #ddfade;"> callback. However, since the </span><code style="line-height: 1.4285715;; font-family: monospace"><span class="diff-html-added" style="font-size: 100%; background-color: #ddfade;">notify_required</span></code><span class="diff-html-added" style="font-size: 100%; background-color: #ddfade;"> callback will be immediately called into with </span><code style="line-height: 1.4285715;; font-family: monospace"><span class="diff-html-added" style="font-size: 100%; background-color: #ddfade;">AST_SIP_SUBSCRIPTION_NOTIFY_REASON_STARTED</span></code><span class="diff-html-added" style="font-size: 100%; background-color: #ddfade;"> as the reason, the notifier can use that opportunity to do anything that requires the subscription, to include setting up the underlying stasis subscription.</span> </p> <p class="diff-block-target diff-block-context" style="margin: 10px 0 0 0"> <span class="diff-html-added" style="font-size: 100%; background-color: #ddfade;">The </span><code style="font-family: monospace"><span class="diff-html-added" style="font-size: 100%; background-color: #ddfade;">notify_required</span></code><span class="diff-html-added" style="font-size: 100%; background-color: #ddfade;"> callback is a general callback that tells the notifier that it needs to send a NOTIFY based on the current state of the subscription. The reason lets the notifier know why the NOTIFY is needed. Because one of the reasons is </span><code style="font-family: monospace"><span class="diff-html-added" style="font-size: 100%; background-color: #ddfade;">AST_SIP_SUBSCRIPTION_NOTIFY_REASON_TERMINATED</span></code><span class="diff-html-added" style="font-size: 100%; background-color: #ddfade;"> there is no reason to have a separate </span><code style="font-family: monospace"><span class="diff-html-added" style="font-size: 100%; background-color: #ddfade;">subscription_terminated</span></code><span class="diff-html-added" style="font-size: 100%; background-color: #ddfade;"> callback for notifiers. However, you'll n</span> </p> <p class="diff-block-target diff-block-context" style="margin: 10px 0 0 0"> <span class="diff-html-added" style="font-size: 100%; background-color: #ddfade;">Note that the old </span><code style="font-family: monospace"><span class="diff-html-added" style="font-size: 100%; background-color: #ddfade;">notify_response</span></code><span class="diff-html-added" style="font-size: 100%; background-color: #ddfade;"> 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 entirely.</span> </p> <h1 id="PJSIPSubscriptionAbstractionPlan-Changestosubscriberusage" class="diff-block-target diff-block-context" style="margin: 10px 0 0 0; font-size: 24px; font-weight: normal; line-height: 30px; margin: 40px 0 0 0"> <span class="diff-html-added" style="font-size: 100%; background-color: #ddfade;">Changes to subscriber usage</span> </h1> <p class="diff-block-target diff-block-context" style="margin: 10px 0 0 0"> <span class="diff-html-added" style="font-size: 100%; background-color: #ddfade;">More in-depth subscriber usage changes will be happening in the <link>Outbound Subscriptoins<link> section later. However, a prerequisite is to make sure that what exists for subscribers in the </span><code style="font-family: monospace"><span class="diff-html-added" style="font-size: 100%; background-color: #ddfade;">ast_sip_subscription_handler</span></code><span class="diff-html-added" style="font-size: 100%; background-color: #ddfade;"> structure is taken care of. The old subscriber-specific callbacks need to be converted not to use PJSIP-specific structures. Here are the parts that need conversion:</span> </p> 
<table class="diff-macro diff-html-added diff-block-target diff-block-context" style="background-color: #f0f0f0;border: 1px solid #dddddd;margin: 10px 1px;padding: 0 2px 2px;width: 100%;background-color: #ddfade;border-color: #93c49f;; border-collapse: collapse; mso-table-lspace: 0pt; mso-table-rspace: 0pt; color: #333"> 
<thead> 
<tr> 
<th class="diff-macro-title" style="background-color: transparent; text-align: left; font-weight: normal;padding: 5px;"><span class="diff-html-added" style="font-size: 100%; background-color: #ddfade;"><span class="icon macro-placeholder-icon" style="background-color: ;line-height: 20px;"><img src="https://wiki.asterisk.org/wiki/s/en_GB-1988229788/4732/f543bd9a3bbc12daed85f6f5e5cba84282599932.48/_/plugins/servlet/confluence/placeholder/macro-icon?name=code" style="padding-right: 5px; vertical-align: text-bottom;" /> </span>Code Block</span></th> 
</tr> 
</thead> 
<tbody> 
<tr> 
<td class="diff-macro-body" style="background-color: #fff;border: 1px solid #dddddd;padding: 10px;; padding: 0px; border-collapse: collapse"> <pre style="margin: 10px 0 0 0; margin-top: 0">
<span class="diff-html-added" style="font-size: 100%; background-color: #ddfade;">struct ast_sip_subscription *ast_sip_create_subscription(const struct ast_sip_subscription_handler *handler,
        enum ast_sip_subscription_role role, struct ast_sip_endpoint *endpoint, pjsip_rx_data *rdata);
 
struct ast_sip_subscription_handler {
        void (*subscription_terminated)(struct ast_sip_subscription *sub, pjsip_rx_data *rdata);
    void (*notify_request)(struct ast_sip_subscription *sub,
            pjsip_rx_data *rdata, struct ast_sip_subscription_response_data *response_data);
    int (*refresh_subscription)(struct ast_sip_subscription *sub);
}</span>
</pre> </td> 
</tr> 
</tbody> 
</table> <p class="diff-block-target diff-block-context" style="margin: 10px 0 0 0"> <span class="diff-html-added" style="font-size: 100%; background-color: #ddfade;">We already eliminated the </span><code style="font-family: monospace"><span class="diff-html-added" style="font-size: 100%; background-color: #ddfade;">subscription_terminated</span></code><span class="diff-html-added" style="font-size: 100%; background-color: #ddfade;"> callback for notifiers; however, for subscribers, we will keep the callback but eliminate the </span><code style="font-family: monospace"><span class="diff-html-added" style="font-size: 100%; background-color: #ddfade;">pjsip_rx_data</span></code><span class="diff-html-added" style="font-size: 100%; background-color: #ddfade;"> from it. The </span><code style="font-family: monospace"><span class="diff-html-added" style="font-size: 100%; background-color: #ddfade;">refresh_subscription</span></code><span class="diff-html-added" style="font-size: 100%; background-color: #ddfade;"> callback will be eliminated since the pubsub core should be perfectly capable of refreshing subscriptions on its own. Here is the revised version:</span> </p> 
<table class="diff-macro diff-html-added diff-block-target diff-block-context" style="background-color: #f0f0f0;border: 1px solid #dddddd;margin: 10px 1px;padding: 0 2px 2px;width: 100%;background-color: #ddfade;border-color: #93c49f;; border-collapse: collapse; mso-table-lspace: 0pt; mso-table-rspace: 0pt; color: #333"> 
<thead> 
<tr> 
<th class="diff-macro-title" style="background-color: transparent; text-align: left; font-weight: normal;padding: 5px;"><span class="diff-html-added" style="font-size: 100%; background-color: #ddfade;"><span class="icon macro-placeholder-icon" style="background-color: ;line-height: 20px;"><img src="https://wiki.asterisk.org/wiki/s/en_GB-1988229788/4732/f543bd9a3bbc12daed85f6f5e5cba84282599932.48/_/plugins/servlet/confluence/placeholder/macro-icon?name=code" style="padding-right: 5px; vertical-align: text-bottom;" /> </span>Code Block</span></th> 
</tr> 
</thead> 
<tbody> 
<tr> 
<td class="diff-macro-body" style="background-color: #fff;border: 1px solid #dddddd;padding: 10px;; padding: 0px; border-collapse: collapse"> <pre style="margin: 10px 0 0 0; margin-top: 0">
<span class="diff-html-added" style="font-size: 100%; background-color: #ddfade;">/*! Create a new outbound SIP subscription to the requested resource at the requested endpoint. */
struct ast_sip_subscription *ast_sip_create_subscription(const struct ast_sip_subscriber *subscriber,
        struct ast_sip_endpoint *endpoint, const char *resource);
 
struct ast_sip_subscriber {
    /*! A NOTIFY has been received with the attached body. */
    void (*state_change)(struct ast_sip_subscription *sub, const char *body, enum pjsip_evsub_state state);
}</span>
</pre> </td> 
</tr> 
</tbody> 
</table> <p class="diff-block-target diff-block-context" style="margin: 10px 0 0 0"> <span class="diff-html-added" style="font-size: 100%; background-color: #ddfade;">Everything has been changed drastically.</span> </p> <p class="diff-block-target diff-block-context" style="margin: 10px 0 0 0"> <code style="font-family: monospace"><span class="diff-html-added" style="font-size: 100%; background-color: #ddfade;">ast_sip_create_subscription</span></code><span class="diff-html-added" style="font-size: 100%; background-color: #ddfade;"> is now only used by subscribers; notifiers have no need to create subscriptions themselves. As such, in addition to creating the </span><code style="font-family: monospace"><span class="diff-html-added" style="font-size: 100%; background-color: #ddfade;">ast_sip_subscription</span></code><span class="diff-html-added" style="font-size: 100%; background-color: #ddfade;"> structure, it will also send out the initial SUBSCRIBE request to the specified resource at the specified endpoint.</span> </p> <p class="diff-block-target diff-block-context" style="margin: 10px 0 0 0"> <span class="diff-html-added" style="font-size: 100%; background-color: #ddfade;">As was noted with notifiers earlier, </span><code style="font-family: monospace"><span class="diff-html-added" style="font-size: 100%; background-color: #ddfade;">ast_sip_subscription_handler</span></code><span class="diff-html-added" style="font-size: 100%; background-color: #ddfade;"> is being replaced by separate notifier and subscriber structures. The subscriber structure has a few major changes. </span><code style="font-family: monospace"><span class="diff-html-added" style="font-size: 100%; background-color: #ddfade;">refresh_subscription</span></code><span class="diff-html-added" style="font-size: 100%; background-color: #ddfade;"> has been removed since the pubsub core will handle it. </span><code style="font-family: monospace"><span class="diff-html-added" style="font-size: 100%; background-color: #ddfade;">notify_request</span></code><span class="diff-html-added" style="font-size: 100%; background-color: #ddfade;"> has been altered to be </span><code style="font-family: monospace"><span class="diff-html-added" style="font-size: 100%; background-color: #ddfade;">state_change</span></code><span class="diff-html-added" style="font-size: 100%; background-color: #ddfade;"> 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 </span><code style="font-family: monospace"><span class="diff-html-added" style="font-size: 100%; background-color: #ddfade;">PJSIP_EVSUB_STATE_TERMINATED</span></code><span class="diff-html-added" style="font-size: 100%; background-color: #ddfade;"> then the subscriber can know that the subscription has been terminated. Because of this, there is no need for a </span><code style="font-family: monospace"><span class="diff-html-added" style="font-size: 100%; background-color: #ddfade;">subscription_terminated</span></code><span class="diff-html-added" style="font-size: 100%; background-color: #ddfade;"> callback.</span> </p> <h1 id="PJSIPSubscriptionAbstractionPlan-Changestopublishhandlerusage" class="diff-block-target diff-block-context" style="margin: 10px 0 0 0; font-size: 24px; font-weight: normal; line-height: 30px; margin: 40px 0 0 0"> <span class="diff-html-added" style="font-size: 100%; background-color: #ddfade;">Changes to publish handler usage</span> </h1> <p class="diff-block-target diff-block-context" style="margin: 10px 0 0 0"> <span class="diff-html-added" style="font-size: 100%; background-color: #ddfade;">Publisher changes are similar to notifier changes. Here are the areas where publication handling needs to be altered:</span> </p> 
<table class="diff-macro diff-html-added diff-block-target diff-block-context" style="background-color: #f0f0f0;border: 1px solid #dddddd;margin: 10px 1px;padding: 0 2px 2px;width: 100%;background-color: #ddfade;border-color: #93c49f;; border-collapse: collapse; mso-table-lspace: 0pt; mso-table-rspace: 0pt; color: #333"> 
<thead> 
<tr> 
<th class="diff-macro-title" style="background-color: transparent; text-align: left; font-weight: normal;padding: 5px;"><span class="diff-html-added" style="font-size: 100%; background-color: #ddfade;"><span class="icon macro-placeholder-icon" style="background-color: ;line-height: 20px;"><img src="https://wiki.asterisk.org/wiki/s/en_GB-1988229788/4732/f543bd9a3bbc12daed85f6f5e5cba84282599932.48/_/plugins/servlet/confluence/placeholder/macro-icon?name=code" style="padding-right: 5px; vertical-align: text-bottom;" /> </span>Code Block</span></th> 
</tr> 
</thead> 
<tbody> 
<tr> 
<td class="diff-macro-body" style="background-color: #fff;border: 1px solid #dddddd;padding: 10px;; padding: 0px; border-collapse: collapse"> <pre style="margin: 10px 0 0 0; margin-top: 0">
<span class="diff-html-added" style="font-size: 100%; background-color: #ddfade;">struct ast_sip_publication_handler {
    struct ast_sip_publication *(*new_publication)(struct ast_sip_endpoint *endpoint, pjsip_rx_data *rdata);
    int (*publish_refresh)(struct ast_sip_publication *pub, pjsip_rx_data *rdata);
    void (*publish_termination)(struct ast_sip_publication *pub, pjsip_rx_data *rdata);
};
 
struct ast_sip_publication *ast_sip_create_publication(struct ast_sip_endpoint *endpoint, pjsip_rx_data *rdata);</span>
</pre> </td> 
</tr> 
</tbody> 
</table> <p class="diff-block-target diff-block-context" style="margin: 10px 0 0 0"> <span class="diff-html-added" style="font-size: 100%; background-color: #ddfade;">Here is the revised edition:</span> </p> 
<table class="diff-macro diff-html-added diff-block-target diff-block-context" style="background-color: #f0f0f0;border: 1px solid #dddddd;margin: 10px 1px;padding: 0 2px 2px;width: 100%;background-color: #ddfade;border-color: #93c49f;; border-collapse: collapse; mso-table-lspace: 0pt; mso-table-rspace: 0pt; color: #333"> 
<thead> 
<tr> 
<th class="diff-macro-title" style="background-color: transparent; text-align: left; font-weight: normal;padding: 5px;"><span class="diff-html-added" style="font-size: 100%; background-color: #ddfade;"><span class="icon macro-placeholder-icon" style="background-color: ;line-height: 20px;"><img src="https://wiki.asterisk.org/wiki/s/en_GB-1988229788/4732/f543bd9a3bbc12daed85f6f5e5cba84282599932.48/_/plugins/servlet/confluence/placeholder/macro-icon?name=code" style="padding-right: 5px; vertical-align: text-bottom;" /> </span>Code Block</span></th> 
</tr> 
</thead> 
<tbody> 
<tr> 
<td class="diff-macro-body" style="background-color: #fff;border: 1px solid #dddddd;padding: 10px;; padding: 0px; border-collapse: collapse"> <pre style="margin: 10px 0 0 0; margin-top: 0">
<span class="diff-html-added" style="font-size: 100%; background-color: #ddfade;">enum ast_sip_publish_state {
    /*! Publication has just been initialized */
    AST_SIP_PUBLISH_STATE_INITIALIZED,
    /*! Publication is currently active */
    AST_SIP_PUBLISH_STATE_ACTIVE,
    /*! Publication has been terminated */
    AST_SIP_PUBLISH_STATE_TERMINATED,
}; 
 
struct ast_sip_publication_handler {
    /*! New publication has arrived. Return appropriate SIP response code */
    int (*new_publication)(struct ast_sip_endpoint *endpoint, const char *resource);
    /*! Published resource has changed states. Use the state parameter to determine if publication is terminated. */
    int (*publication_state_change)(struct ast_sip_publication *pub, const char *body, enum ast_sip_publish_state state);
};
 
const char *ast_sip_publish_get_resource(struct ast_sip_publication *pub);</span>
</pre> </td> 
</tr> 
</tbody> 
</table> <p class="diff-block-target diff-block-context" style="margin: 10px 0 0 0"> <span class="diff-html-added" style="font-size: 100%; background-color: #ddfade;">Like with the notifier, the </span><code style="font-family: monospace"><span class="diff-html-added" style="font-size: 100%; background-color: #ddfade;">new_publication</span></code><span class="diff-html-added" style="font-size: 100%; background-color: #ddfade;"> 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 </span><code style="font-family: monospace"><span class="diff-html-added" style="font-size: 100%; background-color: #ddfade;">publication_state_change</span></code><span class="diff-html-added" style="font-size: 100%; background-color: #ddfade;"> callback to relay the actual PUBLISH body to the handler. </span><code style="font-family: monospace"><span class="diff-html-added" style="font-size: 100%; background-color: #ddfade;">publish_refresh</span></code><span class="diff-html-added" style="font-size: 100%; background-color: #ddfade;"> and </span><code style="font-family: monospace"><span class="diff-html-added" style="font-size: 100%; background-color: #ddfade;">publish_termination</span></code><span class="diff-html-added" style="font-size: 100%; background-color: #ddfade;"> are not needed since the </span><code style="font-family: monospace"><span class="diff-html-added" style="font-size: 100%; background-color: #ddfade;">publication_state_change</span></code><span class="diff-html-added" style="font-size: 100%; background-color: #ddfade;"> covers their functionality.</span> </p> </td> 
</tr> 
</tbody> 
</table> </td> 
</tr> 
<tr> 
<td class="email-content-main mobile-expand action-padding last-row-padding" style="padding: 0px; border-collapse: collapse; border-left: 1px solid #ccc; border-right: 1px solid #ccc; border-top: 0; border-bottom: 0; padding: 0 15px 15px 16px; background-color: #fff; padding-bottom: 10px; padding-bottom: 10px"> 
<table id="actions-pattern" cellspacing="0" cellpadding="0" border="0" width="100%" style="border-collapse: collapse; mso-table-lspace: 0pt; mso-table-rspace: 0pt; color: #333; font-family: Arial, sans-serif; font-size: 14px; line-height: 20px; mso-line-height-rule: exactly; mso-text-raise: 1px"> 
<tbody> 
<tr> 
<td id="actions-pattern-container" valign="middle" style="padding: 0px; border-collapse: collapse; padding: 15px 0 0 24px; vertical-align: middle"> 
<table align="left" style="border-collapse: collapse; mso-table-lspace: 0pt; mso-table-rspace: 0pt; color: #333"> 
<tbody> 
<tr> 
<td class="actions-pattern-action-icon-container" style="padding: 0px; border-collapse: collapse; font-family: Arial, sans-serif; font-size: 14px; line-height: 20px; mso-line-height-rule: exactly; mso-text-raise: 0px; vertical-align: middle"><a href="https://wiki.asterisk.org/wiki/display/AST/PJSIP+Subscription+Abstraction+Plan?src=email" title="View page" style="color: #3b73af; text-decoration: none"><img class="actions-pattern-action-icon-image" src="cid:confluence.mail.templates.view.page" alt="View page-icon" title="View page-icon" height="16" width="16" border="0" style="vertical-align: middle" /></a></td>
<td class="actions-pattern-action-text-container" style="padding: 0px; border-collapse: collapse; font-family: Arial, sans-serif; font-size: 14px; line-height: 20px; mso-line-height-rule: exactly; mso-text-raise: 4px; padding-left: 5px; white-space: nowrap"><a href="https://wiki.asterisk.org/wiki/display/AST/PJSIP+Subscription+Abstraction+Plan?src=email" title="View page" style="color: #3b73af; text-decoration: none">View page</a></td>
<td class="actions-pattern-action-bull" style="padding: 0px; border-collapse: collapse; font-family: Arial, sans-serif; font-size: 14px; line-height: 20px; mso-line-height-rule: exactly; mso-text-raise: 4px; color: #999; padding: 0 5px">•</td> 
</tr> 
</tbody> 
</table> 
<table align="left" style="border-collapse: collapse; mso-table-lspace: 0pt; mso-table-rspace: 0pt; color: #333"> 
<tbody> 
<tr> 
<td class="actions-pattern-action-icon-container" style="padding: 0px; border-collapse: collapse; font-family: Arial, sans-serif; font-size: 14px; line-height: 20px; mso-line-height-rule: exactly; mso-text-raise: 0px; vertical-align: middle"><a href="https://wiki.asterisk.org/wiki/display/AST/PJSIP+Subscription+Abstraction+Plan?showComments=true&showCommentArea=true#addcomment" title="Add comment" style="color: #3b73af; text-decoration: none"><img class="actions-pattern-action-icon-image" src="cid:confluence.mail.templates.add.comment" alt="Add comment-icon" title="Add comment-icon" height="16" width="16" border="0" style="vertical-align: middle" /></a></td>
<td class="actions-pattern-action-text-container" style="padding: 0px; border-collapse: collapse; font-family: Arial, sans-serif; font-size: 14px; line-height: 20px; mso-line-height-rule: exactly; mso-text-raise: 4px; padding-left: 5px; white-space: nowrap"><a href="https://wiki.asterisk.org/wiki/display/AST/PJSIP+Subscription+Abstraction+Plan?showComments=true&showCommentArea=true#addcomment" title="Add comment" style="color: #3b73af; text-decoration: none">Add comment</a></td>
<td class="actions-pattern-action-bull" style="padding: 0px; border-collapse: collapse; font-family: Arial, sans-serif; font-size: 14px; line-height: 20px; mso-line-height-rule: exactly; mso-text-raise: 4px; color: #999; padding: 0 5px">•</td> 
</tr> 
</tbody> 
</table> 
<table style="border-collapse: collapse; mso-table-lspace: 0pt; mso-table-rspace: 0pt; color: #333"> 
<tbody> 
<tr> 
<td class="actions-pattern-action-icon-container" style="padding: 0px; border-collapse: collapse; font-family: Arial, sans-serif; font-size: 14px; line-height: 20px; mso-line-height-rule: exactly; mso-text-raise: 0px; vertical-align: middle"><a href="https://wiki.asterisk.org/wiki/plugins/likes/like.action?contentId=28934231&src=email" title="Like" style="color: #3b73af; text-decoration: none"><img class="actions-pattern-action-icon-image" src="cid:likes.like" alt="Like-icon" title="Like-icon" height="16" width="16" border="0" style="vertical-align: middle" /></a></td>
<td class="actions-pattern-action-text-container" style="padding: 0px; border-collapse: collapse; font-family: Arial, sans-serif; font-size: 14px; line-height: 20px; mso-line-height-rule: exactly; mso-text-raise: 4px; padding-left: 5px; white-space: nowrap"><a href="https://wiki.asterisk.org/wiki/plugins/likes/like.action?contentId=28934231&src=email" title="Like" style="color: #3b73af; text-decoration: none">Like</a></td> 
</tr> 
</tbody> 
</table> </td> 
</tr> 
</tbody> 
</table> </td> 
</tr> 
<tr> 
<td class="email-content-rounded-bottom mobile-expand" style="padding: 0px; border-collapse: collapse; color: #fff; height: 5px; line-height: 5px; padding: 0 15px 0 16px; background-color: #fff; border-bottom-right-radius: 5px; border-bottom-left-radius: 5px; border-top: 0; border-left: 1px solid #ccc; border-bottom: 1px solid #ccc; border-right: 1px solid #ccc; mso-line-height-rule: exactly"> </td> 
</tr> 
</tbody> 
</table> </td> 
</tr> 
<tr> 
<td id="footer-pattern" style="padding: 0px; border-collapse: collapse; padding: 12px 20px"> 
<table id="footer-pattern-container" cellspacing="0" cellpadding="0" border="0" width="100%" style="border-collapse: collapse; mso-table-lspace: 0pt; mso-table-rspace: 0pt; color: #333"> 
<tbody> 
<tr> 
<td id="footer-pattern-links-container" width="100%" style="padding: 0px; border-collapse: collapse; color: #999; font-size: 12px; line-height: 18px; font-family: Arial, sans-serif; mso-line-height-rule: exactly; mso-text-raise: 2px"> 
<table align="left" style="border-collapse: collapse; mso-table-lspace: 0pt; mso-table-rspace: 0pt; color: #333; font-size: 12px; line-height: 18px; font-family: Arial, sans-serif; mso-line-height-rule: exactly; mso-text-raise: 2px"> 
<tbody> 
<tr> 
<td class="footer-pattern-links mobile-resize-text" style="padding: 0px; border-collapse: collapse"><a href="https://wiki.asterisk.org/wiki/users/removespacenotification.action?spaceKey=AST&src=email" title="" style="color: #3b73af; text-decoration: none">Stop watching space</a></td>
<td class="footer-pattern-links-bull" style="padding: 0px; border-collapse: collapse; padding: 0 5px; color: #999">•</td> 
</tr> 
</tbody> 
</table> 
<table style="border-collapse: collapse; mso-table-lspace: 0pt; mso-table-rspace: 0pt; color: #333; font-size: 12px; line-height: 18px; font-family: Arial, sans-serif; mso-line-height-rule: exactly; mso-text-raise: 2px"> 
<tbody> 
<tr> 
<td class="footer-pattern-links mobile-resize-text" style="padding: 0px; border-collapse: collapse"><a href="https://wiki.asterisk.org/wiki/users/editmyemailsettings.action?src=email" title="" style="color: #3b73af; text-decoration: none">Manage notifications</a></td> 
</tr> 
</tbody> 
</table> </td> 
</tr> 
<tr> 
<td id="footer-pattern-text" class="mobile-resize-text" width="100%" style="padding: 0px; border-collapse: collapse; color: #999; font-size: 12px; line-height: 18px; font-family: Arial, sans-serif; mso-line-height-rule: exactly; mso-text-raise: 2px; display: none">This message was sent by Atlassian Confluence 5.4.3</td> 
</tr> 
</tbody> 
</table> </td> 
</tr> 
</tbody> 
</table> 
<table id="sealed-section" border="0" cellpadding="0" cellspacing="0" width="0" style="border-collapse: collapse; mso-table-lspace: 0pt; mso-table-rspace: 0pt; color: #333; display: none"> 
<tbody> 
<tr> 
<td style="padding: 0px; border-collapse: collapse; border: 0; font-size: 0px; line-height: 0; mso-line-height-rule: exactly"></td> 
</tr> 
</tbody> 
</table>
</body>
</html>