BAL and Maple Release 2.2

Signed-off-by: Shad Ansari <developer@Carbon.local>
diff --git a/bal_release/src/lib/libbalapi/bal_api.c b/bal_release/src/lib/libbalapi/bal_api.c
new file mode 100644
index 0000000..4374fd2
--- /dev/null
+++ b/bal_release/src/lib/libbalapi/bal_api.c
@@ -0,0 +1,658 @@
+/******************************************************************************
+ *
+ *  <:copyright-BRCM:2016:DUAL/GPL:standard
+ *  
+ *     Copyright (c) 2016 Broadcom
+ *     All Rights Reserved
+ *  
+ *  Unless you and Broadcom execute a separate written software license
+ *  agreement governing use of this software, this software is licensed
+ *  to you under the terms of the GNU General Public License version 2
+ *  (the "GPL"), available at http://www.broadcom.com/licenses/GPLv2.php,
+ *  with the following added to such license:
+ *  
+ *     As a special exception, the copyright holders of this software give
+ *     you permission to link this software with independent modules, and
+ *     to copy and distribute the resulting executable under terms of your
+ *     choice, provided that you also meet, for each linked independent
+ *     module, the terms and conditions of the license of that module.
+ *     An independent module is a module which is not derived from this
+ *     software.  The special exception does not apply to any modifications
+ *     of the software.
+ *  
+ *  Not withstanding the above, under no circumstances may you combine
+ *  this software in any way with any other Broadcom software provided
+ *  under a license other than the GPL, without Broadcom's express prior
+ *  written consent.
+ *  
+ *  :>
+ *
+ *****************************************************************************/
+ 
+/**
+ * @file bal_api.c
+ * @brief The BAL Public API
+ *
+ * @addtogroup api
+ */
+
+/*@{*/
+
+/* Project includes */
+#include "bal_api.h"
+#include "bal_msg.h"
+#include "bal_api_worker.h"
+#include "bal_obj_msg_pack_unpack.h"
+#ifdef BAL_MONOLITHIC
+#include <bal_worker.h>
+#endif
+
+#ifdef ENABLE_LOG
+#include <bcm_dev_log.h>
+
+/*
+ * @brief The logging device id for the BAL public API
+ */
+dev_log_id log_id_public_api;
+#endif
+
+/*
+ * @brief The global mgmt queues 
+ * 
+ * These are the queues through which the BAL API communicates with
+ * the core, and vice versa.
+ */
+static bcmos_msg_queue balapi_rsp_queue;
+static bcmos_msg_queue balapi_to_core_queue;
+
+bcmos_msg_queue *p_balapi_rsp_queue;
+bcmos_msg_queue *p_balapi_to_core_queue;
+
+static bcmos_mutex balapi_lock;
+static uint32_t balapi_exchange_id;
+static STAILQ_HEAD(pending_req_list, bcmos_msg) pending_req_list;
+
+static bcmos_task api_rsp_rx_thread;
+static int _bal_ipc_api_rx_handler(long data);
+
+/* Rx polling timeout (us) */
+#define BAL_API_RX_POLL_TIMEOUT         100000
+
+/*****************************************************************************
+ * Initialize the BAL Public API internal data structures
+ *****************************************************************************/
+bcmos_errno bcmbal_api_init(const char *balapi_mgmt_ip_port,
+                            const char *core_mgmt_ip_port)
+{
+    bcmos_errno ret = BCM_ERR_OK;
+    bcmos_msg_queue_parm msg_q_p = {};
+    bcmos_task_parm task_p = {};
+
+#ifdef ENABLE_LOG
+    log_id_public_api = bcm_dev_log_id_register("BAL_API", DEV_LOG_LEVEL_INFO, DEV_LOG_ID_TYPE_BOTH);
+    BUG_ON(log_id_public_api == DEV_LOG_INVALID_ID);
+#endif
+
+    do
+    {
+        STAILQ_INIT(&pending_req_list);
+
+        ret = bcmos_mutex_create(&balapi_lock, 0, "bal_api");
+        if (BCM_ERR_OK != ret)
+        {
+            BCM_LOG(ERROR, log_id_public_api, "Couldn't create BAL API protection mutex\n");
+            break;
+        }
+
+        /* Create BAL API RX management queue - the BAL Public API
+         * exchanges management messages with the BAL core using this queue.
+         */
+        msg_q_p.name = "balapi_mgmt_q";
+        if (NULL != balapi_mgmt_ip_port)
+        {
+            msg_q_p.local_ep_address = balapi_mgmt_ip_port;
+            msg_q_p.remote_ep_address = NULL;
+            msg_q_p.ep_type = BCMOS_MSG_QUEUE_EP_UDP_SOCKET;
+        }
+        else
+        {
+            msg_q_p.ep_type = BCMOS_MSG_QUEUE_EP_LOCAL;
+        }
+        ret = bcmos_msg_queue_create(&balapi_rsp_queue, &msg_q_p);
+        if (BCM_ERR_OK != ret)
+        {
+            BCM_LOG(ERROR, log_id_public_api, "Couldn't create BAL API mgmt queue\n");
+            ret = BCM_ERR_INTERNAL;
+            break;
+        }
+        p_balapi_rsp_queue = &balapi_rsp_queue;
+#ifdef BAL_MONOLITHIC
+        if (NULL == balapi_mgmt_ip_port)
+            p_bal_core_to_api_queue = p_balapi_rsp_queue;
+#endif
+
+        /* Create queue for sending API requests to the core. Only do it if API and core interact via UDP
+         */
+        if (NULL != core_mgmt_ip_port)
+        {
+            msg_q_p.name = "balapi_to_core_q";
+            msg_q_p.local_ep_address = NULL;
+            msg_q_p.remote_ep_address = core_mgmt_ip_port;
+            msg_q_p.ep_type = BCMOS_MSG_QUEUE_EP_UDP_SOCKET;
+
+            ret = bcmos_msg_queue_create(&balapi_to_core_queue, &msg_q_p);
+            if (BCM_ERR_OK != ret)
+            {
+                BCM_LOG(ERROR, log_id_public_api, "Couldn't create BAL API mgmt queue\n");
+                ret = BCM_ERR_INTERNAL;
+                break;
+            }
+            p_balapi_to_core_queue = &balapi_to_core_queue;
+        }
+
+        /* Create BAL API RX thread */
+        task_p.name = "ipc_api_rsp_rx_thread";
+        task_p.priority = TASK_PRIORITY_IPC_RX;
+        task_p.handler = _bal_ipc_api_rx_handler;
+        task_p.data = (long)p_balapi_rsp_queue;
+
+        ret = bcmos_task_create(&api_rsp_rx_thread, &task_p);
+        if (ret)
+        {
+            BCM_LOG(ERROR, log_id_public_api, "Couldn't create BAL API response RX thread\n");
+            break;
+        }
+
+        /*
+         * Initialize the BAL Public API backend worker and rx threads.  These
+         * threads are used to receive asynchronous indications from the core.
+         */
+        enable_bal_api_indications(balapi_mgmt_ip_port);
+
+    }
+    while(0);
+
+    return ret;
+}
+
+/*****************************************************************************
+ * Un-initialize the BAL Public API internal data structures
+ *****************************************************************************/
+bcmos_errno bcmbal_api_finish(void)
+{
+    bcmos_task_destroy(&api_rsp_rx_thread);
+    bcmos_msg_queue_destroy(&balapi_rsp_queue);
+    if (p_balapi_to_core_queue == &balapi_to_core_queue)
+        bcmos_msg_queue_destroy(&balapi_to_core_queue);
+
+    bal_api_indications_finish();
+
+    return BCM_ERR_OK;
+}
+
+/* Find pending request matching response */
+static bal_comm_msg_hdr *_bal_api_get_request_by_ex_id(uint32_t ex_id)
+{
+    bcmos_msg *req_msg, *tmp_msg;
+    bal_comm_msg_hdr *comm_hdr = NULL;
+
+    STAILQ_FOREACH_SAFE(req_msg, &pending_req_list, next, tmp_msg)
+    {
+        comm_hdr = bcmbal_bal_hdr_get_by_bcmos_hdr(req_msg);
+        if (comm_hdr->ex_id == ex_id)
+        {
+            STAILQ_REMOVE(&pending_req_list, req_msg, bcmos_msg, next);
+            break;
+        }
+    }
+    return req_msg ? comm_hdr : NULL;
+}
+
+/* Check if any pending request timed out */
+static void _bal_api_check_req_timeout(void)
+{
+    bcmos_msg *req_msg, *tmp_msg;
+    bal_comm_msg_hdr *comm_hdr;
+    bcmbal_obj *req_obj;
+    uint32_t ts = bcmos_timestamp();
+
+    STAILQ_FOREACH_SAFE(req_msg, &pending_req_list, next, tmp_msg)
+    {
+        comm_hdr = bcmbal_bal_hdr_get_by_bcmos_hdr(req_msg);
+        if (ts - comm_hdr->timestamp >= BCMBAL_MSG_TIMEOUT_1_SEC)
+        {
+            STAILQ_REMOVE(&pending_req_list, req_msg, bcmos_msg, next);
+            req_obj = (bcmbal_obj *)bcmbal_payload_ptr_get(comm_hdr);
+            /* Release pending API call */
+            req_obj->status = BCM_ERR_TIMEOUT;
+            BCM_LOG(DEBUG, log_id_public_api, "Timing out request %p\n", comm_hdr);
+            bcmos_sem_post(&comm_hdr->sem);
+        }
+    }
+}
+
+/* API response handler */
+static int _bal_ipc_api_rx_handler(long data)
+{
+    static uint32_t last_timeout_check_ts;
+    bcmos_msg_queue *rxq = (bcmos_msg_queue *)data;
+    bcmos_task *my_task = bcmos_task_current();
+    bcmos_msg *msg;
+    bcmos_errno ret = BCM_ERR_OK;
+    uint32_t ex_id;
+    bal_comm_msg_hdr *req;
+    bcmbal_obj *req_obj;
+
+    last_timeout_check_ts = bcmos_timestamp();
+    while (!my_task->destroy_request)
+    {
+        /* Wait for response */
+        msg = NULL;
+        req = NULL;
+
+        ret = bcmos_msg_recv(rxq, BAL_API_RX_POLL_TIMEOUT, &msg);
+        if(BCM_ERR_OK != ret && BCM_ERR_TIMEOUT != ret)
+        {
+            BCM_LOG(ERROR, log_id_public_api,
+                "error during bcmos_msg_recv (error:%s)\n", bcmos_strerror(ret));
+        }
+
+        /* Peek exchange id */
+        if (msg)
+        {
+            ret = bcmbal_bal_msg_peek_ex_id(msg, &ex_id);
+            if(BCM_ERR_OK != ret)
+            {
+                BCM_LOG(ERROR, log_id_public_api,
+                    "bad message. Can't find exchange id (error:%s)\n", bcmos_strerror(ret));
+                bcmos_msg_free(msg);
+                msg = NULL;
+            }
+            else
+            {
+                BCM_LOG(DEBUG, log_id_public_api, "Received message with ex_id=%u\n", ex_id);
+            }
+        }
+
+        /* Now find pending request and also check if any pending request(s) timed out */
+        bcmos_mutex_lock(&balapi_lock);
+        if (msg)
+        {
+            req = _bal_api_get_request_by_ex_id(ex_id);
+            if (NULL == req)
+            {
+                BCM_LOG(ERROR, log_id_public_api,
+                    "Request with ex_id=%u is not found. Probably expired. Response discarded\n", ex_id);
+            }
+            else
+            {
+                BCM_LOG(DEBUG, log_id_public_api, "Found request %p\n", req);
+            }
+        }
+        if (bcmos_timestamp() - last_timeout_check_ts >= BCMBAL_MSG_TIMEOUT_1_SEC)
+        {
+            _bal_api_check_req_timeout();
+            last_timeout_check_ts = bcmos_timestamp();
+        }
+        bcmos_mutex_unlock(&balapi_lock);
+
+        /* Got a message. Now unpack it */
+        if (req)
+        {
+            req_obj = (bcmbal_obj *)bcmbal_payload_ptr_get(req);
+            ret = bcmbal_obj_msg_unpack(msg, &req);
+            if (BCM_ERR_OK != ret)
+            {
+                BCM_LOG(ERROR, log_id_public_api, "Error during message unpack: %s\n", bcmos_strerror(ret));
+                req_obj->status = ret;
+            }
+            /* Release pending API */
+            BCM_LOG(DEBUG, log_id_public_api, "Posting request semaphore for %p\n", req);
+            bcmos_sem_post(&req->sem);
+        }
+
+        if (msg)
+            bcmos_msg_free(msg); /* release packed message. It is no longer needed */
+    }
+
+    my_task->destroyed = BCMOS_TRUE;
+
+    return (BCM_ERR_OK == ret) ? 0 : -EINVAL;
+}
+
+static bcmbal_mgmt_oper_id _bcmbal_obj_to_oper_id(const bcmbal_obj *objinfo)
+{
+    if (objinfo->group == BCMBAL_MGT_GROUP_STAT)
+    {
+        return BCMBAL_MGMT_OPER_ID_GET_STATS;
+    }
+    else if ((objinfo->type & BCMBAL_OBJ_MSG_TYPE_GET))
+    {
+        return BCMBAL_MGMT_OPER_ID_GET;
+    }
+    else if ((objinfo->type & BCMBAL_OBJ_MSG_TYPE_CLEAR))
+    {
+        return BCMBAL_MGMT_OPER_ID_CLEAR;
+    }
+    else
+    {
+        return BCMBAL_MGMT_OPER_ID_SET;
+    }
+}
+
+#define BALAPI_OPER_TIMEOUT (30000000) /* 30 seconds */
+
+static bcmos_errno _bcmbal_oper(bcmbal_obj *objinfo)
+{
+    bal_comm_msg_hdr *comm_hdr = bcmbal_bal_hdr_get(objinfo);
+    bcmos_msg *os_msg;
+    bcmos_errno ret = BCM_ERR_OK;
+
+    /*
+     * Send the message to the core for processing
+     */
+
+    /* Parameter checks */
+    BUG_ON(NULL == objinfo);
+
+    /* Check the magic number to be sure that the object has been properly initialized */
+    if(BCMBAL_OBJ_INIT_VAL != objinfo->obj_init_val)
+    {
+        BCM_LOG(ERROR, log_id_public_api, 
+                "Object has not been initialized: must use a BCMBAL INIT macro on the object before calling the BAL API\n");
+        return BCM_ERR_PARM;
+    }
+
+    ret = bcmos_sem_create(&comm_hdr->sem, 0, 0, "api_req");
+    if (ret)
+    {
+        BCM_LOG(ERROR, log_id_public_api, "Can't create semaphore: %s\n", bcmos_strerror(ret));
+        /* return here. We don't want to destroy semaphore that wasn't created */
+        return ret;
+    }
+
+    do
+    {
+        bcmbal_msg_hdr_set(objinfo,
+                           BCMBAL_MGMT_MSG,
+                           BAL_MSG_TYPE_REQ,
+                           BAL_SUBSYSTEM_PUBLIC_API,
+                           objinfo->obj_type,
+                           _bcmbal_obj_to_oper_id(objinfo),
+                           0);
+
+        BCM_LOG(DEBUG, log_id_public_api, "about to send %p\n", objinfo);
+
+        bcmos_mutex_lock(&balapi_lock);
+        bcmbal_ex_id_set(objinfo, ++balapi_exchange_id);
+        os_msg = bcmbal_bcmos_hdr_get(objinfo);
+        STAILQ_INSERT_TAIL(&pending_req_list, os_msg, next);
+        bcmos_mutex_unlock(&balapi_lock);
+
+        if (BCM_ERR_OK != (ret = bcmbal_msg_send(p_balapi_to_core_queue, objinfo, BCMOS_MSG_SEND_NO_FREE_ON_ERROR)))
+        {
+            BCM_LOG(ERROR, log_id_public_api, "message send failed with error: %s\n", bcmos_strerror(ret));
+            break;
+        }
+        BCM_LOG(DEBUG, log_id_public_api, "REQ message sent to core\n");
+
+        /*
+         * We've sent the message to the core, now, wait for the response (or timeout)
+         */
+        ret = bcmos_sem_wait(&comm_hdr->sem, BALAPI_OPER_TIMEOUT);
+        if (BCM_ERR_OK != ret)
+        {
+            BCM_LOG(ERROR, log_id_public_api, "rsp message receive for failed with error: %s\n",
+                    bcmos_strerror(ret));
+            break;
+        }
+        BCM_LOG(DEBUG, log_id_public_api, "RSP message received from core\n");
+
+        if (BCM_ERR_OK != ret)
+        {
+            BCM_LOG(ERROR, log_id_public_api, "failed to process rsp msg\n");
+            break;
+        }
+
+        if(BCM_ERR_OK != objinfo->status)
+        {
+            BCM_LOG(ERROR, log_id_public_api, "remote message command status is: %s\n",
+                bcmos_strerror(objinfo->status));
+        }
+
+        /*
+         * Pass the command status received from the core back to the caller
+         */
+        ret = objinfo->status;
+    }
+    while(0);
+
+    bcmos_sem_destroy(&comm_hdr->sem);
+
+    return ret;
+}
+
+/*****************************************************************************
+ * BAL Public API Set (or modify) command.
+ *****************************************************************************/
+bcmos_errno bcmbal_cfg_set(bcmbal_cfg *objinfo)
+{
+    bcmos_errno ret = BCM_ERR_OK;
+
+    BCM_LOG(INFO, log_id_public_api, "BAL PUBLIC API - BCMBAL_SET\n");
+
+    if(BCMBAL_OBJ_ID_PACKET == objinfo->hdr.obj_type)
+    {
+        BCM_LOG(ERROR, log_id_public_api, "unsupported object id detected %d\n", objinfo->hdr.obj_type);
+        ret = BCM_ERR_NOT_SUPPORTED;
+
+    }
+    else
+    {
+        objinfo->hdr.type = BCMBAL_OBJ_MSG_TYPE_SET;
+        ret = _bcmbal_oper(&objinfo->hdr);
+    }
+
+    return ret;
+}
+
+#define BCMBAL_MAX_PROXY_PACKET_SIZE  (1600)
+
+/*****************************************************************************
+ * BAL Public API Packet Send function.
+ *****************************************************************************/
+bcmos_errno bcmbal_pkt_send(bcmbal_dest dest,
+                            const char *packet_to_send,
+                            uint16_t packet_len)
+{
+    /* Convert the user packet into a BAL object */
+    bcmbal_packet_cfg *p_packet_obj;
+    bcmbal_packet_key key;
+    bcmbal_u8_list_u32 pkt;
+    bcmos_errno ret;
+
+    BCM_LOG(INFO, log_id_public_api, "BAL PUBLIC API - BCMBAL_SEND to %s\n",
+            (BCMBAL_DEST_TYPE_NNI == dest.type) ? "NNI" : "SUB-TERM");
+
+    if(BCMBAL_MAX_PROXY_PACKET_SIZE < packet_len)
+    {
+        BCM_LOG(ERROR, log_id_public_api, "user packet length (%d) cannot be greater than %d\n",
+                packet_len,
+                BCMBAL_MAX_PROXY_PACKET_SIZE);
+
+        return BCM_ERR_PARM;
+    }
+
+    BCM_LOG(INFO, log_id_public_api, "user packet first 8 bytes %02X%02X%02X%02X%02X%02X%02X%02X\n",
+            packet_to_send[0], packet_to_send[1], packet_to_send[2], packet_to_send[3],
+            packet_to_send[4], packet_to_send[5], packet_to_send[6], packet_to_send[7]);
+
+    /* Set up the object key */
+    key.packet_send_dest = dest;
+
+    /* Allocate room for the packet object including the user packet */
+    p_packet_obj = bcmos_calloc(sizeof(bcmbal_packet_cfg) + packet_len);
+
+    BCMBAL_CFG_INIT(p_packet_obj, packet, key);
+
+    /* Now fill in user packet data into the object */
+    pkt.len = packet_len;
+    pkt.val = (uint8_t *)&p_packet_obj[1];
+    memcpy(pkt.val, packet_to_send, packet_len);
+
+    BCMBAL_CFG_PROP_SET(p_packet_obj, packet, pkt, pkt);
+
+    p_packet_obj->hdr.hdr.type = BCMBAL_OBJ_MSG_TYPE_SET; /* internally packet SEND is modeled as a config SET */
+    ret = _bcmbal_oper(&(p_packet_obj->hdr.hdr));
+    bcmos_free(p_packet_obj);
+
+    return ret;
+}
+
+/*****************************************************************************
+ * BAL Public API Get command.
+ *****************************************************************************/
+bcmos_errno bcmbal_cfg_get(bcmbal_cfg *objinfo)
+{
+    bcmos_errno ret = BCM_ERR_OK;
+
+    BCM_LOG(DEBUG, log_id_public_api, "BAL PUBLIC API - BCMBAL_GET\n");
+
+    if(BCMBAL_OBJ_ID_PACKET == objinfo->hdr.obj_type)
+    {
+        BCM_LOG(ERROR, log_id_public_api, "unsupported object id detected %d\n", objinfo->hdr.obj_type);
+        ret = BCM_ERR_NOT_SUPPORTED;
+
+    }
+    else
+    {
+        objinfo->hdr.type = BCMBAL_OBJ_MSG_TYPE_GET;
+        ret = _bcmbal_oper(&(objinfo->hdr));
+    }
+
+    return ret;
+}
+
+/*****************************************************************************
+ * BAL Public API Clear command.
+ *****************************************************************************/
+bcmos_errno bcmbal_cfg_clear(bcmbal_cfg *objinfo)
+{
+    bcmos_errno ret = BCM_ERR_OK;
+
+    BCM_LOG(INFO, log_id_public_api, "BAL PUBLIC API - BCMBAL_CLEAR\n");
+
+    if(BCMBAL_OBJ_ID_PACKET == objinfo->hdr.obj_type)
+    {
+        BCM_LOG(ERROR, log_id_public_api, "unsupported object id detected %d\n", objinfo->hdr.obj_type);
+        ret = BCM_ERR_NOT_SUPPORTED;
+
+    }
+    else
+    {
+        objinfo->hdr.type = BCMBAL_OBJ_MSG_TYPE_CLEAR;
+        ret = _bcmbal_oper(&objinfo->hdr);
+    }
+
+    return ret;
+}
+
+/*****************************************************************************
+ * @brief BAL Public API Get Stats command.
+ *****************************************************************************/
+bcmos_errno bcmbal_stat_get(bcmbal_stat *objinfo)
+{
+
+    /* Parameter checks */
+    BUG_ON(NULL == objinfo);
+
+    /*
+     * @todo Finish the stats function
+     */
+
+    BCM_LOG(ERROR, log_id_public_api, "bal get stats API not supported\n");
+
+    return BCM_ERR_NOT_SUPPORTED;
+}
+
+/*****************************************************************************
+ * BAL Public API indication subscription.
+ *****************************************************************************/
+bcmos_errno bcmbal_subscribe_ind(bcmbal_cb_cfg *cb_cfg)
+{
+
+    bcmos_errno ret = BCM_ERR_OK;
+
+    /*
+     * The indication subscription function
+     */
+    BCM_LOG(DEBUG, log_id_public_api, "BAL indication subscription for type: %s (%d)\n",
+            bcmbal_objtype_str(cb_cfg->obj_type), cb_cfg->obj_type);
+
+    ret = _manage_api_ind_listener(IND_CB_SUBSCRIBE, cb_cfg);
+
+    return ret;
+}
+
+/*****************************************************************************
+ * BAL Public API indication un-subscription.
+ *****************************************************************************/
+bcmos_errno bcmbal_unsubscribe_ind(bcmbal_cb_cfg *cb_cfg)
+{
+
+    bcmos_errno ret = BCM_ERR_OK;
+
+    BUG_ON(NULL == cb_cfg);
+
+    /*
+     * The indication subscription function
+     */
+    BCM_LOG(DEBUG, log_id_public_api, "BAL indication un-subscription for type: %s (%d)\n",
+            bcmbal_objtype_str(cb_cfg->obj_type), cb_cfg->obj_type);
+
+    ret = _manage_api_ind_listener(IND_CB_UNSUBSCRIBE, cb_cfg);
+
+    return ret;
+}
+
+/*****************************************************************************/
+/**
+ * @brief A function to get the string representation of the interface type
+ *
+ * @param int_type          The interface type to get
+ *
+ * @returns const char *    A pointer to a string containing the interface type,
+ *                          or "INVALID", if not a valid type.
+ *
+ *****************************************************************************/
+const char *bcmbal_get_interface_type_str(bcmbal_intf_type int_type)
+{
+    const char *type_str;
+
+    switch (int_type)
+    {
+        case(BCMBAL_INTF_TYPE_PON):
+        {
+            type_str = "pon";
+        }
+        break;
+
+        case(BCMBAL_INTF_TYPE_NNI):
+        {
+            type_str = "nni";
+        }
+        break;
+
+        default:
+        {
+            type_str = "INVALID";
+        }
+        break;
+
+    }
+
+    return type_str;
+}
+
+
+/*@}*/