<p>Joshua Elson has uploaded this change for <strong>review</strong>.</p><p><a href="https://gerrit.asterisk.org/9375">View Change</a></p><pre style="font-family: monospace,monospace; white-space: pre-wrap;">res_parking: Add dialplan functions for lot state and channel<br><br>This commit adds two new functions to res_parking.<br><br>The fist, CHECK_PARKING_SLOT, allows the determination of<br>whether a particular parking lot is in use from dialplan.<br><br>Additionally, GET_PARKING_SLOT_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>1 file changed, 150 insertions(+), 0 deletions(-)<br><br></pre><pre style="font-family: monospace,monospace; white-space: pre-wrap;">git pull ssh://gerrit.asterisk.org:29418/asterisk refs/changes/75/9375/1</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..042222c 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,6 +30,7 @@</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>@@ -42,6 +43,40 @@</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="CHECK_PARKING_SLOT" language="en_US"></span><br><span style="color: hsl(120, 100%, 40%);">+                <synopsis></span><br><span style="color: hsl(120, 100%, 40%);">+                        Check whether a parking slot in a parking lot is currently occupied.</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 true if the current parking slot</span><br><span style="color: hsl(120, 100%, 40%);">+                        in 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%);">+        <function name="GET_PARKING_SLOT_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 slot 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 true if the current parking slot</span><br><span style="color: hsl(120, 100%, 40%);">+                        in 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 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 +739,116 @@</span><br><span>       }</span><br><span> }</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+static int func_check_parking_slot (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 parking_lot *, lot, NULL, ao2_cleanup);</span><br><span style="color: hsl(120, 100%, 40%);">+       int space = -1;</span><br><span style="color: hsl(120, 100%, 40%);">+       int preferred_space = -1;</span><br><span style="color: hsl(120, 100%, 40%);">+     int ret = 0;</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,</span><br><span style="color: hsl(120, 100%, 40%);">+                    "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) || sscanf(args.parking_space, "%30d", &space) != 1) {</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%);">+   ao2_lock(lot);</span><br><span style="color: hsl(120, 100%, 40%);">+        preferred_space = parking_lot_get_space(lot, space);</span><br><span style="color: hsl(120, 100%, 40%);">+  ao2_unlock(lot);</span><br><span style="color: hsl(120, 100%, 40%);">+      </span><br><span style="color: hsl(120, 100%, 40%);">+      if (space == -1 || preferred_space != space) {</span><br><span style="color: hsl(120, 100%, 40%);">+                ret = 1; /* Lot is full */</span><br><span style="color: hsl(120, 100%, 40%);">+    } else {</span><br><span style="color: hsl(120, 100%, 40%);">+              ret = 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%);">+   ast_copy_string(buf, ret ? "1" : "0" , 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%);">+</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%);">+       int space = -1;</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,</span><br><span style="color: hsl(120, 100%, 40%);">+                    "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 (sscanf(args.parking_space, "%d", &space) != 1 || 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", 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_retrieve_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%);">+</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 = "GET_PARKING_SLOT_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 style="color: hsl(120, 100%, 40%);">+static struct ast_custom_function check_parking_slot_function = {</span><br><span style="color: hsl(120, 100%, 40%);">+  .name = "CHECK_PARKING_SLOT",</span><br><span style="color: hsl(120, 100%, 40%);">+       .read = func_check_parking_slot,</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 +862,17 @@</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(&check_parking_slot_function);</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(&check_parking_slot_function);</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></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: newchange </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: 1 </div>
<div style="display:none"> Gerrit-Owner: Joshua Elson <joshelson@gmail.com> </div>