/*-------------------------------------------------------------------------
   Syslog function copy right information

   Copyright (C) 2007-2008. Tang, Li      <tangli@palmmicro.com>
                            Lin, Rongrong <woody@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
-------------------------------------------------------------------------*/

// RFC 3164. The BSD syslog Protocol

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

#define SYSLOG_SERVER_PORT	514

UDP_SOCKET _pSyslogSocket;
BOOLEAN _bUseSyslog;

const UCHAR _cMonth[12][4] = {"JAN", "FEB", "MAR", "APR", "MAY", "JUN", "JUL", "AUG", "SEP", "OCT", "NOV", "DEC"};

void SyslogOpen()
{
	OptionsGetBuf(Sys_pLogIp, OPT_SYSLOG_IP, IP_ALEN);
	if (!Sys_pLogIp[0] && !Sys_pLogIp[1])
	{
		_bUseSyslog = FALSE;
	}
	else
	{
		_bUseSyslog = TRUE;
		_pSyslogSocket = UdpListen(SYSLOG_SERVER_PORT, UDP_DEBUG_BANK_OFFSET, 0);
		UdpConnectTo(_pSyslogSocket, Sys_pLogIp, SYSLOG_SERVER_PORT);
	}
}

void SyslogClose()
{
	UdpClose(_pSyslogSocket);
}

void Syslog(UCHAR iPri, PCHAR pStr)
{
	PCHAR pCur;
	PCHAR pData;
	USHORT sBackupLen;
	PCHAR pBackup;

	if (!_bUseSyslog)				return;
	if (!pStr || !strlen(pStr))		return;

//	if (iPri == SYSLOG_PRI_DEBUG)
//	{
		sBackupLen = strlen(pStr);
		sBackupLen += 42 + UDP_DATA + IP_DATA + EP_DATA;	// remember extra byte for checksum
		pBackup = malloc(sBackupLen);
		if (!pBackup)	return;		// debug message too long, fail silently

		memcpy(pBackup, Adapter_pPacketBuf, sBackupLen);
//	}

	pData = Adapter_pUdpBuf;
	pCur = pData;
	memcpy(pCur, "<160>", 5);
	pCur[3] += iPri;
	pCur += 5;

	memcpy(pCur, _cMonth[Sys_tmLocal.iMon-1], 3);
	pCur += 3;
	*pCur++ = ' ';
	if (Sys_tmLocal.iMday < 10)
	{
		*pCur++ = ' ';
		*pCur++ = Sys_tmLocal.iMday + '0';
	}
	else
	{
		*pCur++ = div_16x8(Sys_tmLocal.iMday, 10) + '0';
		*pCur++ = mod_16x8(Sys_tmLocal.iMday, 10) + '0';
	}
	*pCur++ = ' ';
	*pCur++ = div_16x8(Sys_tmLocal.iHour, 10) + '0';
	*pCur++ = mod_16x8(Sys_tmLocal.iHour, 10) + '0';
	*pCur++ = ':';
	*pCur++ = div_16x8(Sys_tmLocal.iMin, 10) + '0';
	*pCur++ = mod_16x8(Sys_tmLocal.iMin, 10) + '0';
	*pCur++ = ':';
	*pCur++ = div_16x8(Sys_tmLocal.iSec, 10) + '0';
	*pCur++ = mod_16x8(Sys_tmLocal.iSec, 10) + '0';
	*pCur++ = ' ';

	ip2str(Sys_pIpAddress, pCur);
	pCur += strlen(pCur);
	*pCur ++ = ' ';
	strcpy(pCur, pStr);
//	strcat(pCur, "\r\n");
	strcat(pCur, "\n");

	UdpSend(_pSyslogSocket, strlen(pData) + 1);

//	if (iPri == SYSLOG_PRI_DEBUG)
//	{
		memcpy(Adapter_pPacketBuf, pBackup, sBackupLen);
		free(pBackup);
//	}
}

