<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/4190/">https://reviewboard.asterisk.org/r/4190/</a>
</td>
</tr>
</table>
<br />
<blockquote style="margin-left: 1em; border-left: 2px solid #d0d0d0; padding-left: 10px;">
<p style="margin-top: 0;">On November 24th, 2014, 3:47 p.m. UTC, <b>Joshua Colp</b> wrote:</p>
<blockquote style="margin-left: 1em; border-left: 2px solid #d0d0d0; padding-left: 10px;">
<table width="100%" border="0" bgcolor="white" style="border: 1px solid #C0C0C0; border-collapse: collapse; margin: 2px padding: 2px;">
<thead>
<tr>
<th colspan="4" bgcolor="#F0F0F0" style="border-bottom: 1px solid #C0C0C0; font-size: 9pt; padding: 4px 8px; text-align: left;">
<a href="https://reviewboard.asterisk.org/r/4190/diff/2/?file=69049#file69049line295" style="color: black; font-weight: bold; text-decoration: underline;">branches/12/res/res_pjsip_config_wizard.c</a>
<span style="font-weight: normal;">
(Diff revision 2)
</span>
</th>
</tr>
</thead>
<tbody>
<tr>
<th bgcolor="#b1ebb0" style="border-right: 1px solid #C0C0C0;" align="right"><font size="2"></font></th>
<td bgcolor="#c5ffc4" width="50%"><pre style="font-size: 8pt; line-height: 140%; margin: 0; "></pre></td>
<th bgcolor="#b1ebb0" style="border-left: 1px solid #C0C0C0; border-right: 1px solid #C0C0C0;" align="right"><font size="2">295</font></th>
<td bgcolor="#c5ffc4" width="50%"><pre style="font-size: 8pt; line-height: 140%; margin: 0; "><span class="tb"> </span><span class="n">ast_variable_list_append</span><span class="p">(</span><span class="o">&</span><span class="n">vars</span><span class="p">,</span> <span class="n">ast_variable_new</span><span class="p">(</span><span class="s">"@pjsip_wizard"</span><span class="p">,</span> <span class="n">id</span><span class="p">,</span> <span class="s">""</span><span class="p">));</span></pre></td>
</tr>
</tbody>
</table>
<pre style="white-space: pre-wrap; white-space: -moz-pre-wrap; white-space: -pre-wrap; white-space: -o-pre-wrap; word-wrap: break-word;">A question:
If stuff starts falling apart and we run out of memory - how will all of this handle it? Will it be obvious what is going on?</pre>
</blockquote>
<p>On November 24th, 2014, 5:17 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;">Well, there's no checking in ast_variable_new if it fails to allocate memory so asterisk is going to segfault there because it tries to dereference the pointer immediately. I can fix that to return a NULL. Do you want me to spit an error message out there as well? If ast_variable_new can't allocate a few bytes for the variable what are the chances that asterisk will survive long enough to spit that message out?
</pre>
</blockquote>
</blockquote>
<pre style="margin-left: 1em; white-space: pre-wrap; white-space: -moz-pre-wrap; white-space: -pre-wrap; white-space: -o-pre-wrap; word-wrap: break-word;">We should try to make Asterisk as tolerant and graceful as we can.</pre>
<br />
<blockquote style="margin-left: 1em; border-left: 2px solid #d0d0d0; padding-left: 10px;">
<p style="margin-top: 0;">On November 24th, 2014, 3:47 p.m. UTC, <b>Joshua Colp</b> wrote:</p>
<blockquote style="margin-left: 1em; border-left: 2px solid #d0d0d0; padding-left: 10px;">
<table width="100%" border="0" bgcolor="white" style="border: 1px solid #C0C0C0; border-collapse: collapse; margin: 2px padding: 2px;">
<thead>
<tr>
<th colspan="4" bgcolor="#F0F0F0" style="border-bottom: 1px solid #C0C0C0; font-size: 9pt; padding: 4px 8px; text-align: left;">
<a href="https://reviewboard.asterisk.org/r/4190/diff/2/?file=69050#file69050line450" style="color: black; font-weight: bold; text-decoration: underline;">branches/12/res/res_pjsip_endpoint_identifier_ip.c</a>
<span style="font-weight: normal;">
(Diff revision 2)
</span>
</th>
</tr>
</thead>
<tbody style="background-color: #e4d9cb; padding: 4px 8px; text-align: center;">
<tr>
<td colspan="4"><pre style="font-size: 8pt; line-height: 140%; margin: 0; ">static int cli_print_body(void *obj, void *arg, int flags)</pre></td>
</tr>
</tbody>
<tbody>
<tr>
<th bgcolor="#b1ebb0" style="border-right: 1px solid #C0C0C0;" align="right"><font size="2"></font></th>
<td bgcolor="#c5ffc4" width="50%"><pre style="font-size: 8pt; line-height: 140%; margin: 0; "></pre></td>
<th bgcolor="#b1ebb0" style="border-left: 1px solid #C0C0C0; border-right: 1px solid #C0C0C0;" align="right"><font size="2">450</font></th>
<td bgcolor="#c5ffc4" width="50%"><pre style="font-size: 8pt; line-height: 140%; margin: 0; "><span class="tb"> </span><span class="n">ast_sorcery_apply_wizard_mapping</span><span class="p">(</span><span class="n">ast_sip_get_sorcery</span><span class="p">(),</span> <span class="s">"identify"</span><span class="p">,</span> <span class="s">"pjsip_wizard"</span><span class="p">,</span></pre></td>
</tr>
</tbody>
</table>
<pre style="white-space: pre-wrap; white-space: -moz-pre-wrap; white-space: -pre-wrap; white-space: -o-pre-wrap; word-wrap: break-word;">Why does this need to happen here versus in your own wizard module?</pre>
</blockquote>
<p>On November 24th, 2014, 5:17 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;">Chicken and egg. Being a sorcery wizard, this module HAS to load before any of the pjsip modules therefore it has no access to the pjsip sorcery instance. The next trigger point is pjsip sorcery calling the open callback for a specific object type. This will never happen unless the pjsip modules apply the wizard for their types.
</pre>
</blockquote>
</blockquote>
<pre style="margin-left: 1em; white-space: pre-wrap; white-space: -moz-pre-wrap; white-space: -pre-wrap; white-space: -o-pre-wrap; word-wrap: break-word;">Ah, and because you are loading so early you can't use an observer since the object type doesn't exist yet.</pre>
<br />
<p>- Joshua</p>
<br />
<p>On November 18th, 2014, 5:13 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.ab6f3b1072c9.png'); background-position: left top; background-repeat: repeat-x; border: 1px black solid;">
<tr>
<td>
<div>Review request for Asterisk Developers, Joshua Colp and Mark Michelson.</div>
<div>By George Joseph.</div>
<p style="color: grey;"><i>Updated Nov. 18, 2014, 5:13 p.m.</i></p>
<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;">The PJSIP Configuration Wizard allows for creation of simple pjsip scenarios like phone or trunk without having to directly specify individual endpoints, aors, auths, identifies or registrations. The easiest way to demonstrate this is with an example or two from pjsip_wizard.conf.sample...
;============EXAMPLE WIZARD CONFIGURATION FOR A PHONE=======================
; This config would create an endpoint, aor with dynamic contact, inbound
; auth and a phoneprov object.
[myphone]
type = wizard
accepts_auth = yes
accepts_registrations = yes
transport = ipv4
aor/max_contacts = 1
inbound_auth/username = testname
inbound_auth/password = test password
endpoint/allow = ulaw
endpoint/context = default
phoneprov/MAC = 001122aa4455
phoneprov/PROFILE = profile1
;============EXAMPLE WIZARD CONFIGURATION FOR AN ITSP TRUNK=================
; This ITSP has 2 servers available and requires registration.
; This config would create an endpoint, an aor with 2 static contacts, an outbound
; auth, an identify with 2 matches, and 2 registrations.
[mytrunk]
type = wizard
sends_auth = yes
sends_registrations = yes
transport = ipv4
; The number of remote_hosts drives the number of contacts, matches and registrations.
remote_hosts = sip1.myitsp.com:5060,sip2.myitsp.com:5060
outbound_auth/username = testname
outbound_auth/password = test password
endpoint/allow = ulaw
endpoint/context = default
pjsip_wizard.conf.sample has more details.
The history of the wizard approach can be found in the following 2 threads...
http://lists.digium.com/pipermail/asterisk-dev/2014-September/070426.html
http://lists.digium.com/pipermail/asterisk-dev/2014-October/070616.html
THEORY OF OPERATION:
N.B.: The term 'wizard' is used in 2 contexts here. This module implements a sorcery wizard similar to res_sorcery_config and provides the functionality for the PJSIP Configuration Wizard.
The wizard is implemented in a single module but did require a few tweaks to other res_pjsip modules and sorcery itself. There are 2 parts to this module, the config wizard and the sorcery wizard. When the module loads, it registers itself as a sorcery wizard which is implemented in the bottom half of res_pjsip_config_wizard.c. When sorcery calls the wizard's load and reload functions for a specific pjsip object type, the wizard parses through the pjsip_wizard.conf file and creates the appropriate object for each 'wizard' type. For example, if asked to load endpoints, the wizard will parse pjsip_wizard.conf and create an endpoint for each 'wizard' type in the file. This process happens AFTER objects are read from sources defined in sorcery.conf and pjsip.conf. In the end, the pjsip stack is none the wiser about where the objects came from and all AMI, ARI, CLI etc. operate as normal. The only way to differentiate between objects created discretely and those created by the wizard is that the wizard-created ones will all have an extended attribute named '@pjsip_wizard' with a value of the wizard id.
SUMMARY OF CHANGES MADE:
* The new res_pjsip_config_wizard module was created.
* An existing internal sorcery api was exposed as ast_sorcery_apply_wizard_mapping to allow the addition of a new wizard to an object type. The underlying plumbing was already there.
* config_auth, location, pjsip_configuration, res_pjsip_endpoint_identifier_ip, res_pjsip_outbound_registration and res_pjsip_phoneprov_provider were all modified to call ast_sorcery_apply_wizard_mapping after calling ast_sorcery_apply_default.
* res_pjsip_phoneprov_provider needed a little more work to be compatible.
* During troubleshooting I realized that there were no 'pjsip show identify' commands so I added them to res_pjsip_endpoint_identifier. I also plugged an existing CLI reference leak.
RELOADABILITY:
The new module itself cannot be reloaded or unloaded but there's no point to that anyway. It would just unregister as a sorcery wizard and re-register. 'core reload' and 'module reload res_pjsip' work quite well though which is much more important. 'core reload' is the preferred reload mechanism over reloading specific pjsip modules because it reloads all modules so modules such as res_pjsip_outbound_registration know to start registration for newly discovered objects.
BACKWARDS COMPATIBILITY:
This module does not change any existing functionality. Once created by the wizard, pjsip objects are indistinguishable from ones created discretely other than the addition of the '@pjsip_wizard' attribute.
OTHER:
This module does not use sorcery to read its pjsip_wizard.conf file. Since this module implements a sorcery wizard, doing so would have created 'chicken and egg' scenarios which would have been complex to solve. It does use the standard config mechanism though so you can use extconfig.conf to get the config from an external source.
</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;">Test suite tests are available that use the wizard to create objects and AMI to read the results. The results are indistinguishable except the for '@pjsip_wizard' attribute.
I've converted my own PBX to use the wizard approach and phones and trunks operate normally.
</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_phoneprov_provider.c <span style="color: grey">(428167)</span></li>
<li>branches/12/res/res_pjsip_outbound_registration.c <span style="color: grey">(428167)</span></li>
<li>branches/12/res/res_pjsip_endpoint_identifier_ip.c <span style="color: grey">(428167)</span></li>
<li>branches/12/res/res_pjsip_config_wizard.c <span style="color: grey">(PRE-CREATION)</span></li>
<li>branches/12/res/res_pjsip/pjsip_configuration.c <span style="color: grey">(428167)</span></li>
<li>branches/12/res/res_pjsip/pjsip_cli.c <span style="color: grey">(428167)</span></li>
<li>branches/12/res/res_pjsip/location.c <span style="color: grey">(428167)</span></li>
<li>branches/12/res/res_pjsip/config_auth.c <span style="color: grey">(428167)</span></li>
<li>branches/12/main/sorcery.c <span style="color: grey">(428167)</span></li>
<li>branches/12/include/asterisk/sorcery.h <span style="color: grey">(428167)</span></li>
<li>branches/12/configs/pjsip_wizard.conf.sample <span style="color: grey">(PRE-CREATION)</span></li>
</ul>
<p><a href="https://reviewboard.asterisk.org/r/4190/diff/" style="margin-left: 3em;">View Diff</a></p>
</td>
</tr>
</table>
</div>
</body>
</html>