/*-------------------------------------------------------------------------
   Misc function copy right information

   Copyright (C) 2006-2009. Lin, Rongrong <woody@palmmicro.com>
                            Tang, Li      <tangli@palmmicro.com>

   This program is free software; you can redistribute it and/or
   modify it under the terms of the GNU Lesser General Public
   License as published by the Free Software Foundation; either
   version 2.1 of the License, or (at your option) any later version.

   This software is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
   Lesser General Public License for more details.

   You should have received a copy of the GNU Lesser General Public
   License along with this library; if not, write to the Free Software
   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
-------------------------------------------------------------------------*/

#include "type.h"
#include "core.h"
#include "apps.h"

const UCHAR Rtp_cPayLoad[VOICE_CODER_NUM] = {RTP_ULAW, RTP_ALAW, RTP_G726_32, RTP_GSM, RTP_ILBC, RTP_SPEEX, RTP_G729};
PCHAR Rtp_pData;

// Misc functions

void itoa(USHORT sVal, PCHAR pBuf, UCHAR iRadix)
{
    PCHAR p;            // pointer to traverse string 
    PCHAR pFirstDigit;  // pointer to first digit 
	UCHAR iTmp;          // temp UCHAR 

    p = pBuf;
    pFirstDigit = p;        // save pointer to first digit 

    do 
    {
		iTmp = mod_16x8(sVal, iRadix);
		sVal = div_16x8(sVal, iRadix);

        // convert to ascii and store 
        if (iTmp > 9)
		{
            *p++ = iTmp - 10 + 'A';  // a letter 
		}
        else
		{
            *p++ = iTmp + '0';       // a digit 
		}
    } while (sVal > 0);

	// We now have the digit of the number in the buffer, but in reverse order.  Thus we reverse them now. 
	
    *p-- = '\0';            // terminate string; p points to last digit 

    do 
    {
		iTmp = *p;
        *p = *pFirstDigit;
        *pFirstDigit = iTmp;   // swap *p and *pFirstDigit 
        --p;
        ++pFirstDigit;         // advance to next two digits 
    } while (pFirstDigit < p); // repeat until halfway 
}

USHORT atoi(PCHAR pBuf, UCHAR iRadix)
{
	UCHAR iPos, iVal;
	USHORT sTotal;

	sTotal = 0;
	iPos = 0;
	do
	{
		iVal = pBuf[iPos];
		if (iVal >= '0' && iVal <= '9')
		{
			iVal -= '0';
		}
		else 
		{
			if (iRadix == 16)
			{
				if (iVal >= 'a' && iVal <= 'f')
				{
					iVal -= 'a' - 10;
				}
				else if (iVal >= 'A' && iVal <= 'F')
				{
					iVal -= 'A' - 10;
				}
				else
				{
					break;
				}
			}
			else
			{
				break;
			}
		}
		sTotal = (USHORT)mul_16x8(sTotal, iRadix);
		sTotal += iVal;
		iPos ++;
	} while (1);

	return sTotal;
}

void ltoa(ULONG lVal, PCHAR pBuf, UCHAR iRadix)
{
    PCHAR p;            // pointer to traverse string 
    PCHAR pFirstDigit;  // pointer to first digit 
	UCHAR iTmp;          // temp UCHAR 

    p = pBuf;
    pFirstDigit = p;        // save pointer to first digit 

    do 
    {
		iTmp = mod_32x8(lVal, iRadix);
		lVal = div_32x8(lVal, iRadix);

        // convert to ascii and store 
        if (iTmp > 9)
		{
            *p++ = iTmp - 10 + 'A';  // a letter 
		}
        else
		{
            *p++ = iTmp + '0';       // a digit 
		}
    } while (lVal);

	// We now have the digit of the number in the buffer, but in reverse order.  Thus we reverse them now. 
	
    *p-- = '\0';            // terminate string; p points to last digit 

    do 
    {
		iTmp = *p;
        *p = *pFirstDigit;
        *pFirstDigit = iTmp;   // swap *p and *pFirstDigit 
        --p;
        ++pFirstDigit;         // advance to next two digits 
    } while (pFirstDigit < p); // repeat until halfway 
}

ULONG atol(PCHAR pBuf, UCHAR iRadix)
{
	UCHAR iPos, iVal;
	ULONG lTotal;

	lTotal = 0;
	iPos = 0;
	do
	{
		iVal = pBuf[iPos];
		if (iVal >= '0' && iVal <= '9')
		{
			iVal -= '0';
		}
		else 
		{
			if (iRadix == 16)
			{
				if (iVal >= 'a' && iVal <= 'f')
				{
					iVal -= 'a' - 10;
				}
				else if (iVal >= 'A' && iVal <= 'F')
				{
					iVal -= 'A' - 10;
				}
				else
				{
					break;
				}
			}
			else
			{
				break;
			}
		}
		lTotal = mul_32x8(lTotal, iRadix);
		lTotal += iVal;
		iPos ++;
	} while (1);

	return lTotal;
}

void ip2str(PCHAR pIP, PCHAR pStr)
{
	UCHAR i;

	pStr[0] = 0;
	for (i = 0; i < IP_ALEN; i ++)
	{
		itoa(pIP[i], (PCHAR)(pStr + strlen(pStr)), 10);
		if (i < IP_ALEN-1)
		{
			strcat(pStr, ".");
		}
	}
}

BOOLEAN str2ip(PCHAR pStr, PCHAR pDstIP)
{
	UCHAR iVal, iCount;
	USHORT iTotal;
	UCHAR pIp[IP_ALEN];

	iTotal = 0;
	iCount = 0;
	do
	{
		iVal = *pStr;
		pStr ++;
		if (iVal >= '0' && iVal <= '9')
		{
//			iTotal *= 10;
			iTotal = (USHORT)mul_16x8(iTotal, 10);
			iTotal += iVal - '0';
			if (iTotal >= 256)
			{
				return FALSE;
			}
		}
		else
		{
			pIp[iCount] = (UCHAR)iTotal;
			iTotal = 0;
			iCount ++;
			if (iCount < IP_ALEN)
			{
				if (iVal != '.' && iVal != '*')
				{
					return FALSE;
				}
			}
			else
			{
				break;
			}
		}
	} while (iVal);

	memcpy4(pDstIP, pIp);
	return TRUE;
}

void mac2str(PCHAR pMac, PCHAR pString)
{
	UCHAR i, iVal;
	PCHAR p;

	p = pString;
	for (i = 0; i < HW_ALEN; i ++)
	{
		iVal = pMac[i];
		if (iVal < 0x10)
		{
			*p ++ = '0';
			itoa(iVal, p, 16);
			p ++;
		}
		else
		{
			itoa(iVal, p, 16);
			p += 2;
		}
		*p ++ = '-';
	}
	p --;
	*p = 0;
}

const UCHAR _cUpAscMapping[] = "0123456789ABCDEF";
const UCHAR _cLowAscMapping[] = "0123456789abcdef";

UCHAR char2asc(UCHAR iChar, BOOLEAN bUpper)
{
	if (bUpper)
		return _cUpAscMapping[iChar&0x0f];
	else
		return _cLowAscMapping[iChar&0x0f];
}

void char2asc_str(PCHAR pDst, PCHAR pSrc, UCHAR iLen, BOOLEAN bUpper)
{
	UCHAR i, iVal;
	PCHAR p;

	p = pDst;
	for (i = 0; i < iLen; i ++)
	{
		iVal = pSrc[i];
		*p ++ = char2asc((UCHAR)(iVal>>4), bUpper);
		*p ++ = char2asc(iVal, bUpper);
	}
	*p = 0;
}

const UCHAR _cDtmfKeys[MAP_KEY_NUM] = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '*', '#', 'T'};

UCHAR ascii2keyid(UCHAR iAscii)
{
	UCHAR i;

	for (i = 0; i < MAP_KEY_NUM; i ++)
	{
		if (iAscii == _cDtmfKeys[i])
		{		
			return i;
		}
	}

	return MAP_KEY_UNKNOWN;
}

UCHAR keyid2ascii(UCHAR iKeyid)
{
	if (iKeyid < MAP_KEY_NUM)
	{
		return (UCHAR)(_cDtmfKeys[iKeyid]);
	}
	else
	{
		return 0;
	}
}

/*
void to_lower(PCHAR pData, UCHAR iLen)
{
	UCHAR i, iChar;

	for (i = 0; i < iLen; i ++)
	{
		iChar = *pData;
		if (iChar >= 'A' && iChar <= 'Z')
		{
			iChar += 0x20;
		}
		*pData = iChar;
		pData ++;
	}
}

void str_to_lower(PCHAR pStr)
{
	to_lower(pStr, strlen(pStr));
}
*/

BOOLEAN IsValidIP(PCHAR pIP)
{
	UCHAR iFirst, iSecond;

	iFirst = pIP[0];
	iSecond = pIP[1];

	if (iFirst == 127 || iFirst >= 224)
	{
		return FALSE;
	}
	else if (!iFirst)
	{
		if (!iSecond)
		{
			return FALSE;
		}
	}

	return TRUE;
}

BOOLEAN IsPrivateIP(PCHAR pIP)
{
	UCHAR iFirst, iSecond;

	iFirst = pIP[0];
	iSecond = pIP[1];

	if (iFirst == 10)
	{
		return TRUE;
	}
	else if (iFirst == 192 )
	{
  		if (iSecond == 168)
		{
			return TRUE;
		}
	}
	else if (iFirst == 172)
	{
		if (iSecond >= 16 && iSecond <= 31)
		{
			return TRUE;
		}
	}
	return FALSE;
}

