--- main/features.c.orig        2014-07-13 02:19:41.645523053 +0000
+++ main/features.c     2014-08-10 19:51:55.845183382 +0000
@@ -443,34 +443,49 @@
                        <ref type="function">FEATUREMAP</ref>
                </see-also>
        </function>
-       <function name="FEATUREMAP" language="en_US">
+       <function name="CHECKPARKINGSLOT" language="en_US">
                <synopsis>
-                       Get or set a feature map to a given value on a specific channel.
+                       Check whether a parking slot in a parking lot is currently occupied.
                </synopsis>
                <syntax>
-                       <parameter name="feature_name" required="true">
-                               <para>The allowed values are:</para>
-                               <enumlist>
-                                       <enum name="atxfer"><para>Attended Transfer</para></enum>
-                                       <enum name="blindxfer"><para>Blind Transfer</para></enum>
-                                       <enum name="automon"><para>Auto Monitor</para></enum>
-                                       <enum name="disconnect"><para>Call Disconnect</para></enum>
-                                       <enum name="parkcall"><para>Park Call</para></enum>
-                                       <enum name="automixmon"><para>Auto MixMonitor</para></enum>
-                               </enumlist>
+                       <parameter name="parking_slot" required="true">
+                       </parameter>
+                       <parameter name="parking_lot" required="true">
                        </parameter>
                </syntax>
                <description>
-                       <para>When this function is used as a read, it will get the current
-                       digit sequence mapped to the specified feature for this channel.  This
-                       value will be the one configured in features.conf if a channel specific
-                       value has not been set.  This function can also be used to set a channel
-                       specific value for a feature mapping.</para>
+                       <para>This function returns true if the current parking slot
+                       in the parking lot space is occupied.</para>
                </description>
-               <see-also>
-                       <ref type="function">FEATURE</ref>
-               </see-also>
        </function>
+        <function name="FEATUREMAP" language="en_US">
+                <synopsis>
+                        Get or set a feature map to a given value on a specific channel.
+                </synopsis>
+                <syntax>
+                        <parameter name="feature_name" required="true">
+                                <para>The allowed values are:</para>
+                                <enumlist>
+                                        <enum name="atxfer"><para>Attended Transfer</para></enum>
+                                        <enum name="blindxfer"><para>Blind Transfer</para></enum>
+                                        <enum name="automon"><para>Auto Monitor</para></enum>
+                                        <enum name="disconnect"><para>Call Disconnect</para></enum>
+                                        <enum name="parkcall"><para>Park Call</para></enum>
+                                        <enum name="automixmon"><para>Auto MixMonitor</para></enum>
+                                </enumlist>
+                        </parameter>
+                </syntax>
+                <description>
+                        <para>When this function is used as a read, it will get the current
+                        digit sequence mapped to the specified feature for this channel.  This
+                        value will be the one configured in features.conf if a channel specific
+                        value has not been set.  This function can also be used to set a channel
+                        specific value for a feature mapping.</para>
+                </description>
+                <see-also>
+                        <ref type="function">FEATURE</ref>
+                </see-also>
+        </function>
        <managerEvent language="en_US" name="ParkedCallTimeOut">
                <managerEventInstance class="EVENT_FLAG_CALL">
                        <synopsis>Raised when a parked call times out.</synopsis>
@@ -9030,6 +9045,116 @@
        return 0;
 }
 
+
+/*! \brief  Dial plan function to get the parking log channel */
+static int func_get_parkingslot_channel(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t len)
+{
+
+       struct ast_parkinglot *parkinglot;
+       struct parkeduser *pu;
+       const char *content = NULL;
+       int parking_space = -1;
+
+        AST_DECLARE_APP_ARGS(args,
+                AST_APP_ARG(parking_space);
+                AST_APP_ARG(parking_lot);
+                AST_APP_ARG(other);     /* Any remining unused arguments */
+        );
+
+        /* Parse the arguments. */
+        AST_STANDARD_APP_ARGS(args, data);
+
+        if (args.argc < 2) {
+                /* Didn't receive enough arguments to do anything */
+                ast_log(LOG_ERROR,
+                        "Usage: %s(<parking_space>,<parking_lot>)\n",
+                        cmd);
+                return -1;
+        }
+
+       parkinglot = find_parkinglot(args.parking_lot);
+       if (!parkinglot) {
+               ast_debug(1, "GETPARKINGSLOTCHANNEL Function Call Failed as parking lot %s does not exist.\n",
+                       args.parking_lot);
+       } else {
+
+               sscanf(args.parking_space, "%30d", &parking_space);
+
+               /* Check if parking space is occupied. */
+               AST_LIST_LOCK(&parkinglot->parkings);
+               AST_LIST_TRAVERSE_SAFE_BEGIN(&parkinglot->parkings, pu, list) {
+                       if (pu->parkingnum == parking_space) {
+                               content = ast_channel_name(pu->chan);
+                               ast_copy_string(buf, content, len); 
+                               break;
+                       }
+               }
+               AST_LIST_TRAVERSE_SAFE_END;
+               AST_LIST_UNLOCK(&parkinglot->parkings);
+
+       }
+
+       parkinglot_unref(parkinglot);
+
+       return 0;
+
+}
+
+/*! \brief  Dial plan function to check if parking slot is occupied */
+static int func_check_parkingslot(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t len)
+{
+
+       struct ast_parkinglot *parkinglot;
+       struct parkeduser *pu;
+       int parking_space = -1;
+       int ret = 0;
+
+        AST_DECLARE_APP_ARGS(args,
+                AST_APP_ARG(parking_space);
+                AST_APP_ARG(parking_lot);
+                AST_APP_ARG(other);     /* Any remining unused arguments */
+        );
+
+        /* Parse the arguments. */
+        AST_STANDARD_APP_ARGS(args, data);
+
+        if (args.argc < 2) {
+                /* Didn't receive enough arguments to do anything */
+                ast_log(LOG_ERROR,
+                        "Usage: %s(<parking_space>,<parking_lot>)\n",
+                        cmd);
+                return -1;
+        }
+
+       parkinglot = find_parkinglot(args.parking_lot);
+       if (!parkinglot) {
+               ast_debug(1, "CHECKPARKINGSLOT Function Call Failed as parking lot %s does not exist.\n",
+                       args.parking_lot);
+       } else {
+
+               sscanf(args.parking_space, "%30d", &parking_space);
+
+               /* Check if parking space is occupied. */
+               AST_LIST_LOCK(&parkinglot->parkings);
+               AST_LIST_TRAVERSE_SAFE_BEGIN(&parkinglot->parkings, pu, list) {
+                       if (pu->parkingnum == parking_space) {
+                               ret = 1;
+                               break;
+                       }
+               }
+               AST_LIST_TRAVERSE_SAFE_END;
+               AST_LIST_UNLOCK(&parkinglot->parkings);
+
+       }
+
+       parkinglot_unref(parkinglot);
+
+       ast_copy_string(buf, ret ? "1" : "0" , len);
+
+       return 0;
+
+}
+
 static struct ast_custom_function feature_function = {
        .name = "FEATURE",
        .read = feature_read,
@@ -9042,6 +9167,16 @@
        .write = featuremap_write
 };
 
+static struct ast_custom_function checkparkingslot_function = {
+        .name = "CHECKPARKINGSLOT",
+        .read = func_check_parkingslot,
+};
+
+static struct ast_custom_function getparkingslotchannel_function = {
+        .name = "GETPARKINGSLOTCHANNEL",
+        .read = func_get_parkingslot_channel,
+};
+
 /*! \internal \brief Clean up resources on Asterisk shutdown */
 static void features_shutdown(void)
 {
@@ -9049,6 +9184,8 @@
        ast_devstate_prov_del("Park");
        ast_custom_function_unregister(&featuremap_function);
        ast_custom_function_unregister(&feature_function);
+       ast_custom_function_unregister(&checkparkingslot_function);
+       ast_custom_function_unregister(&getparkingslotchannel_function);
        ast_manager_unregister("Bridge");
        ast_manager_unregister("Park");
        ast_manager_unregister("Parkinglots");
@@ -9096,8 +9233,11 @@
        }
        res |= __ast_custom_function_register(&feature_function, NULL);
        res |= __ast_custom_function_register(&featuremap_function, NULL);
+       res |= __ast_custom_function_register(&checkparkingslot_function, NULL);
+       res |= __ast_custom_function_register(&getparkingslotchannel_function, NULL);
 
        res |= ast_devstate_prov_add("Park", metermaidstate);
+
 #if defined(TEST_FRAMEWORK)
        res |= AST_TEST_REGISTER(features_test);
 #endif /* defined(TEST_FRAMEWORK) */