/*Copyright (C) 2005 Michael Kasianowicz (xtravar@yahoo.com)

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

This program 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 General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
*/

#ifndef __P2K_H__
#define __P2K_H__

/* this is a C99 header... oops */
#include <inttypes.h>
#include <wchar.h>

#define P2K_HEADER_SIZE 8
#define P2K_PACKET_ID_MAX 0x0FFF
#define P2K_PACKET_DATA_MAX 0x0FFF

/* borrowed the descriptions for these commands from multiple places
	don't know if they're correct or if someone holds copyright 
	assuming public domain */
typedef enum {
		P2K_AUD_TN_LST			=	0x0000,	/* Start or Stop audio tones predefined by the Audio Manager.  P2K sends 3 & 3G sends 1. */
		P2K_AD_CONV				=	0x0001,	/* Return result of A/D conversion on specified line */
		P2K_AUTOCYCLE			=	0x0002,	/* Simulates product operations by enabling/disabling phone functions. */
		P2K_AUD_CTRL			=	0x0003,	/* Control various audio functions; enable/disable vibrator */
		P2K_AUD_LPB				=	0x0004,	/* Enable audio loopback.  P2K sends 1 & 3G sends 2. */
		P2K_AUD_LVL				=	0x0005,	/* Set audio level */
		P2K_AUD_PATH			=	0x0006,	/* Change audio path */
		P2K_CARRIER				=	0x0007,	/* Enable/disable carrier */
		P2K_CDATA				=	0x0008,	/* Tx continuous data on a channel */
		P2K_COMPD				=	0x0009,	/* Enable/disable compander */
		P2K_CP_MODE				=	0x000A,	/* Select radio call processing mode */
		P2K_DTMF				=	0x000B,	/* Generate/disable DTMF tones */
		P2K_ERS_PANIC			=	0x000C,	/* Erases panic information in flash memory */
		P2K_FLASH				=	0x000D,	/* Put the phone in a mode suitable for flashing */
		P2K_GET_PANIC			=	0x000E,	/* Allows to read the information stored in the panic sector in NVM. */
		P2K_HDW					=	0x000F,	/* General hardware control */
		P2K_INIT				=	0x0011,	/* Initialize radio to known states to be determined */
		P2K_INVM				=	0x0012,	/* Initialize the non-volatile memory parameters */
		P2K_KEYS				=	0x0013,	/* Perform key strokes */
		P2K_LOAD_SYN			=	0x0014,	/* Load channel into synthesizer */
		P2K_LONG_STAT			=	0x0015,	/* Display radio status in detailed format */
		P2K_MEMACS				=	0x0016,	/* Read/write memory access to MCU/DSP */
		P2K_MDI					=	0x0017,	/* Builds MDI message and sends it to DSP. */
		P2K_PHASE				=	0x001D,	/* Set a phasing parameter in HW/SW; program to NVM */
		P2K_PWR_OFF				=	0x001E,	/* Power down the phone */
		P2K_PREKEY				=	0x001F,	/* Control of prekey power supply to RF section */
		P2K_RDELEM				=	0x0020,	/* Read element in NVM */
		P2K_RDWR_SPI			=	0x0021,	/* Generic read/write to SPI bus */
		P2K_RESTART				=	0x0022,	/* Generate a software restart */
		P2K_RCVS1				=	0x0023,	/* Receive Contiguous 1-word messages on analog control channel; count errors */
		P2K_RCVS2				=	0x0024,	/* Receive contiguous 1 word messages on ACC for the specified number of frames. */
		P2K_RQ					=	0x0026,	/* Request various data/status */
		P2K_RSSI				=	0x0027,	/* Return compensated RSSI (in dBm) for current ch */
		P2K_RTCC				=	0x0029,	/* Set real time clock */
		P2K_SAT					=	0x002B,	/* Enable/disable SAT transponding */
		P2K_SET_LNA				=	0x002C,	/* Set the Low Noise Amplifier gain control, CDMA only */
		P2K_SET_RF_PWR			=	0x002D,	/* Set RF power attenuation */
		P2K_SIGTONE				=	0x002E,	/* Enable/disable signalling tone */
		P2K_STELEM				=	0x002F,	/* Program element to NVM */
		P2K_PARM				=	0x0030,	/*  */
		P2K_MSG_INJ				=	0x0033,	/* Inject message to specific task or message queue */
		P2K_MSG_RT				=	0x0034,	/* Configure message routing (task/bottom connector) */
		P2K_SBSDY_LCK			=	0x0035,	/* Subsidy activation command */
		P2K_SUSPEND				=	0x0036,	/* Terminate normal mode and enter test mode */
		P2K_TST_DISP			=	0x0037,	/* Place a test pattern in the display */
		P2K_XUPID				=	0x0038,	/* Used to get/set Extended Universal Platform Identifier in the flash boot block. */
		P2K_VERSION				=	0x0039,	/* Get version of selected phone element (DSP, etc) */
		P2K_WSTS				=	0x003A,	/* Receive contiguous 1-word msgs on analog ctrl channel; count sync sequences */
		P2K_WRITE_DA			=	0x003B,	/* Write to D to A converter */
		P2K_SMARTCARD			=	0x003C,	/* Read/Write From/To SIM card */
		P2K_LEDS				=	0x003E,	/* Handles the LEDS on the display. */
		P2K_KEY_TEST			=	0x003F,	/* Returns the latest key pressed. */
		P2K_IRDA				=	0x0040,	/* Enable\Disable the IRDA port.  P2K sends 1 & 3G sends 3. */
		P2K_GPIO_TEST			=	0x0041,	/* Allows access over the various GPIO ports and pins.  P2K uses 8 & 2, 3G uses 13 & 4. */
		P2K_BT					=	0x0042,	/* Passes data to the Bluetooth Test Control Interface */
		P2K_FLIP				=	0x0043,	/* Sets/Retrieves the state of the flip. */
		P2K_AUD_TN_GEN			=	0x0044,	/* Enable/Disable a generated tone. P2K sends 13 & 3G sends 14. */
		P2K_KEY_PRESS			=	0x0045,	/* Performs a key press/releaes events. */
		P2K_ICACS				=	0x0046,	/* Peforms key press/ release event */
		P2K_SSI_LPB				=	0x0048,	/* Loops back the SAP SSI lines */
		P2K_CEM_TEST			=	0x0049,	/* Allows for connectivity testing of CE-Module bus pins that can't be checked via the GPIO_TEST command. */
		P2K_FSAC				=	0x004A,	/* Activates different file system requests to and from phone. */
		P2K_WR_PBK				=	0x004B,	/* Stores phonebook record in NVM. */
		P2K_PU_TSTMODE			=	0x004C,	/* Gets powerup mode of phone or sets next powerup mode. */
		P2K_CALL				=	0x004D,	/* Make a test voice call in the factory. */
		P2K_PROT				=	0x0050,	/* Command allows technology selection.  (either GSM or TDMA) */
		P2K_MEMORY				=	0x0051,	/* Returns information about alocated memory (LCA only). */
		P2K_CARRIER_SYN_ATTN	=	0x0052,	/* Combination of CARRIER, LOAD_SYN, and SET_RF_PWR. */
		P2K_HIBERNATE			=	0x0053,	/* Powers the phone off using the battery hibernate machanism. */
		P2K_KJAVA				=	0x0054,	/* kJava Test Commands. */
		P2K_TRAC_ACTIVE			=	0x0055,	/* Changes Tracfone state. */
		P2K_IS_FR				=	0x0056,	/* Future Ready. */
		P2K_SWDL				=	0x0057,	/* SW Download file creation for backup. */
		P2K_SWUL				=	0x0058,	/* SW Download file restore. */
		P2K_AUD_TN_TEST			=	0x0059,	/* Play list of phased frequencies. */
		P2K_EFSAC				=	0x0060,	/* Activates different file system requests to and from the phone. */
		P2K_TST_CAMERA			=	0x0061,	/* General purpose Camera command. */
		P2K_ALERT				=	0x0090,	/* Generates a tone. */
		P2K_HS_LPB				=	0x0091,	/* Enable headset loopback function1. */
		P2K_AUD_PH_LPB			=	0x0092,	/* Enable headset loopback function2. */
		P2K_ALT_STOP_AUD_PH_LPB	=	0x0093,	/* Disables tone and enables loopback. */
		P2K_VIB_STOP_ALERT		=	0x0094,	/* Disables vibrator and tone. */
		P2K_CIT_ELEM			=	0x0095,	/* Stamps status of CIT test. */
		P2K_DIGTS				=	0x0B04,	/* Switch to DTC mode */
		P2K_TDMA_INFO			=	0x0B05,	/* Pass TDMA data to TDMA stack */
		P2K_TDMA_ON				=	0x0B06,	/* Synchronize to forward traffic channel  */
		P2K_PA_FDBACK			=	0x0B08,	/* Report a power measurement from Tx Output power detection ckt */
		P2K_TDMA_CFG			=	0x0B09,	/* Configure the DSP into different test settings */
		P2K_IR_STATUS			=	0x0B0A,	/* Configures and retrieves IR scan parameters */
		P2K_TX_PWR_DET			=	0x0B0B,	/*  */
		P2K_COMMIT				=	0x0B0C,	/* Used to commit scratchpad changes to active memory */
		P2K_CPY_ACTIVE			=	0x0B0D,	/* Copies the active memory to scratchpad memory */
		P2K_GENERIC_DSP			=	0x0C00,	/* Generic DSP command. */
		P2K_RDWR_UART			=	0x0C01,	/* Read/Write UART. */
		P2K_WSCMP				=	0x0C02,	/* WCDMA Simple CAMP. */
		P2K_RDWR_DSP_SPI		=	0x0C03,	/* Read/Write DSP SPI bus devices. */
		P2K_DSP_SPI_TRIG_CONFIG	=	0x0C04,	/* DSP SPI Trigger Configure. */
		P2K_L1T_TOLS			=	0x0C05,	/* L1 Timer - Override L1 Signals. */
		P2K_L1T_TFTS			=	0x0C06,	/* L1 Timer - Frame Table Select. */
		P2K_L1T_THEG			=	0x0C07,	/* L1 Timer - Halt Event Generator. */
		P2K_L1T_TWRC			=	0x0C08,	/* L1 Timer - Write Register Command. */
		P2K_L1T_TRRC			=	0x0C09,	/* L1 Timer - Read Register Command. */
		P2K_L1T_TCCT			=	0x0C0A,	/* L1 Timer - Change Channel Timing. */
		P2K_WLOAD_SYN			=	0x0C0B,	/* WCDMA Load Synthesizer. */
		P2K_RSSI_RSCP			=	0x0C0D,	/* Receive Signal Strength Indicator, Receive Signal Code Power. */
		P2K_W_CARRIER			=	0x0C0E,	/* WCDMA Carrier. */
		P2K_W_PHASE				=	0x0C0F,	/* WCDMA Phase. */
		P2K_WPC_VAR				=	0x0C10,	/* WCDMA Power Control Variables. */
		P2K_WPC_DTAR			=	0x0C11,	/* WCDMA Power Control RF Detect Target. */
		P2K_WPC_TPC				=	0x0C12,	/* WCDMA Power Control TPC Patterns. */
		P2K_RDWR_HARM			=	0x0C13,	/* Read/Write Harmony Lite. */
		P2K_RQBER				=	0x0C14,	/* Request PN9 Sequence Bit Error Rate. */
		P2K_AUD_SAMP			=	0x0C15,	/* Audio Sample. */
		P2K_WOPCHAN				=	0x0C16,	/* WCDMA Open Channel. */
		P2K_GPS					=	0x0C17,	/* GPS Test Command. */
		P2K_SUSPEND_COMP		=	0x0C18,	/* Suspend Component. */
		P2K_TOUCH_SCREEN		=	0x0C19,	/* Touch Screen Interface Parameters. */
		P2K_CAMERA				=	0x0C1A,	/* Test Camera HW and Driver. */
		P2K_TST_MMC				=	0x0C1B,	/* Test Multi-Media Card. */
		P2K_WUPD_COMP			=	0x0C1C,	/* Update Compensated Values. */
		P2K_BAUD_RATE			=	0x0C1D,	/* Configure UART baud rate. */
		P2K_PDLOG				=	0x0C20,	/* Power Down LOG. */
		P2K_RD_IC				=	0x0C21,	/* Read Integrated Circuit ID. */
		P2K_OCD					=	0x0C23,	/* On Chip Debugger. */
		P2K_WLONG_STAT			=	0x0C24,	/* Get WCDMA long status. */
		P2K_RDWR_IO				=	0x0C25,	/* GPIO_TEST abstraction. */
		P2K_DIP_SWITCH			=	0x0D00,	/* Read a set of SW flags. */
		P2K_READ_ADC			=	0x0D01,	/* Read Specified ADC. */
		P2K_GPS_CHECK_AGC		=	0x0D02,	/* Read GPS AGC. */
		P2K_CW_SIGNAL			=	0x0D03,	/* Continuous wave generation from interleaver. */
		P2K_PING				=	0x0FFF,	/* Test test command connection. */
		P2K_SCMP				=	0x0901,	/* Start Simple Camp */
		P2K_TLPB				=	0x0902,	/* Starts / Stops TCH loopback */
		P2K_GPRS_LPB			=	0x0903,	/* GPRS Loopback mode. */
		P2K_EGPM				=	0x0904,	/* Enables/Disables handovers from the GSM band to the PCS band in GSM/PCS phones. */
		P2K_GPRS_SEND			=	0x0905,	/* Initiates mobile originated data from RLC in the GPRS stack. */
		P2K_TXBD				=	0x0906,	/* Modifies TX phasing param's during burst xmit. */
} p2k_command;

typedef enum {
    P2K_FSAC_OPEN,
    P2K_FSAC_READ,
    P2K_FSAC_WRITE,
    P2K_FSAC_SEEK,
    P2K_FSAC_CLOSE,
    P2K_FSAC_DELETE,
    P2K_FSAC_CLEAR,
    P2K_FSAC_COUNT,
    P2K_FSAC_LIST,
    P2K_FSAC_UNKNOWN,
    P2K_FSAC_VOLNAME,
    P2K_FSAC_VOLSPACE
} p2k_fsac_command;

#pragma pack(2)
typedef struct {
	uint16_t id;
	uint16_t command;
	uint16_t data_size;
	uint16_t _dummy;
	uint8_t data[];
} p2k_packet;

#pragma pack()

typedef enum {
	P2K_RESULT_NODATA = 0x06,
	P2K_RESULT_DATA = 0x08
#if 0
	P2K_ERROR_LENGTH,		/* Invalid data length for command */
	P2K_ERROR_SECURITY,		/* Inadequate security level for command/parameter */
	P2K_ERROR_COMMAND,		/* Command/parameter not supported for current protocol */
	P2K_ERROR_OPCODE,		/* Unsupported/invalid opcode */
	P2K_ERROR_PARAM,		/* Unsupported/invalid parameter for opcode */
	P2K_ERROR_NODATA,		/* Unexpected result - no data received */
	P2K_ERROR_GENERIC,		/* Generic failure */
	P2K_ERROR_DATA,			/* Unexpected result - data received */
	P2K_ERROR_UNKNOWN,		/* Unknown error */
	P2K_ERROR_NOMEM,		/* Couldn't allocate memory */
	P2K_ERROR_INTERR,		/* Internal task error */
	P2K_ERROR_TIMEOUT,		/* Test command task timed out waiting for response */
	P2K_ERROR_CDMAPARSE,	/* CDMA parse error */
	P2K_ERROR_LESSDATA,		/* Length specified in command header greater than received */
	P2K_ERROR_POWERDOWN		/* Irrecoverable error - phone is being powered down */
#endif
} p2k_result;

/* functions primarily for reading from a received packet */
p2k_packet * p2k_packet_from_buff(const uint8_t *buff, int *buff_pos);

int p2k_packet_get_id(p2k_packet *packet);
int p2k_packet_get_command(p2k_packet *packet);
int p2k_packet_get_data_size(p2k_packet *packet);

int p2k_packet_get_result(p2k_packet *packet);

int p2k_packet_get_buff(p2k_packet *packet, int *pos, uint8_t *buff, int len);
int p2k_packet_get_u8(p2k_packet *packet, int *pos, uint8_t *value);
int p2k_packet_get_u16(p2k_packet *packet, int *pos, uint16_t *value);
int p2k_packet_get_u32(p2k_packet *packet, int *pos, uint32_t *value);
int p2k_packet_get_str(p2k_packet *packet, int *pos, char *str, int len);
int p2k_packet_get_wstr(p2k_packet *packet, int *pos, wchar_t *str, int len);
int p2k_packet_get_wstr_a(p2k_packet *packet, int *pos, char *str, int len);

/* functions primarily for writing to a new packet to send */
p2k_packet * p2k_packet_create(p2k_command command, int max_data_size);
void p2k_packet_init(p2k_packet *packet, p2k_command command);
void p2k_packet_newid(p2k_packet *packet);

int p2k_packet_set_data_size(p2k_packet *packet, uint16_t size);

int p2k_packet_put_buff(p2k_packet *packet, int *pos, const uint8_t *buff, uint16_t len);
int p2k_packet_put_u8(p2k_packet *packet, int *pos, uint8_t value);
int p2k_packet_put_u16(p2k_packet *packet, int *pos, uint16_t value);
int p2k_packet_put_u32(p2k_packet *packet, int *pos, uint32_t value);
int p2k_packet_put_str(p2k_packet *packet, int *pos, const char *str);
int p2k_packet_put_strpad(p2k_packet *packet, int *pos, const char *str, int total);
int p2k_packet_put_wstr(p2k_packet *packet, int *pos, const wchar_t *str);
int p2k_packet_put_wstr_a(p2k_packet *packet, int *pos, const char *str);
int p2k_packet_put_wstrpad(p2k_packet *packet, int *pos, const wchar_t *str, int total);
int p2k_packet_put_wstrpad_a(p2k_packet *packet, int *pos, const char *str, int total);

/* deallocates packet space */
int p2k_packet_destroy(p2k_packet *packet);

const char *p2k_command_str(p2k_command com);

const char *p2k_fsac_command_str(p2k_fsac_command com);

void p2k_packet_print(p2k_packet *packet);
void p2k_packet_dbgpr(p2k_packet *packet);

#endif /*__P2K_H__*/
