/*---------------------------------------------------------------------------*\

    FILE....: WOBBLY.CPP
    TYPE....: C++ Module
    AUTHOR..: David Rowe
    DATE....: 14/11/97

    Exception class used to terminate functions and returns error code to
    to level function with catch statement.


         Voicetronix Voice Processing Board (VPB) Software

         Copyright (C) 1999-2007 Voicetronix www.voicetronix.com.au

         This library 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 library 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., 51 Franklin St, Fifth Floor, Boston,
         MA  02110-1301  USA

\*---------------------------------------------------------------------------*/

#include "wobbly.h"
#include "vpbapi.h"
#include <assert.h>
#include <string.h>

#undef Wobbly	// turn off wobbly macro otherwise it will stuff
				// up function declarations below

/*-------------------------------------------------------------------------*\

								TYPEDEFS

\*-------------------------------------------------------------------------*/

typedef struct {
	const char *s;		// error string
	int	    code;	// error code
} ERROR;

/*-------------------------------------------------------------------------*\

							    STATICS
	
\*-------------------------------------------------------------------------*/

// make sure this array is null terminated 

static ERROR errors[] = {
	{"PORT_ALREADY_INITIALISED",					100},
	{"PORT_CANT_OPEN_DEVICE",					101},
	{"PORT_CANT_CLOSE_DEVICE",					102},
	{"PORT_WRITE_FAIL",						103},
	{"PORT_READ_FAIL",						104},
	{"PORT_ALLOCATE_FAIL",						105},
	{"PORT_NEW_FAIL",						106},
	//{"PORT_CANT_ALLOCATE_MEMORY",					107},

	{"VPBREG_REG_KEY_ACCESS_FAIL",					200},
	//{"VPBREG_NO_VPB_DEVICES_DETECTED",				201},
	{"VPBREG_TOO_MANY_VPBS_ACCESSED",				202},
	{"VPBREG_REG_KEY_PROPERTY_FAIL",				203},
	//{"VPBREG_CANT_ALLOCATE_MEMORY",				204},
	{"VPBREG_CANT_GET_OS_VER",					205},
	{"VPBREG_OS_NOT_SUPPORTED",					206},

	{"HIP_ALREADY_INITIALISED",					300},
	//{"HIP_CANT_ALLOCATE_MEMORY",					301},
	{"HIP_CANT_GET_OS_VER",						302},
	{"HIP_OS_NOT_SUPPORTED",					303},
	{"HIP_CANT_START_DEVICE_DRIVER",				304},
	{"HIP_OPEN_FAIL",						305},
	{"HIP_INIT_VPB_FAIL",						306},
	{"HIP_DSP_RESET_FAIL",						307},
	{"HIP_DSP_RUN_FAIL",						308},
	{"HIP_WRITE_DSP_SRAM_FAIL",					309},
	{"HIP_READ_DSP_SRAM_FAIL",					310},
	//{"HIP_SET_PIP_FAIL",						311},
	{"HIP_CLOSE_FAIL",						312},

	//{"FIFO_CANT_ALLOCATE_MEMORY",					400},

	{"COFF_CANT_OPEN_FILE",						500},
	{"COFF_BAD_MAGIC_NUMBER",					501},
	{"COFF_TOO_MANY_SECTIONS",					502},
	{"COFF_INVALID_COFF_FILE",					503},
	{"COFF_CANT_ALLOCATE_MEMORY",					504},
	{"COFF_FILE_READ_ERROR",					505},
	{"COFF_DSP_MEMORY_TEST_FAILED",					506},
	{"COFF_CANT_FIND_SYMBOL",					507},

	{"COMM_ALREADY_INITIALISED",					600},
	{"COMM_TIME_OUT_CONFIGURING_DSP - DSP not responding", 		601},
	{"COMM_DSP_MESSAGE_CORRUPT",					602},
	//{"COMM_CANT_ALLOCATE_MEMORY",					603},
	{"COMM_TIME_OUT_WAITING_FOR_MESS",				604},
	{"COMM_DSP_ASSERT",						605},
	{"COMM_DOWN_MESSAGE_Q_FULL",					606},
	{"COMM_FIRMWARE_MODEL_NUMBER",					607},
	{"COMM_UNKOWN_BOARD_TYPE",					608},

	//{"DSPFIFO_CANT_ALLOCATE_MEMORY",				700},
	{"DSPFIFO_OPEN_FAIL",						701},
	{"DSPFIFO_CLOSE_FAIL",						702},
	{"DSPFIFO_WRITE_FAIL",						703},
	{"DSPFIFO_READ_FAIL",						704},
	{"DSPFIFO_HOW_FULL_FAIL",					705},

	{"VPBHANDLE_DEVICENAME_FAIL",					800},
	{"VPBHANDLE_BOARD_NUMBER",					801},
	{"VPBHANDLE_CHANNEL_NUMBER",					802},

	{"MESS_CANT_CREATE_MESSAGEBOX",					900},

	// API error messages ----------------------------------------------

	// General errors

	//{"VPBAPI_CANT_ALLOCATE_MEMORY",				1000},
	{"VPBAPI_INVALID_HANDLE",					1001},
	{"VPBAPI_BAD_OBJECT_ID",					1002},
	{"VPBAPI_BAD_TONED_EVENT",					1003},
	{"VPBAPI_DEVICE_BUSY",						1004},

	{"VPBAPI_SETERRORMODE_MODE_INVALID",				1030},

	// playrec, play functions

	{"VPBAPI_PLAY_SYNC_MODE_NOT_SUPPORTED",				1050},
	{"VPBAPI_PLAY_MULAW_NOT_SUPPORTED",				1051},
	{"VPBAPI_PLAY_NOT_SUPPORTED",					1052},
	{"VPBAPI_PLAY_OFFSET_TOO_BIG",					1053},
	{"VPBAPI_PLAY_BAD_LENGTH",					1054},
	{"VPBAPI_DEVICE_NOT_PREPARED",					1055},
	{"VPBAPI_PLAY_OKIADPCM_NOT_SUPPORTED",				1056},
	{"VPBAPI_GAIN_OUT_OF_RANGE",					1057},
	{"VPBAPI_PLAY_CANT_OPEN_VOXFILE",				1058},

	// vpb_rec()

	{"VPBAPI_REC_SYNC_MODE_NOT_SUPPORTED",				1080},
	{"VPBAPI_REC_MULAW_NOT_SUPPORTED",				1081},
	{"VPBAPI_REC_NOT_SUPPORTED",					1082},
	{"VPBAPI_REC_OFFSET_TOO_BIG",					1083},
	{"VPBAPI_REC_BAD_LENGTH",					1084},
	{"PLAYREC_DISK_FULL",						1085},
	{"VPBAPI_REC_OKIADPCM_NOT_SUPPORTED",				1086},
	{"VPBAPI_REC_CANT_OPEN_FILE",					1087},
	{"VPBAPI_RECORD_CANT_OPEN_VOXFILE",				1088},

	//{"VPBAPI_TERM_DIGITS_STRING_TOO_LONG",			1070},  //XXX see below
	{"VPBAPI_INVALID_TERM_DIGITS",					1071},

	// file functions

	{"VPBAPI_VTFILEOPEN_CANT_WRITE_TO_READ_ONLY_FILE",		1060},
	{"VPBAPI_VTFILEOPEN_FILENAME_ALREADY_EXISTS",			1061},
	{"VPBAPI_VTFILEOPEN_INVALID_ARGUMENT	",			1062},
	{"VPBAPI_VTFILEOPEN_TOO_MANY_OPEN_FILES",			1063},
	{"VPBAPI_VTFILEOPEN_FILE_OR_PATH_NOT_FOUND",			1064},
	{"VPBAPI_VTFILEOPEN_CANT_CREATE_FILEHANDLE",			1065},
	{"VPBAPI_VTFILECLOSE_INVALID_FILEHANDLE",			1066},
	{"VPBAPI_VTFILESEEK_INVALID_FILEHANDLE",			1067},
	{"VPBAPI_VTFILESEEK_INVALID_ARGUMENT",				1068},
	{"VPBAPI_VTFILESEEK_CANT_MOVE_POINTER_TO_SPECIFIED_LOCATION",	1069},
	{"VPBAPI_VTFILEREAD_INVALID_FILEHANDLE",			1070},  //XXX see above
	{"VPBAPI_VTFILEREAD_CANT_READ_FILE",				1071},
	{"VPBAPI_VTFILEWRITE_INVALID_FILEHANDLE",			1072},
	{"VPBAPI_VTFILEWRITE_NOT_ENOUGH_MEMORY_SPACE",			1073},
	{"VPBAPI_VTFILEWRITE_CANT_WRITE_TO_FILE",			1074},

	{"VPBAPI_ISDN_CALL_FAILED",					1075},
	{"VPBAPI_ISDN_CALLINFO_FAILED",					1076},

	{"VPBAPI_DIAL_INVALID_DIGIT",					1090},
	{"VPBAPI_DIAL_INVALID_FREQUENCY",				1093},
	{"VPBAPI_DIAL_INVALID_LEVEL",					1094},
	{"VPBAPI_DIAL_NO_TONE",						1095},

	{"VPBAPI_DETECT_TOO_MANY_DETECTORS",				1200},
	{"VPBAPI_DETECT_INVALID_FREQUENCY",				1201},
	{"VPBAPI_DETECT_INVALID_LEVEL",					1202},
	{"VPBAPI_DETECT_INVALID_SNR",					1203},
	{"VPBAPI_DETECT_INVALID_TWIST",					1204},
	{"VPBAPI_DETECT_INVALID_STATES",				1205},
	{"VPBAPI_DETECT_INVALID_TONE",					1206},
	{"VPBAPI_DETECT_NTONES_ERROR",					1207},
	{"VPBAPI_DETECT_TOO_MANY_STATES",				1208},
	{"VPBAPI_DETECT_ALREADY_LOGGING",				1209},
	{"VPBAPI_DETECT_BAD_LOG_FILE_NAME",				1210},
	{"VPBAPI_NOT_ENOUGH_STATES",					1211},

	{"VPBAPI_TIMER_INVALID_TIMER",					1300},
	{"VPBAPI_TIMER_ALREADY_ACTIVE",					1301},
	{"VPBAPI_TIMER_NOT_ACTIVE",					1302},

	{"VPBAPI_VOX_ONLEVEL_TOO_BIG",					1310},
	{"VPBAPI_VOX_ONLEVEL_TOO_SMALL",				1311},
	{"VPBAPI_VOX_OFFLEVEL_TOO_BIG",					1312},
	{"VPBAPI_VOX_OFFLEVEL_TOO_SMALL",				1313},
	{"VPBAPI_VOX_RUNON_TOO_BIG",					1314},
	{"VPBAPI_VOX_RUNON_TOO_SMALL",					1315},

	{"VPBAPI_ADPCM_SIZE_ADPCM_MUST_BE_EVEN",			1330},

	{"VPBAPI_WAVE_CANT_OPEN_FILE",					1340},
	{"VPBAPI_WAVE_FORMAT_NOT_SUPPORTED",				1341},

	//{"VPBAPI_DIGITS_MAX_DIGITS_TOO_BIG",				1350},
	{"VPBAPI_DIGITS_INVALID_TERM_DIGITS",				1351},
	//{"VPBAPI_DIGITS_TERM_DIGITS_STRING_TOO_LONG",			1352},

	{"VPBAPI_CALL_PROGRESS_ALREADY_ACTIVE",				2200},
	{"VPBAPI_CALL_BODGY_TONE_MAP",					2201},
	{"VPBAPI_CALL_MAX_TONE_MAP",					2202},
	{"VPBAPI_CALL_MAX_CALLS_PER_MIN",				2203},

	// vpbapi2\arbch module wobblies

	{"ARBCH_PLAY_CHANNEL_IN_USE",					1400},
	{"ARBCH_RECORD_CHANNEL_IN_USE",					1401},

	// udp module network communication wobblies

	{"UDP_OUT_OF_MEMORY",						1900},
	{"UDP_WSASTARTUP_ERROR",					1901},
	{"UDP_SOCKET_ERROR",						1902},
	{"UDP_BIND_ERROR",						1903},
	{"UDP_SEND_ERROR",						1904},
	{"UDP_RECEIVE_ERROR",						1905},
	{"UDP_RECEIVE_IPADDR_ERROR",					1906},

	// wave module communication wobblies

	{"WAVE_INITIALISE_ERROR",					2000},
	{"WAVE_BUFFERA_ERROR",						2001},
	{"WAVE_BUFFERB_ERROR",						2002},
	{"WAVE_CANT_PLAY_FORMAT",					2003},
	{"WAVE_FAIL_TO_OPEN",						2004},
	{"WAVE_UNABLE_TO_PREPARE_HEADER",				2005},
	{"WAVE_UNABLE_TO_WRITE",					2006},

	// ADPCM ??

	{"ADPCM_OUT_OF_MEMORY",						2100},

        // mapdev
        {"MAPDEV_INVALID_CHANNEL",					2200},

	// Caller ID

	{"VPBAPI_CID_NO_SIGNAL",					2300},
	{"VPBAPI_CID_BAD_MESS_TYPE",					2301},
	{"VPBAPI_CID_BAD_CHECKSUM",					2302},

	// Bridging

	{"VPBAPI_BRIDGE_HANDLES_DENTICAL",				2400},
	{"VPBAPI_BRIDGE_DIFFERENT_BOARDS",				2401},

	// Conferencing

	{"VPBAPI_CONF_BOARD_NOT_SUPPORTED",				2501},


	// Null terminator record, must be at end of this array

	{"",								0}
};

/*-------------------------------------------------------------------------*\

							    FUNCTIONS

\*-------------------------------------------------------------------------*/

Wobbly::Wobbly(const int c) {
    code = c;
	extended_code = 0;
	file[0] = 0;
	line = 0;
}

Wobbly::Wobbly(const int c, const int ex) {
    code = c;
	extended_code = ex;
	file[0] = 0;
	line = 0;
}

Wobbly::Wobbly(const int c, const char f[], const int l) {
    code = c;
	extended_code = 0;
	if (strlen(f) < (MAX_STR-1))
		strcpy(file, f);
	else {
		memcpy(file, f, sizeof(char)*(MAX_STR-1));
		file[MAX_STR-1] = 0;
	}
	line = l;
}

void Wobbly::translate(char s[]) const
//	char	s[]		error in string form (max length MAX_STR) 
{
	int		i=0;

	assert(s != NULL);

	while(errors[i].code) {
		if (errors[i].code == code) {
			assert(strlen(errors[i].s) < (MAX_STR-1));	// room for term NULL
			strcpy(s, errors[i].s);
			return;
		}
		i++;
	}

	assert(0);	// invalid error code, shouldnt get this far
}

