<html>
 <body>
  <div style="font-family: Verdana, Arial, Helvetica, Sans-Serif;">
   <table bgcolor="#f9f3c9" width="100%" cellpadding="8" style="border: 1px #c9c399 solid;">
    <tr>
     <td>
      This is an automatically generated e-mail. To reply, visit:
      <a href="https://reviewboard.asterisk.org/r/2858/">https://reviewboard.asterisk.org/r/2858/</a>
     </td>
    </tr>
   </table>
   <br />





<blockquote style="margin-left: 1em; border-left: 2px solid #d0d0d0; padding-left: 10px;">
 <p style="margin-top: 0;">On September 17th, 2013, 7:22 p.m. UTC, <b>Mark Michelson</b> wrote:</p>
 <blockquote style="margin-left: 1em; border-left: 2px solid #d0d0d0; padding-left: 10px;">
  <pre style="white-space: pre-wrap; white-space: -moz-pre-wrap; white-space: -pre-wrap; white-space: -o-pre-wrap; word-wrap: break-word;">Thanks for the submission! Despite the number of comments below, this is a really great first effort. Most of the comments below focus on small matters that can be easily corrected, such as coding guidelines violations. I&#39;ll take another pass at this once you fix the stuff mentioned here.</pre>
 </blockquote>












 <p>On September 18th, 2013, 5:52 a.m. UTC, <b>Olle E Johansson</b> wrote:</p>
 <blockquote style="margin-left: 1em; border-left: 2px solid #d0d0d0; padding-left: 10px;">
  <pre style="white-space: pre-wrap; white-space: -moz-pre-wrap; white-space: -pre-wrap; white-space: -o-pre-wrap; word-wrap: break-word;">I like having this functionality, but based on experiences would like to suggest name changes. The current one in chan_sip only adds headers to the initial INVITE so it&#39;s really ADDHEADERINVITEREQUEST. We need to have a name that also allow for adding functions to add headers to responses and possibly BYE requests and responses. THis just copies the chan_sip names which many years of experience has told me was a bad choice of names. This early in the morning I&#39;m unable to come up with a good suggestion, so I leave that to someone else.</pre>
 </blockquote>





 <p>On September 18th, 2013, 1:45 p.m. UTC, <b>Mark Michelson</b> wrote:</p>
 <blockquote style="margin-left: 1em; border-left: 2px solid #d0d0d0; padding-left: 10px;">
  <pre style="white-space: pre-wrap; white-space: -moz-pre-wrap; white-space: -pre-wrap; white-space: -o-pre-wrap; word-wrap: break-word;">I have a couple of ideas about this.

1.

Matt had an idea on the dev list to wrap the functionality of PJSIP_HEADER, PJSIPAddHeader, and PJSIPRemoveHeader into a single function, 
PJSIP_HEADER. When used in read mode (e.g. Set(MYVAR=${PJSIP_HEADER(CSeq)})), the function would work like it currently does.

When used in write mode, though, you could do something like:

Set(PJSIP_HEADER(X-Custom-Header)=Hello)

in order to add &quot;X-Customer-Header: Hello&quot; to the outbound INVITE. You could do

Set(PJSIP_HEADER(X-Custom-Header)=)

in order to remove the X-Custom-Header from the outbound INVITE [1].

We could expand upon this some to incorporate your idea without the need to add more functions. The PJSIP_HEADER function could have a second parameter that states what methods the header should be added to. For instance:

Set(PJSIP_HEADER(X-Custom-Header, BYE)=GoodBye)

would place &quot;X-Custom-Header: GoodBye&quot; onto BYE requests on the dialog. If no method is provided, we could interpret a default value of &quot;INVITE&quot; since this is the previous behavior of the SIPAddHeader function.

This would at least provide a way of adding custom headers to various requests within the dialog. Responses would be more difficult, since presumably you may have separate custom headers that you want for provisional responses, 200 OKs, and other final responses. You may also have different custom headers you would want to use for different request methods. However, some syntax could be worked out that would allow for the appropriate level of customization.

[1] This method of removing headers would not allow for setting headers with no value, which is strange but allowable AFAICT under RFC 3261&#39;s ABNF (depending on the header type). 

2.

We could keep the PJSIP_HEADER function, and PJSIPAddHeader and PJSIPRemoveHeader application syntax, but change their intended usage. Currently, as you have pointed out, they only apply to INVITEs, and the functions are intended to be used in the same dialplan snippets that handle incoming calls.

Session supplements have the ability to be called into when any request or response is sent or received during an INVITE-intiated dialog. A session supplement could call a configured dialplan gosub when a request or response is received or sent. Within this gosub, a user could use PJSIPAddHeader and PJSIPRemoveHeader in order to add or remove headers from the request or response that is about to be sent out. They could use PJSIP_HEADER in order to read the headers in the current request or response that is being sent/received.


Honestly, approach 2 sounds really cool to me, but it may be too much of a departure from what people are used to. It also, unfortunately, would require some significant rework from George on this patch. Approach 1 is less dynamic, but it is also more familiar. It also means that the initial work George is doing here would be valid; we just would need to expand on it once the initial groundwork is laid.


What do you think?</pre>
 </blockquote>





 <p>On September 18th, 2013, 3:28 p.m. UTC, <b>George Joseph</b> wrote:</p>
 <blockquote style="margin-left: 1em; border-left: 2px solid #d0d0d0; padding-left: 10px;">
  <pre style="white-space: pre-wrap; white-space: -moz-pre-wrap; white-space: -pre-wrap; white-space: -o-pre-wrap; word-wrap: break-word;">My 2 cents...  This sounds like an opportunity to do the right thing for the future so don&#39;t worry about the work on my part.  I&#39;ve got the time and can dig in when you guys decide on the direction.
</pre>
 </blockquote>





 <p>On September 18th, 2013, 5:05 p.m. UTC, <b>Matt Jordan</b> wrote:</p>
 <blockquote style="margin-left: 1em; border-left: 2px solid #d0d0d0; padding-left: 10px;">
  <pre style="white-space: pre-wrap; white-space: -moz-pre-wrap; white-space: -pre-wrap; white-space: -o-pre-wrap; word-wrap: break-word;">Well, *I* obviously like my idea :-)

I think option #2 is neat, but honestly, it isn&#39;t precluded by option #1. Having dialplan callbacks that called when certain things happen in Asterisk is something we&#39;ve talked about from time to time. Using PJSIP_HEADER in such a callback would just change what request the function applies to by default.

I&#39;d say go for option #1, and let&#39;s keep option #2 on the table as a good improvement to go do.

Olle: What do you think?</pre>
 </blockquote>





 <p>On September 23rd, 2013, 4:50 p.m. UTC, <b>George Joseph</b> wrote:</p>
 <blockquote style="margin-left: 1em; border-left: 2px solid #d0d0d0; padding-left: 10px;">
  <pre style="white-space: pre-wrap; white-space: -moz-pre-wrap; white-space: -pre-wrap; white-space: -o-pre-wrap; word-wrap: break-word;">Any more thoughts?  How about I start down the road of option 1 for INVITEs, get that accepted and merged, then follow it up with the additional parameter to select which messages to apply to?</pre>
 </blockquote>








</blockquote>

<pre style="white-space: pre-wrap; white-space: -moz-pre-wrap; white-space: -pre-wrap; white-space: -o-pre-wrap; word-wrap: break-word;">Sounds good to me.
</pre>
<br />










<p>- Matt</p>


<br />
<p>On September 17th, 2013, 9:35 p.m. UTC, George Joseph wrote:</p>








<table bgcolor="#fefadf" width="100%" cellspacing="0" cellpadding="8" style="background-image: url('https://reviewboard.asterisk.org/static/rb/images/review_request_box_top_bg.png'); background-position: left top; background-repeat: repeat-x; border: 1px black solid;">
 <tr>
  <td>

<div>Review request for Asterisk Developers and Mark Michelson.</div>
<div>By George Joseph.</div>


<p style="color: grey;"><i>Updated Sept. 17, 2013, 9:35 p.m.</i></p>







<div style="margin-top: 1.5em;">
 <b style="color: #575012; font-size: 10pt; margin-top: 1.5em;">Bugs: </b>


 <a href="https://issues.asterisk.org/jira/browse/ASTERISK-22498">ASTERISK-22498</a>


</div>



<div style="margin-top: 1.5em;">
 <b style="color: #575012; font-size: 10pt;">Repository: </b>
Asterisk
</div>


<h1 style="color: #575012; font-size: 10pt; margin-top: 1.5em;">Description </h1>
 <table width="100%" bgcolor="#ffffff" cellspacing="0" cellpadding="10" style="border: 1px solid #b8b5a0">
 <tr>
  <td>
   <pre style="margin: 0; padding: 0; white-space: pre-wrap; white-space: -moz-pre-wrap; white-space: -pre-wrap; white-space: -o-pre-wrap; word-wrap: break-word;">For PJSIP_HEADER, an incoming supplemental session callback is registered that takes the pjsip_hdrs from the incoming session and stores them in a linked list in the session datastore.  Calls to PJSIP_HEADER traverse over the list and return the nth matching header where &#39;n&#39; is the &#39;number&#39; argument to the function.

For PJSIPAddHeader, the first call creates a datastore and linked list and adds the datastore to the session.  The header is then created as a pjsip_hdr and added to the list.  An outgoing supplemental session callback then traverses the list and adds the headers to the outgoing pjsip_msg.

For PJSIPRemoveHeader, the list created with PJSIPAddHeader is traversed and all matching entries are removed.  As with SIPRemoveHeader, an empty arguments removes all headers previously added.

Rather than cloning the incoming pjsip_msg or using pjsip_msg to accumulate the outgoing headers, I used a simple AST_LIST. There was a lot of overhead with the clone functions and some tricky behavior with the pjsip_msg/pjsip_hdr internal lists. Using the AST_LISTs cut down on both instructions and memory.  

All memory allocation is from the pj_pool attached to the session.</pre>
  </td>
 </tr>
</table>


<h1 style="color: #575012; font-size: 10pt; margin-top: 1.5em;">Testing </h1>
<table width="100%" bgcolor="#ffffff" cellspacing="0" cellpadding="10" style="border: 1px solid #b8b5a0">
 <tr>
  <td>
   <pre style="margin: 0; padding: 0; white-space: pre-wrap; white-space: -moz-pre-wrap; white-space: -pre-wrap; white-space: -o-pre-wrap; word-wrap: break-word;">Tested successfully...
PJSIP_HEADER return the full value of nth specified header from either the incoming session, or headers previously added to the outgoing session by PJSIPHeader.
PJSIP_HEADER fails if there was no header specified in the function call.
PJSIP_HEADER fails if there was no datastore on the incoming session (should never happen).
PJSIP_HEADER fails if the nth header wasn&#39;t found.

PJSIPAddHeader adds a pjsip_hdr structure to the linked list when the input string is properly formatted as &quot;header_name:\s*header_value&quot;.
PJSIPAddHeader fails if no &#39;:&#39; was found in the input string.
PJSIPAddHeader fails if after parsing either the header name or value is empty.

PJSIPRemoveHeader removes all matching headers from the linked list when a partial header name is specified.
PJSIPRemoveHeader removes all matching headers from the linked list when a full header is specified with a trailing &#39;:&#39;.
PJSIPRemoveHeader removes all previously added header from the linked list when no header is specified.
PJSIPRemoveHeader returns successfully (silently) if there was no linked list.


</pre>
  </td>
 </tr>
</table>


<h1 style="color: #575012; font-size: 10pt; margin-top: 1.5em;">Diffs</b> </h1>
<ul style="margin-left: 3em; padding-left: 0;">

 <li>/branches/12/res/res_pjsip_header_funcs.c <span style="color: grey">(PRE-CREATION)</span></li>

</ul>

<p><a href="https://reviewboard.asterisk.org/r/2858/diff/" style="margin-left: 3em;">View Diff</a></p>







  </td>
 </tr>
</table>








  </div>
 </body>
</html>