<p>George Joseph <strong>merged</strong> this change.</p><p><a href="https://gerrit.asterisk.org/9375">View Change</a></p><div style="white-space:pre-wrap">Approvals:
  Kevin Harwell: Looks good to me, but someone else must approve
  Richard Mudgett: Looks good to me, approved
  George Joseph: Approved for Submit

</div><pre style="font-family: monospace,monospace; white-space: pre-wrap;">res_parking: Add dialplan function for lot channel<br><br>This commit adds a new function to res_parking.<br><br>This function, PARK_GET_CHANNEL allows the retrieval<br>of the channel name of the channel occupying the parking slot.<br><br>ASTERISK-22825 #close<br><br>Change-Id: Idba6ae55b8a53f734238cb3d995cedb95c0e7b74<br>---<br>M res/parking/parking_bridge_features.c<br>M res/parking/parking_controller.c<br>M res/parking/res_parking.h<br>3 files changed, 107 insertions(+), 0 deletions(-)<br><br></pre><pre style="font-family: monospace,monospace; white-space: pre-wrap;"><span>diff --git a/res/parking/parking_bridge_features.c b/res/parking/parking_bridge_features.c</span><br><span>index 2770233..cbc23fa 100644</span><br><span>--- a/res/parking/parking_bridge_features.c</span><br><span>+++ b/res/parking/parking_bridge_features.c</span><br><span>@@ -30,10 +30,12 @@</span><br><span> #include "asterisk/astobj2.h"</span><br><span> #include "asterisk/logger.h"</span><br><span> #include "asterisk/pbx.h"</span><br><span style="color: hsl(120, 100%, 40%);">+#include "asterisk/app.h"</span><br><span> #include "asterisk/bridge.h"</span><br><span> #include "asterisk/bridge_internal.h"</span><br><span> #include "asterisk/bridge_channel.h"</span><br><span> #include "asterisk/bridge_features.h"</span><br><span style="color: hsl(120, 100%, 40%);">+#include "asterisk/conversions.h"</span><br><span> #include "asterisk/features.h"</span><br><span> #include "asterisk/say.h"</span><br><span> #include "asterisk/datastore.h"</span><br><span>@@ -42,6 +44,24 @@</span><br><span> #include "asterisk/core_local.h"</span><br><span> #include "asterisk/causes.h"</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+/*** DOCUMENTATION</span><br><span style="color: hsl(120, 100%, 40%);">+        <function name="PARK_GET_CHANNEL" language="en_US"></span><br><span style="color: hsl(120, 100%, 40%);">+         <synopsis></span><br><span style="color: hsl(120, 100%, 40%);">+                      Get the channel name of an occupied parking space in a parking lot.</span><br><span style="color: hsl(120, 100%, 40%);">+           </synopsis></span><br><span style="color: hsl(120, 100%, 40%);">+                     <syntax></span><br><span style="color: hsl(120, 100%, 40%);">+                                <parameter name="parking_space" required="true"></span><br><span style="color: hsl(120, 100%, 40%);">+                            </parameter></span><br><span style="color: hsl(120, 100%, 40%);">+                            <parameter name="parking_lot" required="true"></span><br><span style="color: hsl(120, 100%, 40%);">+                              </parameter></span><br><span style="color: hsl(120, 100%, 40%);">+                    </syntax></span><br><span style="color: hsl(120, 100%, 40%);">+               <description></span><br><span style="color: hsl(120, 100%, 40%);">+                   <para>This function returns the channel of the specified parking space</span><br><span style="color: hsl(120, 100%, 40%);">+                          if the parking lot space is occupied.</para></span><br><span style="color: hsl(120, 100%, 40%);">+                    </description></span><br><span style="color: hsl(120, 100%, 40%);">+  </function></span><br><span style="color: hsl(120, 100%, 40%);">+***/</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span> struct parked_subscription_datastore {</span><br><span>  struct stasis_subscription *parked_subscription;</span><br><span> };</span><br><span>@@ -704,6 +724,60 @@</span><br><span>        }</span><br><span> }</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+/*! \brief  Dial plan function to get the parking lot channel of an occupied parking lot */</span><br><span style="color: hsl(120, 100%, 40%);">+static int func_get_parkingslot_channel(struct ast_channel *chan, const char *function, char *data, char *buf, size_t len)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+        RAII_VAR(struct parked_user *, pu, NULL, ao2_cleanup);</span><br><span style="color: hsl(120, 100%, 40%);">+        RAII_VAR(struct parking_lot *, lot, NULL, ao2_cleanup);</span><br><span style="color: hsl(120, 100%, 40%);">+       unsigned int space = 0;</span><br><span style="color: hsl(120, 100%, 40%);">+       const char *content = NULL;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ AST_DECLARE_APP_ARGS(args,</span><br><span style="color: hsl(120, 100%, 40%);">+            AST_APP_ARG(parking_space);</span><br><span style="color: hsl(120, 100%, 40%);">+           AST_APP_ARG(parking_lot);</span><br><span style="color: hsl(120, 100%, 40%);">+             AST_APP_ARG(other);</span><br><span style="color: hsl(120, 100%, 40%);">+   );</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+  /* Parse the arguments. */</span><br><span style="color: hsl(120, 100%, 40%);">+    AST_STANDARD_APP_ARGS(args, data);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+  if (args.argc < 2) {</span><br><span style="color: hsl(120, 100%, 40%);">+               /* Didn't receive enough arguments to do anything */</span><br><span style="color: hsl(120, 100%, 40%);">+              ast_log(LOG_ERROR, "Usage: %s(<parking_space>,<parking_lot>)\n",</span><br><span style="color: hsl(120, 100%, 40%);">+                        function);</span><br><span style="color: hsl(120, 100%, 40%);">+            return -1;</span><br><span style="color: hsl(120, 100%, 40%);">+    }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   lot = parking_lot_find_by_name(args.parking_lot);</span><br><span style="color: hsl(120, 100%, 40%);">+     if (!lot) {</span><br><span style="color: hsl(120, 100%, 40%);">+           ast_log(LOG_ERROR, "Could not find parking lot: '%s'\n", args.parking_lot);</span><br><span style="color: hsl(120, 100%, 40%);">+         return -1;</span><br><span style="color: hsl(120, 100%, 40%);">+    }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   if (!ast_strlen_zero(args.parking_space)) {</span><br><span style="color: hsl(120, 100%, 40%);">+           if (ast_str_to_uint(args.parking_space, &space) != 0) {</span><br><span style="color: hsl(120, 100%, 40%);">+                   ast_log(LOG_ERROR, "value '%s' for parking_space argument is invalid. Must be an integer greater than 0.\n",</span><br><span style="color: hsl(120, 100%, 40%);">+                                args.parking_space);</span><br><span style="color: hsl(120, 100%, 40%);">+                  return -1;</span><br><span style="color: hsl(120, 100%, 40%);">+            }</span><br><span style="color: hsl(120, 100%, 40%);">+     }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   pu = parking_lot_inspect_parked_user(lot, space);</span><br><span style="color: hsl(120, 100%, 40%);">+     if (!pu) {</span><br><span style="color: hsl(120, 100%, 40%);">+            return -1;</span><br><span style="color: hsl(120, 100%, 40%);">+    }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   content = ast_channel_name(pu->chan);</span><br><span style="color: hsl(120, 100%, 40%);">+      ast_copy_string(buf, content, len);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ return 0;</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+static struct ast_custom_function getparkingslotchannel_function = {</span><br><span style="color: hsl(120, 100%, 40%);">+  .name = "PARK_GET_CHANNEL",</span><br><span style="color: hsl(120, 100%, 40%);">+ .read = func_get_parkingslot_channel,</span><br><span style="color: hsl(120, 100%, 40%);">+};</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span> struct ast_parking_bridge_feature_fn_table parking_provider = {</span><br><span>       .module_version = PARKING_MODULE_VERSION,</span><br><span>    .module_name = __FILE__,</span><br><span>@@ -717,12 +791,15 @@</span><br><span> {</span><br><span>        ast_bridge_features_unregister(AST_BRIDGE_BUILTIN_PARKCALL);</span><br><span>         ast_parking_unregister_bridge_features(parking_provider.module_name);</span><br><span style="color: hsl(120, 100%, 40%);">+ ast_custom_function_unregister(&getparkingslotchannel_function);</span><br><span> }</span><br><span> </span><br><span> int load_parking_bridge_features(void)</span><br><span> {</span><br><span>         parking_provider.module = AST_MODULE_SELF;</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+        ast_custom_function_register(&getparkingslotchannel_function);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span>         if (ast_parking_register_bridge_features(&parking_provider)) {</span><br><span>           return -1;</span><br><span>   }</span><br><span>diff --git a/res/parking/parking_controller.c b/res/parking/parking_controller.c</span><br><span>index 9e9e540..365acdd 100644</span><br><span>--- a/res/parking/parking_controller.c</span><br><span>+++ b/res/parking/parking_controller.c</span><br><span>@@ -163,6 +163,23 @@</span><br><span>        return 0;</span><br><span> }</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+struct parked_user *parking_lot_inspect_parked_user(struct parking_lot *lot, int target)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+       struct parked_user *user;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   if (target < 0) {</span><br><span style="color: hsl(120, 100%, 40%);">+          user = ao2_callback(lot->parked_users, 0, NULL, NULL);</span><br><span style="color: hsl(120, 100%, 40%);">+     } else {</span><br><span style="color: hsl(120, 100%, 40%);">+              user = ao2_callback(lot->parked_users, 0, retrieve_parked_user_targeted, &target);</span><br><span style="color: hsl(120, 100%, 40%);">+     }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   if (!user) {</span><br><span style="color: hsl(120, 100%, 40%);">+          return NULL;</span><br><span style="color: hsl(120, 100%, 40%);">+  }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   return user;</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span> struct parked_user *parking_lot_retrieve_parked_user(struct parking_lot *lot, int target)</span><br><span> {</span><br><span>  RAII_VAR(struct parked_user *, user, NULL, ao2_cleanup);</span><br><span>diff --git a/res/parking/res_parking.h b/res/parking/res_parking.h</span><br><span>index 3c34e5c..79fb97f 100644</span><br><span>--- a/res/parking/res_parking.h</span><br><span>+++ b/res/parking/res_parking.h</span><br><span>@@ -196,6 +196,19 @@</span><br><span> int parking_lot_get_space(struct parking_lot *lot, int target_override);</span><br><span> </span><br><span> /*!</span><br><span style="color: hsl(120, 100%, 40%);">+ * \brief Determine if there is a parked user in a parking space and return it if there is.</span><br><span style="color: hsl(120, 100%, 40%);">+ *</span><br><span style="color: hsl(120, 100%, 40%);">+ * \param lot Parking lot being pulled from</span><br><span style="color: hsl(120, 100%, 40%);">+ * \param target If < 0   search for the first occupied space in the parking lot</span><br><span style="color: hsl(120, 100%, 40%);">+ *               If >= 0  Only pull from the indicated target</span><br><span style="color: hsl(120, 100%, 40%);">+ *</span><br><span style="color: hsl(120, 100%, 40%);">+ * \retval NULL if no parked user could be pulled from the requested parking lot at the requested parking space</span><br><span style="color: hsl(120, 100%, 40%);">+ * \retval reference to the requested parked user</span><br><span style="color: hsl(120, 100%, 40%);">+ *</span><br><span style="color: hsl(120, 100%, 40%);">+ */</span><br><span style="color: hsl(120, 100%, 40%);">+struct parked_user *parking_lot_inspect_parked_user(struct parking_lot *lot, int target);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+/*!</span><br><span>  * \since 12.0.0</span><br><span>  * \brief Determine if there is a parked user in a parking space and pull it from the parking lot if there is.</span><br><span>  *</span><br><span></span><br></pre><p>To view, visit <a href="https://gerrit.asterisk.org/9375">change 9375</a>. To unsubscribe, or for help writing mail filters, visit <a href="https://gerrit.asterisk.org/settings">settings</a>.</p><div itemscope itemtype="http://schema.org/EmailMessage"><div itemscope itemprop="action" itemtype="http://schema.org/ViewAction"><link itemprop="url" href="https://gerrit.asterisk.org/9375"/><meta itemprop="name" content="View Change"/></div></div>

<div style="display:none"> Gerrit-Project: asterisk </div>
<div style="display:none"> Gerrit-Branch: master </div>
<div style="display:none"> Gerrit-MessageType: merged </div>
<div style="display:none"> Gerrit-Change-Id: Idba6ae55b8a53f734238cb3d995cedb95c0e7b74 </div>
<div style="display:none"> Gerrit-Change-Number: 9375 </div>
<div style="display:none"> Gerrit-PatchSet: 6 </div>
<div style="display:none"> Gerrit-Owner: Joshua Elson <joshelson@gmail.com> </div>
<div style="display:none"> Gerrit-Reviewer: Alexei Gradinari <alex2grad@gmail.com> </div>
<div style="display:none"> Gerrit-Reviewer: George Joseph <gjoseph@digium.com> </div>
<div style="display:none"> Gerrit-Reviewer: Jenkins2 </div>
<div style="display:none"> Gerrit-Reviewer: Joshua Elson <joshelson@gmail.com> </div>
<div style="display:none"> Gerrit-Reviewer: Kevin Harwell <kharwell@digium.com> </div>
<div style="display:none"> Gerrit-Reviewer: Richard Mudgett <rmudgett@digium.com> </div>