/******************************************************************************
 *
 *  <: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_utils.c
 * @brief BAL Utilities source
 *
 * This file contains the implementation of various BAL "utilities",
 * which are provided via the libutils.a library.
 */ 

/*@{*/

#ifdef USING_BAL_UTILS

/* --- system includes ---*/
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <limits.h>
#include <arpa/inet.h>
#include <string.h>

#include <bcmos_system.h>

/* --- project includes ---*/
#include "bal_utils.h"


/*
 * Generic helper functions
 */
char *mac_addr_to_str(char *buffer, bcmos_mac_address mac)
{
    char *fmt_str = NULL;

    fmt_str = "%02hhx:%02hhx:%02hhx:%02hhx:%02hhx:%02hhx";

    snprintf(buffer, 20, fmt_str,
             mac.u8[0], mac.u8[1],
             mac.u8[2], mac.u8[3],
             mac.u8[4], mac.u8[5]);
        
    return buffer;
}


bcmos_bool mac_add_is_null(bcmos_mac_address mac)
{
    return ((0 != mac.u8[0]) || (0 != mac.u8[1]) || (0 != mac.u8[2]) ||
            (0 != mac.u8[3]) || (0 != mac.u8[4]) || (0 != mac.u8[5])) ? BCMOS_FALSE : BCMOS_TRUE;
}

/**
 * @brief Determines if string contains a valid IPv4 or IPv6 address
 *
 *
 * @param ipAddrStr Pointer to string to parse
 *
 * @return bcmos_bool
 * @retval TRUE String contains a valid IP address
 * @retval FALSE String does not
 */
bcmos_bool BalIsValidIp(const char *ipAddrStr)
{
    struct sockaddr_in addr4;
	struct in6_addr addr6;
	bcmos_bool ret = BCMOS_FALSE;

    /* Parameter checks. */
    BUG_UNLESS(NULL != ipAddrStr, BCMOS_FALSE);

	/* First look to see if it's a valid IPv4 address, then look to see if it's
       a valid IPv6 address*/
	if (inet_pton(AF_INET, ipAddrStr, &addr4) > 0 || inet_pton(AF_INET6, ipAddrStr, &addr6) > 0)
	{
	    ret = TRUE;
	}

	return ret;
}


/**
 * @brief Convert a string to the specified type of integer
 *
 * NOTE: This function uses the strtoll() function to convert the string to an
 * integer value. U64 values greater than 0x7fffffffffffffff cannot be converted
 * by the strtoll() function because the string value is considered out of the
 * valid -0x8000000000000000 to 0x7fffffffffffffff 64-bit integer range.
 *
 * @param str    String to convert
 * @param pVal   Pointer to the return value
 *
 * @return bcmos_errno
 */
static bcmos_errno BalStringToInt(char *str, BalIntStringT *pVal)
{
    bcmos_errno  rc  = BAL_OK;
    U64        u64 = 0;
    S64        s64 = 0;
    char      *endptr;

    BUG_UNLESS(NULL != str, BAL_PARAM);
    BUG_UNLESS(NULL != pVal, BAL_PARAM);
    BUG_UNLESS(pVal->intType > BAL_STR2INT_INVALID, BAL_PARAM);
    BUG_UNLESS(pVal->intType < BAL_STR2INT_MAX, BAL_PARAM);

    do
    {
        if ((pVal->intType >= BAL_STR2INT_S8) &&
            (pVal->intType <= BAL_STR2INT_S64))
        {
            /* Just assume a signed 64-bit value when converting the string to
             * an integer. Range checking is done below. Make sure that errno
             * is set to zero before calling strtoll().
             */
            errno = 0;
            pVal->intU.s64 = 0;   /* Clear all possibilities to 0 */
            s64 = strtoll(str, &endptr, 10);

            /* General range and error check */
            if ((errno == ERANGE && (s64 == LONG_MAX || s64 == LONG_MIN))
                || (errno != 0 && s64 == 0))
            {
                errno = 0;
                rc = BCM_ERR_RANGE;
                break;

            }

            /* test for no digits or mixed digits and characters */
            if (endptr == str || '\0' != *endptr)
            {
                errno = 0;
                rc = BCM_ERR_PARM;
                break;
            }

            /* routine specific range check */
            switch (pVal->intType)
            {
                case BAL_STR2INT_S8:
                    if ((s64 < -128) || (s64 > 127))
                    {
                        rc = BCM_ERR_RANGE;
                    }
                    else
                    {
                        pVal->intU.s8 = (S8)s64;
                    }
                    break;
                case BAL_STR2INT_S16:
                    if ((s64 < -32768) || (s64 > 32767))
                    {
                        rc = BCM_ERR_RANGE;
                    }
                    else
                    {
                        pVal->intU.s16 = (S16)s64;
                    }
                    break;
                case BAL_STR2INT_S32:
                    if ((s64 < (-2147483647L -1L)) || (s64 > 2147483647L))
                    {
                        rc = BCM_ERR_RANGE;
                    }
                    else
                    {
                        pVal->intU.s32 = (S32)s64;
                    }
                    break;
                case BAL_STR2INT_S64:
                    /* No range checking is needed since the strtoll() function
                     * does the range checking. If the string was invalid, errno
                     * would have been non-zero.
                     */
                    pVal->intU.s64 = s64;
                    break;
                default:
                    /* Should never make it here. */
                    rc = BCM_ERR_PARM;
                    break;
            }
        }
        else {
            /* Just assume an unsigned 64-bit value when converting the string
             * to an integer. Range checking is done below. Make sure that errno
             * is set to zero before calling strtoull().
             */
            errno = 0;
            pVal->intU.u64 = 0;
            u64 = strtoull(str, &endptr, 10);

            /* General range and error check */
            if ((errno == ERANGE && (s64 == LONG_MAX || s64 == LONG_MIN))
                || (errno != 0 && s64 == 0))
            {
                errno = 0;
                rc = BCM_ERR_RANGE;
                break;

            }

            /* test for no digits or mixed digits and characters */
            if (endptr == str || '\0' != *endptr)
            {
                errno = 0;
                rc = BCM_ERR_PARM;
                break;
            }

            /* routine specific range check */
            switch(pVal->intType)
            {
                case BAL_STR2INT_U8:
                    if (u64 > 255)
                    {
                        rc = BCM_ERR_RANGE;
                    }
                    else
                    {
                        pVal->intU.u8 = (U8)u64;
                    }
                    break;
                case BAL_STR2INT_U16:
                    if (u64 > 65535)
                    {
                        rc = BCM_ERR_RANGE;
                    }
                    else
                    {
                        pVal->intU.u16 = (U16)u64;
                    }
                    break;
                case BAL_STR2INT_U32:
                    if (u64 > 4294967295UL)
                    {
                        rc = BCM_ERR_RANGE;
                    }
                    else
                    {
                        pVal->intU.u32 = (U32)u64;
                    }
                    break;
                case BAL_STR2INT_U64:
                    /* No range checking is needed since the strtoull() function
                     * does the range checking. If the string was invalid, errno
                     * would have been non-zero.
                     */
                    pVal->intU.u64 = u64;
                    break;
                default:
                    /* Should never make it here. */
                    rc = BCM_ERR_PARM;
                    break;
            }
        }
    } while (0);

    return(rc);
}

/**
 * @brief Convert a string to an S8 type integer
 *
 * This function converts a string to an S8 type integer
 *
 * @param str    String to convert
 * @param pVal   Pointer to the return value
 *
 * @return bcmos_errno
 */
bcmos_errno BalStringToS8(char *str, S8 *pVal)
{
    bcmos_errno rc = BAL_OK;
    BalIntStringT intStr;

    BUG_UNLESS(NULL != str, BAL_PARAM);
    BUG_UNLESS(NULL != pVal, BAL_PARAM);

    memset(&intStr, 0, sizeof(intStr));

    intStr.intType = BAL_STR2INT_S8;

    rc = BalStringToInt(str, &intStr);
    if (BAL_OK == rc)
    {
        *pVal = intStr.intU.s8;
    }

    return(rc);
}

/**
 * @brief Convert a string to an S16 type integer
 *
 * This function converts a string to an S16 type integer
 *
 * @param str    String to convert
 * @param pVal   Pointer to the return value
 *
 * @return bcmos_errno
 */
bcmos_errno BalStringToS16(char *str, S16 *pVal)
{
    bcmos_errno rc = BAL_OK;
    BalIntStringT intStr;

    BUG_UNLESS(NULL != str, BAL_PARAM);
    BUG_UNLESS(NULL != pVal, BAL_PARAM);

    memset(&intStr, 0, sizeof(intStr));

    intStr.intType = BAL_STR2INT_S16;

    rc = BalStringToInt(str, &intStr);
    if (BAL_OK == rc)
    {
        *pVal = intStr.intU.s16;
    }

    return(rc);
}

/**
 * @brief Convert a string to an S32 type integer
 *
 * This function converts a string to an S32 type integer
 *
 * @param str    String to convert
 * @param pVal   Pointer to the return value
 *
 * @return bcmos_errno
 */
bcmos_errno BalStringToS32(char *str, S32 *pVal)
{
    bcmos_errno rc = BAL_OK;
    BalIntStringT intStr;

    BUG_UNLESS(NULL != str, BAL_PARAM);
    BUG_UNLESS(NULL != pVal, BAL_PARAM);

    memset(&intStr, 0, sizeof(intStr));

    intStr.intType = BAL_STR2INT_S32;

    rc = BalStringToInt(str, &intStr);
    if (BAL_OK == rc)
    {
        *pVal = intStr.intU.s32;
    }

    return(rc);
}

/**
 * @brief Convert a string to an S64 type integer
 *
 * This function converts a string to an S64 type integer
 *
 * @param str    String to convert
 * @param pVal   Pointer to the return value
 *
 * @return bcmos_errno
 */
bcmos_errno BalStringToS64(char *str, S64 *pVal)
{
    bcmos_errno rc = BAL_OK;
    BalIntStringT intStr;

    BUG_UNLESS(NULL != str, BAL_PARAM);
    BUG_UNLESS(NULL != pVal, BAL_PARAM);

    memset(&intStr, 0, sizeof(intStr));

    intStr.intType = BAL_STR2INT_S64;

    rc = BalStringToInt(str, &intStr);
    if (BAL_OK == rc)
    {
        *pVal = intStr.intU.s64;
    }

    return(rc);
}

/**
 * @brief Convert a string to a U8 type integer
 *
 * This function converts a string to a U8 type integer
 *
 * @param str    String to convert
 * @param pVal   Pointer to the return value
 *
 * @return bcmos_errno
 */
bcmos_errno BalStringToU8(char *str, U8 *pVal)
{
    bcmos_errno rc = BAL_OK;
    BalIntStringT intStr;

    BUG_UNLESS(NULL != str, BAL_PARAM);
    BUG_UNLESS(NULL != pVal, BAL_PARAM);

    memset(&intStr, 0, sizeof(intStr));

    intStr.intType = BAL_STR2INT_U8;

    rc = BalStringToInt(str, &intStr);
    if (BAL_OK == rc)
    {
        *pVal = intStr.intU.u8;
    }

    return(rc);
}

/**
 * @brief Convert a string to a U16 type integer
 *
 * This function converts a string to a U16 type integer
 *
 * @param str    String to convert
 * @param pVal   Pointer to the return value
 *
 * @return bcmos_errno
 */
bcmos_errno BalStringToU16(char *str, U16 *pVal)
{
    bcmos_errno rc = BAL_OK;
    BalIntStringT intStr;

    BUG_UNLESS(NULL != str, BAL_PARAM);
    BUG_UNLESS(NULL != pVal, BAL_PARAM);

    memset(&intStr, 0, sizeof(intStr));

    intStr.intType = BAL_STR2INT_U16;

    rc = BalStringToInt(str, &intStr);
    if (BAL_OK == rc)
    {
        *pVal = intStr.intU.u16;
    }

    return(rc);
}

/**
 * @brief Convert a string to a U32 type integer
 *
 * This function converts a string to a U32 type integer
 *
 * @param str    String to convert
 * @param pVal   Pointer to the return value
 *
 * @return bcmos_errno
 */
bcmos_errno BalStringToU32(char *str, U32 *pVal)
{
    bcmos_errno rc = BAL_OK;
    BalIntStringT intStr;

    BUG_UNLESS(NULL != str, BAL_PARAM);
    BUG_UNLESS(NULL != pVal, BAL_PARAM);

    memset(&intStr, 0, sizeof(intStr));

    intStr.intType = BAL_STR2INT_U32;

    rc = BalStringToInt(str, &intStr);
    if (BAL_OK == rc)
    {
        *pVal = intStr.intU.u32;
    }

    return(rc);
}

/**
 * @brief Convert a string to a U64 type integer
 *
 * This function converts a string to a U64 type integer
 *
 * @param str    String to convert
 * @param pVal   Pointer to the return value
 *
 * @return bcmos_errno
 */
bcmos_errno BalStringToU64(char *str, U64 *pVal)
{
    bcmos_errno rc = BAL_OK;
    BalIntStringT intStr;

    BUG_UNLESS(NULL != str, BAL_PARAM);
    BUG_UNLESS(NULL != pVal, BAL_PARAM);

    memset(&intStr, 0, sizeof(intStr));

    intStr.intType = BAL_STR2INT_U64;

    rc = BalStringToInt(str, &intStr);
    if (BAL_OK == rc)
    {
        *pVal = intStr.intU.u64;
    }

    return(rc);
}


#endif /* USING_BAL_UTILS */
