r1987 - in trunk/src/host/qemu-neo1973: . gnokiigsm hw
andrew at sita.openmoko.org
andrew at sita.openmoko.org
Thu May 17 02:24:58 CEST 2007
Author: andrew
Date: 2007-05-17 02:24:48 +0200 (Thu, 17 May 2007)
New Revision: 1987
Added:
trunk/src/host/qemu-neo1973/gnokiigsm/
trunk/src/host/qemu-neo1973/gnokiigsm/at-emulator.c
trunk/src/host/qemu-neo1973/gnokiigsm/at-emulator.h
trunk/src/host/qemu-neo1973/gnokiigsm/bitmaps.h
trunk/src/host/qemu-neo1973/gnokiigsm/call.h
trunk/src/host/qemu-neo1973/gnokiigsm/common.h
trunk/src/host/qemu-neo1973/gnokiigsm/compat.h
trunk/src/host/qemu-neo1973/gnokiigsm/data.h
trunk/src/host/qemu-neo1973/gnokiigsm/datapump.c
trunk/src/host/qemu-neo1973/gnokiigsm/datapump.h
trunk/src/host/qemu-neo1973/gnokiigsm/device.h
trunk/src/host/qemu-neo1973/gnokiigsm/encoding.h
trunk/src/host/qemu-neo1973/gnokiigsm/error.h
trunk/src/host/qemu-neo1973/gnokiigsm/gnokii-internal.h
trunk/src/host/qemu-neo1973/gnokiigsm/gnokii.h
trunk/src/host/qemu-neo1973/gnokiigsm/misc.h
trunk/src/host/qemu-neo1973/gnokiigsm/networks.h
trunk/src/host/qemu-neo1973/gnokiigsm/ringtones.h
trunk/src/host/qemu-neo1973/gnokiigsm/rlp-common.c
trunk/src/host/qemu-neo1973/gnokiigsm/rlp-common.h
trunk/src/host/qemu-neo1973/gnokiigsm/rlp-crc24.c
trunk/src/host/qemu-neo1973/gnokiigsm/rlp-crc24.h
trunk/src/host/qemu-neo1973/gnokiigsm/sms.h
trunk/src/host/qemu-neo1973/gnokiigsm/statemachine.h
trunk/src/host/qemu-neo1973/gnokiigsm/virtmodem.c
trunk/src/host/qemu-neo1973/gnokiigsm/virtmodem.h
trunk/src/host/qemu-neo1973/gnokiigsm/wappush.h
Modified:
trunk/src/host/qemu-neo1973/Makefile.target
trunk/src/host/qemu-neo1973/configure
trunk/src/host/qemu-neo1973/hw/modem.c
trunk/src/host/qemu-neo1973/hw/s3c2410.c
Log:
First go at the GSM modem emulator - for the moment uses code from 'gnokii' AT interpreter (dialing, SMS, RLP, ringtones, bitmaps but no GPRS).
Fix S3C-UART FIFO mode.
Modified: trunk/src/host/qemu-neo1973/Makefile.target
===================================================================
--- trunk/src/host/qemu-neo1973/Makefile.target 2007-05-16 22:38:21 UTC (rev 1986)
+++ trunk/src/host/qemu-neo1973/Makefile.target 2007-05-17 00:24:48 UTC (rev 1987)
@@ -420,6 +420,11 @@
VL_OBJS += pcnet.o
VL_OBJS += rtl8139.o
+# GSM modem
+GNOKIIGSM_OBJS+=virtmodem.o at-emulator.o datapump.o rlp-common.o rlp-crc24.o
+GSM_CPPFLAGS=-I$(SRC_PATH)/gnokiigsm
+GSM_OBJS=$(addprefix gnokiigsm/, $(GNOKIIGSM_OBJS))
+
ifeq ($(TARGET_BASE_ARCH), i386)
# Hardware support
VL_OBJS+= ide.o pckbd.o ps2.o vga.o $(SOUND_HW) dma.o $(AUDIODRV)
@@ -463,8 +468,9 @@
VL_OBJS+= pxa2xx_lcd.o pxa2xx_mmci.o pxa2xx_pcmcia.o max111x.o max7310.o
VL_OBJS+= spitz.o ads7846.o ide.o serial.o nand.o $(AUDIODRV) wm8750.o wm8753.o
VL_OBJS+= s3c2410.o s3c24xx_gpio.o s3c24xx_lcd.o s3c24xx_mmci.o s3c24xx_rtc.o
-VL_OBJS+= s3c24xx_udc.o neo1973.o pcf5060x.o jbt6k74.o modem.o
-CPPFLAGS += -DHAS_AUDIO
+VL_OBJS+= s3c24xx_udc.o neo1973.o pcf5060x.o jbt6k74.o
+VL_OBJS+= $(GSM_OBJS) modem.o
+CPPFLAGS+= -DHAS_AUDIO $(GSM_CPPFLAGS)
endif
ifeq ($(TARGET_BASE_ARCH), sh4)
VL_OBJS+= shix.o sh7750.o sh7750_regnames.o tc58128.o
Modified: trunk/src/host/qemu-neo1973/configure
===================================================================
--- trunk/src/host/qemu-neo1973/configure 2007-05-16 22:38:21 UTC (rev 1986)
+++ trunk/src/host/qemu-neo1973/configure 2007-05-17 00:24:48 UTC (rev 1987)
@@ -928,6 +928,9 @@
if test "$target_user_only" = "no" ; then
mkdir -p $target_dir/slirp
fi
+if test "$target" = "arm-softmmu" ; then
+ mkdir -p $target_dir/gnokiigsm
+fi
#
# don't use ln -sf as not all "ln -sf" over write the file/link
Added: trunk/src/host/qemu-neo1973/gnokiigsm/at-emulator.c
===================================================================
--- trunk/src/host/qemu-neo1973/gnokiigsm/at-emulator.c 2007-05-16 22:38:21 UTC (rev 1986)
+++ trunk/src/host/qemu-neo1973/gnokiigsm/at-emulator.c 2007-05-17 00:24:48 UTC (rev 1987)
@@ -0,0 +1,1178 @@
+/*
+
+ $Id: at-emulator.c,v 1.45 2006/10/03 21:26:37 pkot Exp $
+
+ G N O K I I
+
+ A Linux/Unix toolset and driver for the mobile phones.
+
+ This file is part of gnokii.
+
+ Gnokii 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.
+
+ Gnokii 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 gnokii; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+ Copyright (C) 1999-2000 Hugh Blemings & Pavel Janík ml.
+ Copyright (C) 2001-2004 Pawel Kot
+ Copyright (C) 2002-2004 BORBELY Zoltan
+
+ This file provides a virtual modem or "AT" interface to the GSM phone by
+ calling code in gsm-api.c. Inspired by and in places copied from the Linux
+ kernel AT Emulator IDSN code by Fritz Elfert and others.
+
+*/
+
+#include <stdio.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <signal.h>
+#include <grp.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <time.h>
+#include <ctype.h>
+#include <termios.h>
+
+#include "misc.h"
+#include "gnokii.h"
+#include "compat.h"
+#include "at-emulator.h"
+#include "datapump.h"
+
+#define MAX_LINE_LENGTH 256
+
+#define MAX_CMD_BUFFERS (2)
+#define CMD_BUFFER_LENGTH (100)
+
+/* Definition of some special Registers of AT-Emulator, pinched in
+ part from ISDN driver in Linux kernel */
+#define REG_RINGATA 0
+#define REG_RINGCNT 1
+#define REG_ESC 2
+#define REG_CR 3
+#define REG_LF 4
+#define REG_BS 5
+#define S22 22
+#define S35 35
+#define REG_CTRLZ 100
+#define REG_ESCAPE 101
+
+#define REG_QUIET 14
+#define BIT_QUIET 4
+#define REG_VERBOSE 14
+#define BIT_VERBOSE 8
+#define REG_ECHO 14
+#define BIT_ECHO 2
+
+
+#define MAX_MODEM_REGISTERS 102
+
+/* Message format definitions */
+#define PDU_MODE 0
+#define TEXT_MODE 1
+#define INTERACT_MODE 2
+
+/* Global variables */
+bool gn_atem_initialised = false; /* Set to true once initialised */
+extern bool CommandMode;
+extern int ConnectCount;
+
+struct gn_statemachine *sm;
+gn_data data;
+
+static gn_sms sms;
+static gn_call_info callinfo;
+static char imei[64], model[64], revision[64], manufacturer[64];
+
+/* Local variables */
+static int PtyRDFD; /* File descriptor for reading and writing to/from */
+static int PtyWRFD; /* pty interface - only different in debug mode. */
+
+static u8 ModemRegisters[MAX_MODEM_REGISTERS];
+static char CmdBuffer[MAX_CMD_BUFFERS][CMD_BUFFER_LENGTH];
+static int CurrentCmdBuffer;
+static int CurrentCmdBufferIndex;
+static int IncomingCallNo;
+static int MessageFormat; /* Message Format (text or pdu) */
+static int CallerIDMode;
+
+ /* Current command parser */
+static void (*Parser)(char *); /* Current command parser */
+/* void (*Parser)(char *) = gn_atem_at_parse; */
+
+static gn_memory_type SMSType;
+static int SMSNumber;
+
+/* If initialised in debug mode, stdin/out is used instead
+ of ptys for interface. */
+bool gn_atem_initialise(int read_fd, int write_fd, struct gn_statemachine *vmsm)
+{
+ PtyRDFD = read_fd;
+ PtyWRFD = write_fd;
+
+ gn_data_clear(&data);
+ memset(&sms, 0, sizeof(sms));
+ memset(&callinfo, 0, sizeof(callinfo));
+
+ data.sms = &sms;
+ data.call_info = &callinfo;
+ data.manufacturer = manufacturer;
+ data.model = model;
+ data.revision = revision;
+ data.imei = imei;
+
+ sm = vmsm;
+
+ /* Initialise command buffer variables */
+ CurrentCmdBuffer = 0;
+ CurrentCmdBufferIndex = 0;
+
+ /* Initialise registers */
+ gn_atem_registers_init();
+
+ /* Initial parser is AT routine */
+ Parser = gn_atem_at_parse;
+
+ /* Setup defaults for AT*C interpreter. */
+ SMSNumber = 1;
+ SMSType = GN_MT_ME;
+
+ /* Default message format is PDU */
+ MessageFormat = PDU_MODE;
+
+ /* Set the call passup so that we get notified of incoming calls */
+ data.call_notification = gn_atem_call_passup;
+ gn_sm_functions(GN_OP_SetCallNotification, &data, sm);
+
+ /* query model, revision and imei */
+ if (gn_sm_functions(GN_OP_Identify, &data, sm) != GN_ERR_NONE) return false;
+
+ /* We're ready to roll... */
+ gn_atem_initialised = true;
+ return (true);
+}
+
+
+/* Initialise the "registers" used by the virtual modem. */
+void gn_atem_registers_init(void)
+{
+ memset(ModemRegisters, 0, sizeof(ModemRegisters));
+
+ ModemRegisters[REG_RINGATA] = 0;
+ ModemRegisters[REG_RINGCNT] = 0;
+ ModemRegisters[REG_ESC] = '+';
+ ModemRegisters[REG_CR] = 13;
+ ModemRegisters[REG_LF] = 10;
+ ModemRegisters[REG_BS] = 8;
+ ModemRegisters[S35] = 7;
+ ModemRegisters[REG_ECHO] |= BIT_ECHO;
+ ModemRegisters[REG_VERBOSE] |= BIT_VERBOSE;
+ ModemRegisters[REG_CTRLZ] = 26;
+ ModemRegisters[REG_ESCAPE] = 27;
+
+ CallerIDMode = 0;
+}
+
+
+static void gn_atem_hangup_phone(void)
+{
+ if (IncomingCallNo > 0) {
+ rlp_user_request_set(Disc_Req, true);
+ gn_sm_loop(10, sm);
+ }
+ if (IncomingCallNo > 0) {
+ data.call_info->call_id = IncomingCallNo;
+ gn_sm_functions(GN_OP_CancelCall, &data, sm);
+ IncomingCallNo = -1;
+ }
+ dp_Initialise(PtyRDFD, PtyWRFD);
+}
+
+
+static void gn_atem_answer_phone(void)
+{
+ /* For now we'll also initialise the datapump + rlp code again */
+ dp_Initialise(PtyRDFD, PtyWRFD);
+ data.call_notification = dp_CallPassup;
+ gn_sm_functions(GN_OP_SetCallNotification, &data, sm);
+ data.call_info->call_id = IncomingCallNo;
+ gn_sm_functions(GN_OP_AnswerCall, &data, sm);
+ CommandMode = false;
+}
+
+
+/* This gets called to indicate an incoming call */
+void gn_atem_call_passup(gn_call_status CallStatus, gn_call_info *CallInfo, struct gn_statemachine *state)
+{
+ dprintf("gn_atem_call_passup called with %d\n", CallStatus);
+
+ switch (CallStatus) {
+ case GN_CALL_Incoming:
+ gn_atem_modem_result(MR_RING);
+ IncomingCallNo = CallInfo->call_id;
+ ModemRegisters[REG_RINGCNT]++;
+ gn_atem_cid_out(CallInfo);
+ if (ModemRegisters[REG_RINGATA] != 0) gn_atem_answer_phone();
+ break;
+ case GN_CALL_LocalHangup:
+ case GN_CALL_RemoteHangup:
+ IncomingCallNo = -1;
+ break;
+ default:
+ break;
+ }
+}
+
+/* This gets called to output caller id info of incoming call */
+void gn_atem_cid_out(gn_call_info *CallInfo)
+{
+ struct tm *now;
+ time_t nowh;
+ char buf[14]; /* 7 for "DATE = " + 4 digits + \n + \r + \0 */
+
+ nowh = time(NULL);
+ now = localtime(&nowh);
+
+ switch (CallerIDMode) {
+ case 0: /* no output */
+ break;
+ case 1: /* formatted CID */
+ snprintf(buf, sizeof(buf), "DATE = %02d%02d\r\n", now->tm_mon + 1, now->tm_mday);
+ gn_atem_string_out(buf);
+
+ snprintf(buf, sizeof(buf), "TIME = %02d%02d\r\n", now->tm_hour, now->tm_min);
+ gn_atem_string_out(buf);
+
+ /* TO DO: handle P and O numbers */
+ gn_atem_string_out("NMBR = ");
+ gn_atem_string_out(1 + CallInfo->number); /* skip leading "+" */
+ gn_atem_string_out("\r\nNAME = ");
+ gn_atem_string_out(CallInfo->name);
+ gn_atem_string_out("\r\n");
+
+ /* FIX ME: do a real emulation of rings after the first one (at a lower level than this) */
+ gn_atem_modem_result(MR_RING);
+
+ break;
+
+ }
+}
+
+/* Handler called when characters received from serial port.
+ calls state machine code to process it. */
+void gn_atem_incoming_data_handle(const char *buffer, int length)
+{
+ int count;
+ unsigned char out_buf[3];
+
+ for (count = 0; count < length ; count++) {
+
+ /* If it's a command terminator character, parse what
+ we have so far then go to next buffer. */
+ if (buffer[count] == ModemRegisters[REG_CR] ||
+ buffer[count] == ModemRegisters[REG_LF] ||
+ buffer[count] == ModemRegisters[REG_CTRLZ] ||
+ buffer[count] == ModemRegisters[REG_ESCAPE]) {
+
+ /* Echo character if appropriate. */
+ if (buffer[count] == ModemRegisters[REG_CR] &&
+ (ModemRegisters[REG_ECHO] & BIT_ECHO)) {
+ gn_atem_string_out("\r\n");
+ }
+
+ /* Save CTRL-Z and ESCAPE for the parser */
+ if (buffer[count] == ModemRegisters[REG_CTRLZ] ||
+ buffer[count] == ModemRegisters[REG_ESCAPE])
+ CmdBuffer[CurrentCmdBuffer][CurrentCmdBufferIndex++] = buffer[count];
+
+ CmdBuffer[CurrentCmdBuffer][CurrentCmdBufferIndex] = 0x00;
+
+ Parser(CmdBuffer[CurrentCmdBuffer]);
+
+ CurrentCmdBuffer++;
+ if (CurrentCmdBuffer >= MAX_CMD_BUFFERS) {
+ CurrentCmdBuffer = 0;
+ }
+ CurrentCmdBufferIndex = 0;
+
+ } else if (buffer[count] == ModemRegisters[REG_BS]) {
+ if (CurrentCmdBufferIndex > 0) {
+ /* Echo character if appropriate. */
+ if (ModemRegisters[REG_ECHO] & BIT_ECHO) {
+ gn_atem_string_out("\b \b");
+ }
+
+ CurrentCmdBufferIndex--;
+ }
+ } else {
+ /* Echo character if appropriate. */
+ if (ModemRegisters[REG_ECHO] & BIT_ECHO) {
+ out_buf[0] = buffer[count];
+ out_buf[1] = 0;
+ gn_atem_string_out((char *)out_buf);
+ }
+
+ /* Collect it to command buffer */
+ CmdBuffer[CurrentCmdBuffer][CurrentCmdBufferIndex++] = buffer[count];
+ if (CurrentCmdBufferIndex >= CMD_BUFFER_LENGTH) {
+ CurrentCmdBufferIndex = CMD_BUFFER_LENGTH;
+ }
+ }
+ }
+}
+
+
+/* Parser for standard AT commands. cmd_buffer must be null terminated. */
+void gn_atem_at_parse(char *cmd_buffer)
+{
+ char *buf;
+ int regno, val;
+ char str[256];
+
+ if (!cmd_buffer[0]) return;
+
+ if (strncasecmp (cmd_buffer, "AT", 2) != 0) {
+ gn_atem_modem_result(MR_ERROR);
+ return;
+ }
+
+ for (buf = &cmd_buffer[2]; *buf;) {
+ switch (toupper(*buf)) {
+
+ case 'Z':
+ /* Reset modem */
+ buf++;
+ switch (gn_atem_num_get(&buf)) {
+ case -1:
+ case 0: /* reset and load stored profile 0 */
+ case 1: /* reset and load stored profile 1 */
+ gn_atem_hangup_phone();
+ gn_atem_registers_init();
+ break;
+ default:
+ gn_atem_modem_result(MR_ERROR);
+ return;
+ }
+ break;
+
+ case 'A':
+ /* Answer call */
+ buf++;
+ gn_atem_answer_phone();
+ return;
+ break;
+
+ case 'D':
+ /* Dial Data :-) */
+ /* FIXME - should parse this better */
+ /* For now we'll also initialise the datapump + rlp code again */
+ dp_Initialise(PtyRDFD, PtyWRFD);
+ buf++;
+ if (toupper(*buf) == 'T' || toupper(*buf) == 'P') buf++;
+ while (*buf == ' ') buf++;
+ data.call_notification = dp_CallPassup;
+ gn_sm_functions(GN_OP_SetCallNotification, &data, sm);
+ snprintf(data.call_info->number, sizeof(data.call_info->number), "%s", buf);
+ if (ModemRegisters[S35] == 0)
+ data.call_info->type = GN_CALL_DigitalData;
+ else
+ data.call_info->type = GN_CALL_NonDigitalData;
+ data.call_info->send_number = GN_CALL_Default;
+ CommandMode = false;
+ if (gn_sm_functions(GN_OP_MakeCall, &data, sm) != GN_ERR_NONE) {
+ CommandMode = true;
+ dp_CallPassup(GN_CALL_RemoteHangup, NULL, NULL);
+ } else {
+ IncomingCallNo = data.call_info->call_id;
+ gn_sm_loop(10, sm);
+ }
+ return;
+ break;
+
+ case 'H':
+ /* Hang Up */
+ buf++;
+ switch (gn_atem_num_get(&buf)) {
+ case -1:
+ case 0: /* hook off the phone */
+ gn_atem_hangup_phone();
+ break;
+ case 1: /* hook on the phone */
+ break;
+ default:
+ gn_atem_modem_result(MR_ERROR);
+ return;
+ }
+ break;
+
+ case 'S':
+ /* Change registers */
+ buf++;
+ regno = gn_atem_num_get(&buf);
+ if (regno < 0 || regno >= MAX_MODEM_REGISTERS) {
+ gn_atem_modem_result(MR_ERROR);
+ return;
+ }
+ if (*buf == '=') {
+ buf++;
+ val = gn_atem_num_get(&buf);
+ if (val < 0 || val > 255) {
+ gn_atem_modem_result(MR_ERROR);
+ return;
+ }
+ ModemRegisters[regno] = val;
+ } else if (*buf == '?') {
+ buf++;
+ snprintf(str, sizeof(str), "%d\r\n", ModemRegisters[regno]);
+ gn_atem_string_out(str);
+ } else {
+ gn_atem_modem_result(MR_ERROR);
+ return;
+ }
+ break;
+
+ case 'E':
+ /* E - Turn Echo on/off */
+ buf++;
+ switch (gn_atem_num_get(&buf)) {
+ case -1:
+ case 0:
+ ModemRegisters[REG_ECHO] &= ~BIT_ECHO;
+ break;
+ case 1:
+ ModemRegisters[REG_ECHO] |= BIT_ECHO;
+ break;
+ default:
+ gn_atem_modem_result(MR_ERROR);
+ return;
+ }
+ break;
+
+ case 'Q':
+ /* Q - Turn Quiet on/off */
+ buf++;
+ switch (gn_atem_num_get(&buf)) {
+ case -1:
+ case 0:
+ ModemRegisters[REG_QUIET] &= ~BIT_QUIET;
+ break;
+ case 1:
+ ModemRegisters[REG_QUIET] |= BIT_QUIET;
+ break;
+ default:
+ gn_atem_modem_result(MR_ERROR);
+ return;
+ }
+ break;
+
+ case 'V':
+ /* V - Turn Verbose on/off */
+ buf++;
+ switch (gn_atem_num_get(&buf)) {
+ case -1:
+ case 0:
+ ModemRegisters[REG_VERBOSE] &= ~BIT_VERBOSE;
+ break;
+ case 1:
+ ModemRegisters[REG_VERBOSE] |= BIT_VERBOSE;
+ break;
+ default:
+ gn_atem_modem_result(MR_ERROR);
+ return;
+ }
+ break;
+
+ case 'X':
+ /* X - Set verbosity of the result messages */
+ buf++;
+ switch (gn_atem_num_get(&buf)) {
+ case -1:
+ case 0: val = 0x00; break;
+ case 1: val = 0x40; break;
+ case 2: val = 0x50; break;
+ case 3: val = 0x60; break;
+ case 4: val = 0x70; break;
+ case 5: val = 0x10; break;
+ default:
+ gn_atem_modem_result(MR_ERROR);
+ return;
+ }
+ ModemRegisters[S22] = (ModemRegisters[S22] & 0x8f) | val;
+ break;
+
+ case 'I':
+ /* I - info */
+ buf++;
+ switch (gn_atem_num_get(&buf)) {
+ case -1:
+ case 0: /* terminal id */
+ snprintf(str, sizeof(str), "%d\r\n", ModemRegisters[39]);
+ gn_atem_string_out(str);
+ break;
+ case 1: /* serial number (IMEI) */
+ snprintf(str, sizeof(str), "%s\r\n", imei);
+ gn_atem_string_out(str);
+ break;
+ case 2: /* phone revision */
+ snprintf(str, sizeof(str), "%s\r\n", revision);
+ gn_atem_string_out(str);
+ break;
+ case 3: /* modem revision */
+ gn_atem_string_out(VERSION "\r\n");
+ break;
+ case 4: /* OEM string */
+ snprintf(str, sizeof(str), "%s %s\r\n", manufacturer, model);
+ gn_atem_string_out(str);
+ break;
+ default:
+ gn_atem_modem_result(MR_ERROR);
+ return;
+ }
+ break;
+
+ /* Handle AT* commands (Nokia proprietary I think) */
+ case '*':
+ buf++;
+ if (!strcasecmp(buf, "NOKIATEST")) {
+ gn_atem_modem_result(MR_OK); /* FIXME? */
+ return;
+ } else {
+ if (!strcasecmp(buf, "C")) {
+ gn_atem_modem_result(MR_OK);
+ Parser = gn_atem_sms_parse;
+ return;
+ }
+ }
+ break;
+
+ /* + is the precursor to another set of commands */
+ case '+':
+ buf++;
+ switch (toupper(*buf)) {
+ case 'C':
+ buf++;
+ /* Returns true if error occured */
+ if (gn_atem_command_plusc(&buf) == true) {
+ gn_atem_modem_result(MR_ERROR);
+ return;
+ }
+ break;
+
+ case 'G':
+ buf++;
+ /* Returns true if error occured */
+ if (gn_atem_command_plusg(&buf) == true) {
+ gn_atem_modem_result(MR_ERROR);
+ return;
+ }
+ break;
+
+ default:
+ gn_atem_modem_result(MR_ERROR);
+ return;
+ }
+ break;
+
+ /* # is the precursor to another set of commands */
+ case '#':
+ buf++;
+ /* Returns true if error occured */
+ if (gn_atem_command_diesis(&buf) == true) {
+ gn_atem_modem_result(MR_ERROR);
+ return;
+ }
+ break;
+
+ default:
+ gn_atem_modem_result(MR_ERROR);
+ return;
+ }
+ }
+
+ gn_atem_modem_result(MR_OK);
+}
+
+
+static void gn_atem_sms_print(char *line, gn_sms *message, int mode)
+{
+ switch (mode) {
+ case INTERACT_MODE:
+ gsprintf(line, MAX_LINE_LENGTH,
+ _("\r\nDate/time: %d/%d/%d %d:%02d:%02d Sender: %s Msg Center: %s\r\nText: %s\r\n"),
+ message->smsc_time.day, message->smsc_time.month, message->smsc_time.year,
+ message->smsc_time.hour, message->smsc_time.minute, message->smsc_time.second,
+ message->remote.number, message->smsc.number, message->user_data[0].u.text);
+ break;
+ case TEXT_MODE:
+ if ((message->dcs.type == GN_SMS_DCS_GeneralDataCoding) &&
+ (message->dcs.u.general.alphabet == GN_SMS_DCS_8bit))
+ gsprintf(line, MAX_LINE_LENGTH,
+ _("\"%s\",\"%s\",,\"%02d/%02d/%02d,%02d:%02d:%02d+%02d\"\r\n%s"),
+ (message->status ? _("REC READ") : _("REC UNREAD")),
+ message->remote.number,
+ message->smsc_time.year, message->smsc_time.month, message->smsc_time.day,
+ message->smsc_time.hour, message->smsc_time.minute, message->smsc_time.second,
+ message->time.timezone, _("<Not implemented>"));
+ else
+ gsprintf(line, MAX_LINE_LENGTH,
+ _("\"%s\",\"%s\",,\"%02d/%02d/%02d,%02d:%02d:%02d+%02d\"\r\n%s"),
+ (message->status ? _("REC READ") : _("REC UNREAD")),
+ message->remote.number,
+ message->smsc_time.year, message->smsc_time.month, message->smsc_time.day,
+ message->smsc_time.hour, message->smsc_time.minute, message->smsc_time.second,
+ message->time.timezone, message->user_data[0].u.text);
+ break;
+ case PDU_MODE:
+ gsprintf(line, MAX_LINE_LENGTH, _("0,<Not implemented>"));
+ break;
+ default:
+ gsprintf(line, MAX_LINE_LENGTH, _("<Unknown mode>"));
+ break;
+ }
+}
+
+
+static void gn_atem_sms_handle()
+{
+ gn_error error;
+ char buffer[MAX_LINE_LENGTH];
+
+ data.sms->memory_type = SMSType;
+ data.sms->number = SMSNumber;
+ error = gn_sms_get(&data, sm);
+
+ switch (error) {
+ case GN_ERR_NONE:
+ gn_atem_sms_print(buffer, data.sms, INTERACT_MODE);
+ gn_atem_string_out(buffer);
+ break;
+ default:
+ gsprintf(buffer, MAX_LINE_LENGTH, _("\r\nNo message under number %d\r\n"), SMSNumber);
+ gn_atem_string_out(buffer);
+ break;
+ }
+ return;
+}
+
+/* Parser for SMS interactive mode */
+void gn_atem_sms_parse(char *buff)
+{
+ if (!strcasecmp(buff, "HELP")) {
+ gn_atem_string_out(_("\r\nThe following commands work...\r\n"));
+ gn_atem_string_out("DIR\r\n");
+ gn_atem_string_out("EXIT\r\n");
+ gn_atem_string_out("HELP\r\n");
+ return;
+ }
+
+ if (!strcasecmp(buff, "DIR")) {
+ SMSNumber = 1;
+ gn_atem_sms_handle();
+ Parser = gn_atem_dir_parse;
+ return;
+ }
+ if (!strcasecmp(buff, "EXIT")) {
+ Parser = gn_atem_at_parse;
+ gn_atem_modem_result(MR_OK);
+ return;
+ }
+ gn_atem_modem_result(MR_ERROR);
+}
+
+/* Parser for DIR sub mode of SMS interactive mode. */
+void gn_atem_dir_parse(char *buff)
+{
+ switch (toupper(*buff)) {
+ case 'P':
+ SMSNumber--;
+ gn_atem_sms_handle();
+ return;
+ case 'N':
+ SMSNumber++;
+ gn_atem_sms_handle();
+ return;
+ case 'D':
+ data.sms->memory_type = SMSType;
+ data.sms->number = SMSNumber;
+ if (gn_sm_functions(GN_OP_DeleteSMS, &data, sm) == GN_ERR_NONE) {
+ gn_atem_modem_result(MR_OK);
+ } else {
+ gn_atem_modem_result(MR_ERROR);
+ }
+ return;
+ case 'Q':
+ Parser= gn_atem_sms_parse;
+ gn_atem_modem_result(MR_OK);
+ return;
+ }
+ gn_atem_modem_result(MR_ERROR);
+}
+
+/* Parser for entering message content (+CMGS) */
+void gn_atem_sms_parseText(char *buff)
+{
+ static int index = 0;
+ int i, length;
+ char buffer[MAX_LINE_LENGTH];
+ gn_error error;
+
+ length = strlen(buff);
+
+ sms.user_data[0].type = GN_SMS_DATA_Text;
+
+ for (i = 0; i < length; i++) {
+
+ if (buff[i] == ModemRegisters[REG_CTRLZ]) {
+ /* Exit SMS text mode with sending */
+ sms.user_data[0].u.text[index] = 0;
+ sms.user_data[0].length = index;
+ index = 0;
+ Parser = gn_atem_at_parse;
+ dprintf("Sending SMS to %s (text: %s)\n", data.sms->remote.number, data.sms->user_data[0].u.text);
+
+ /* FIXME: set more SMS fields before sending */
+ error = gn_sms_send(&data, sm);
+
+ if (error == GN_ERR_NONE) {
+ gsprintf(buffer, MAX_LINE_LENGTH, "+CMGS: %d\r\n", data.sms->number);
+ gn_atem_string_out(buffer);
+ gn_atem_modem_result(MR_OK);
+ } else {
+ gn_atem_modem_result(MR_ERROR);
+ }
+ return;
+ } else if (buff[i] == ModemRegisters[REG_ESCAPE]) {
+ /* Exit SMS text mode without sending */
+ sms.user_data[0].u.text[index] = 0;
+ sms.user_data[0].length = index;
+ index = 0;
+ Parser = gn_atem_at_parse;
+ gn_atem_modem_result(MR_OK);
+ return;
+ } else {
+ /* Appent next char to message text */
+ sms.user_data[0].u.text[index++] = buff[i];
+ }
+ }
+
+ /* reached the end of line so insert \n and wait for more */
+ sms.user_data[0].u.text[index++] = '\n';
+ gn_atem_string_out("\r\n> ");
+}
+
+/* Handle AT+C commands, this is a quick hack together at this
+ stage. */
+bool gn_atem_command_plusc(char **buf)
+{
+ float rflevel = -1;
+ gn_rf_unit rfunits = GN_RF_CSQ;
+ char buffer[MAX_LINE_LENGTH], buffer2[MAX_LINE_LENGTH];
+ int status, index;
+ gn_error error;
+
+ if (strncasecmp(*buf, "SQ", 2) == 0) {
+ buf[0] += 2;
+
+ data.rf_unit = &rfunits;
+ data.rf_level = &rflevel;
+ if (gn_sm_functions(GN_OP_GetRFLevel, &data, sm) == GN_ERR_NONE) {
+ gsprintf(buffer, MAX_LINE_LENGTH, "+CSQ: %0.0f, 99\r\n", *(data.rf_level));
+ gn_atem_string_out(buffer);
+ return (false);
+ } else {
+ return (true);
+ }
+ }
+
+ /* AT+CGMI is Manufacturer information for the ME (phone) so
+ it should be Nokia rather than gnokii... */
+ if (strncasecmp(*buf, "GMI", 3) == 0) {
+ buf[0] += 3;
+ gsprintf(buffer, MAX_LINE_LENGTH, "%s\r\n", data.manufacturer);
+ gn_atem_string_out(buffer);
+ return (false);
+ }
+
+ /* AT+CGSN is IMEI */
+ if (strncasecmp(*buf, "GSN", 3) == 0) {
+ buf[0] += 3;
+ strcpy(data.imei, "+CME ERROR: 0");
+ if (gn_sm_functions(GN_OP_GetImei, &data, sm) == GN_ERR_NONE) {
+ gsprintf(buffer, MAX_LINE_LENGTH, "%s\r\n", data.imei);
+ gn_atem_string_out(buffer);
+ return (false);
+ } else {
+ return (true);
+ }
+ }
+
+ /* AT+CGMR is Revision (hardware) */
+ if (strncasecmp(*buf, "GMR", 3) == 0) {
+ buf[0] += 3;
+ strcpy(data.revision, "+CME ERROR: 0");
+ if (gn_sm_functions(GN_OP_GetRevision, &data, sm) == GN_ERR_NONE) {
+ gsprintf(buffer, MAX_LINE_LENGTH, "%s\r\n", data.revision);
+ gn_atem_string_out(buffer);
+ return (false);
+ } else {
+ return (true);
+ }
+ }
+
+ /* AT+CGMM is Model code */
+ if (strncasecmp(*buf, "GMM", 3) == 0) {
+ buf[0] += 3;
+ strcpy(data.model, "+CME ERROR: 0");
+ if (gn_sm_functions(GN_OP_GetModel, &data, sm) == GN_ERR_NONE) {
+ gsprintf(buffer, MAX_LINE_LENGTH, "%s\r\n", data.model);
+ gn_atem_string_out(buffer);
+ return (false);
+ } else {
+ return (true);
+ }
+ }
+
+ /* AT+CMGD is deleting a message */
+ if (strncasecmp(*buf, "MGD", 3) == 0) {
+ buf[0] += 3;
+ switch (**buf) {
+ case '=':
+ buf[0]++;
+ index = atoi(*buf);
+ buf[0] += strlen(*buf);
+
+ data.sms->memory_type = SMSType;
+ data.sms->number = index;
+ error = gn_sm_functions(GN_OP_DeleteSMS, &data, sm);
+
+ switch (error) {
+ case GN_ERR_NONE:
+ break;
+ default:
+ gsprintf(buffer, MAX_LINE_LENGTH, "\r\n+CMS ERROR: %d\r\n", error);
+ gn_atem_string_out(buffer);
+ return (true);
+ }
+ break;
+ default:
+ return (true);
+ }
+ return (false);
+ }
+
+ /* AT+CMGF is mode selection for message format */
+ if (strncasecmp(*buf, "MGF", 3) == 0) {
+ buf[0] += 3;
+ switch (**buf) {
+ case '=':
+ buf[0]++;
+ switch (**buf) {
+ case '0':
+ buf[0]++;
+ MessageFormat = PDU_MODE;
+ break;
+ case '1':
+ buf[0]++;
+ MessageFormat = TEXT_MODE;
+ break;
+ default:
+ return (true);
+ }
+ break;
+ case '?':
+ buf[0]++;
+ gsprintf(buffer, MAX_LINE_LENGTH, "+CMGF: %d\r\n", MessageFormat);
+ gn_atem_string_out(buffer);
+ break;
+ default:
+ return (true);
+ }
+ return (false);
+ }
+
+ /* AT+CMGR is reading a message */
+ if (strncasecmp(*buf, "MGR", 3) == 0) {
+ buf[0] += 3;
+ switch (**buf) {
+ case '=':
+ buf[0]++;
+ index = atoi(*buf);
+ buf[0] += strlen(*buf);
+
+ data.sms->memory_type = SMSType;
+ data.sms->number = index;
+ error = gn_sms_get(&data, sm);
+
+ switch (error) {
+ case GN_ERR_NONE:
+ gn_atem_sms_print(buffer2, data.sms, MessageFormat);
+ gsprintf(buffer, MAX_LINE_LENGTH, "+CMGR: %s\r\n", buffer2);
+ gn_atem_string_out(buffer);
+ break;
+ default:
+ gsprintf(buffer, MAX_LINE_LENGTH, "\r\n+CMS ERROR: %d\r\n", error);
+ gn_atem_string_out(buffer);
+ return (true);
+ }
+ break;
+ default:
+ return (true);
+ }
+ return (false);
+ }
+
+ /* AT+CMGS is sending a message */
+ if (strncasecmp(*buf, "MGS", 3) == 0) {
+ buf[0] += 3;
+ switch (**buf) {
+ case '=':
+ buf[0]++;
+ if (sscanf(*buf, "\"%[+0-9a-zA-Z ]\"", sms.remote.number)) {
+ Parser = gn_atem_sms_parseText;
+ buf[0] += strlen(*buf);
+ gn_atem_string_out("\r\n> ");
+ }
+ return (true);
+ default:
+ return (true);
+ }
+ return (false);
+ }
+
+ /* AT+CMGL is listing messages */
+ if (strncasecmp(*buf, "MGL", 3) == 0) {
+ buf[0] += 3;
+ status = -1;
+
+ switch (**buf) {
+ case 0:
+ case '=':
+ buf[0]++;
+ /* process <stat> parameter */
+ if (*(*buf-1) == 0 || /* i.e. no parameter given */
+ strcasecmp(*buf, "1") == 0 ||
+ strcasecmp(*buf, "3") == 0 ||
+ strcasecmp(*buf, "\"REC READ\"") == 0 ||
+ strcasecmp(*buf, "\"STO SENT\"") == 0) {
+ status = GN_SMS_Sent;
+ } else if (strcasecmp(*buf, "0") == 0 ||
+ strcasecmp(*buf, "2") == 0 ||
+ strcasecmp(*buf, "\"REC UNREAD\"") == 0 ||
+ strcasecmp(*buf, "\"STO UNSENT\"") == 0) {
+ status = GN_SMS_Unsent;
+ } else if (strcasecmp(*buf, "4") == 0 ||
+ strcasecmp(*buf, "\"ALL\"") == 0) {
+ status = 4; /* ALL */
+ } else {
+ return true;
+ }
+ buf[0] += strlen(*buf);
+
+ /* check all message storages */
+ for (index = 1; index <= 20; index++) {
+
+ data.sms->memory_type = SMSType;
+ data.sms->number = index;
+ error = gn_sms_get(&data, sm);
+
+ switch (error) {
+ case GN_ERR_NONE:
+ /* print messsage if it has the required status */
+ if (data.sms->status == status || status == 4 /* ALL */) {
+ gn_atem_sms_print(buffer2, data.sms, MessageFormat);
+ gsprintf(buffer, MAX_LINE_LENGTH, "+CMGL: %d,%s\r\n", index, buffer2);
+ gn_atem_string_out(buffer);
+ }
+ break;
+ case GN_ERR_EMPTYLOCATION:
+ /* don't care if this storage is empty */
+ break;
+ default:
+ /* print other error codes and quit */
+ gsprintf(buffer, MAX_LINE_LENGTH, "\r\n+CMS ERROR: %d\r\n", error);
+ gn_atem_string_out(buffer);
+ return (true);
+ }
+ }
+ break;
+ default:
+ return (true);
+ }
+ return (false);
+ }
+
+ return (true);
+}
+
+/* AT+G commands. Some of these responses are a bit tongue in cheek... */
+bool gn_atem_command_plusg(char **buf)
+{
+ char buffer[MAX_LINE_LENGTH];
+
+ /* AT+GMI is Manufacturer information for the TA (Terminal Adaptor) */
+ if (strncasecmp(*buf, "MI", 3) == 0) {
+ buf[0] += 2;
+
+ gn_atem_string_out(_("Hugh Blemings, Pavel Janik ml. and others...\r\n"));
+ return (false);
+ }
+
+ /* AT+GMR is Revision information for the TA (Terminal Adaptor) */
+ if (strncasecmp(*buf, "MR", 3) == 0) {
+ buf[0] += 2;
+ gsprintf(buffer, MAX_LINE_LENGTH, "%s %s %s\r\n", VERSION, __TIME__, __DATE__);
+
+ gn_atem_string_out(buffer);
+ return (false);
+ }
+
+ /* AT+GMM is Model information for the TA (Terminal Adaptor) */
+ if (strncasecmp(*buf, "MM", 3) == 0) {
+ buf[0] += 2;
+
+ gsprintf(buffer, MAX_LINE_LENGTH, _("gnokii configured on %s for models %s\r\n"), sm->config.port_device, sm->driver.phone.models);
+ gn_atem_string_out(buffer);
+ return (false);
+ }
+
+ /* AT+GSN is Serial number for the TA (Terminal Adaptor) */
+ if (strncasecmp(*buf, "SN", 3) == 0) {
+ buf[0] += 2;
+
+ gsprintf(buffer, MAX_LINE_LENGTH, _("none built in, choose your own\r\n"));
+ gn_atem_string_out(buffer);
+ return (false);
+ }
+
+ return (true);
+}
+
+/* Handle AT# commands */
+bool gn_atem_command_diesis(char **buf)
+{
+ int number;
+ char buffer[MAX_LINE_LENGTH];
+
+ if (strncasecmp(*buf, "CID", 3) == 0) {
+ buf[0] += 3;
+ switch (**buf) {
+ case '?':
+ buf[0]++;
+ gsprintf(buffer, MAX_LINE_LENGTH, "%d\r\n", CallerIDMode);
+ gn_atem_string_out(buffer);
+ return (false);
+ case '=':
+ buf[0]++;
+ if (**buf == '?') {
+ buf[0]++;
+ gn_atem_string_out("0,1\r\n");
+ return (false);
+ } else {
+ number = gn_atem_num_get(buf);
+ if ( number == 0 || number == 1 ) {
+ CallerIDMode = number;
+ return (false);
+ }
+ }
+ }
+ }
+ return (true);
+}
+
+/* Send a result string back. There is much work to do here, see
+ the code in the isdn driver for an idea of where it's heading... */
+void gn_atem_modem_result(int code)
+{
+ char buffer[16];
+
+ if (!(ModemRegisters[REG_VERBOSE] & BIT_VERBOSE)) {
+ sprintf(buffer, "%d\r\n", code);
+ gn_atem_string_out(buffer);
+ } else {
+ switch (code) {
+ case MR_OK:
+ gn_atem_string_out("OK\r\n");
+ break;
+
+ case MR_ERROR:
+ gn_atem_string_out("ERROR\r\n");
+ break;
+
+ case MR_CARRIER:
+ gn_atem_string_out("CARRIER\r\n");
+ break;
+
+ case MR_CONNECT:
+ gn_atem_string_out("CONNECT\r\n");
+ break;
+
+ case MR_NOCARRIER:
+ gn_atem_string_out("NO CARRIER\r\n");
+ break;
+ case MR_RING:
+ gn_atem_string_out("RING\r\n");
+ break;
+ default:
+ gn_atem_string_out(_("\r\nUnknown Result Code!\r\n"));
+ break;
+ }
+ }
+
+}
+
+
+/* Get integer from char-pointer, set pointer to end of number
+ stolen basically verbatim from ISDN code. */
+int gn_atem_num_get(char **p)
+{
+ int v = -1;
+
+ while (*p[0] >= '0' && *p[0] <= '9') {
+ v = ((v < 0) ? 0 : (v * 10)) + (int) ((*p[0]++) - '0');
+ }
+
+ return v;
+}
+
+/* Write string to virtual modem port, either pty or
+ STDOUT as appropriate. This function is only used during
+ command mode - data pump is used when connected. */
+void gn_atem_string_out(char *buffer)
+{
+ int count = 0;
+ char out_char;
+
+ while (count < strlen(buffer)) {
+
+ /* Translate CR/LF/BS as appropriate */
+ switch (buffer[count]) {
+ case '\r':
+ out_char = ModemRegisters[REG_CR];
+ break;
+ case '\n':
+ out_char = ModemRegisters[REG_LF];
+ break;
+ case '\b':
+ out_char = ModemRegisters[REG_BS];
+ break;
+ default:
+ out_char = buffer[count];
+ break;
+ }
+
+ sm->info->write(sm->info->opaque, "%c", out_char);
+ count++;
+ }
+}
Added: trunk/src/host/qemu-neo1973/gnokiigsm/at-emulator.h
===================================================================
--- trunk/src/host/qemu-neo1973/gnokiigsm/at-emulator.h 2007-05-16 22:38:21 UTC (rev 1986)
+++ trunk/src/host/qemu-neo1973/gnokiigsm/at-emulator.h 2007-05-17 00:24:48 UTC (rev 1987)
@@ -0,0 +1,71 @@
+/*
+
+ $Id: at-emulator.h,v 1.12 2004/09/20 16:05:38 bozo Exp $
+
+ G N O K I I
+
+ A Linux/Unix toolset and driver for Nokia mobile phones.
+
+ This file is part of gnokii.
+
+ Gnokii 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.
+
+ Gnokii 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 gnokii; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+ Copyright (C) 1999, 2000 Hugh Blemings & Pavel Janík ml.
+
+ Header file for AT emulator code.
+
+*/
+
+#ifndef _gnokii_data_at_emulator_h
+#define _gnokii_data_at_emulator_h
+
+#include "compat.h"
+#include "gnokii.h"
+
+ /* Prototypes */
+bool gn_atem_initialise(int read_fd, int write_fd, struct gn_statemachine *sm);
+void gn_atem_incoming_data_handle(const char *buffer, int length);
+void gn_atem_registers_init(void);
+void gn_atem_string_out(char *buffer);
+void gn_atem_at_parse(char *cmd_buffer);
+void gn_atem_sms_parse(char *cmd_buffer);
+void gn_atem_dir_parse(char *cmd_buffer);
+bool gn_atem_command_plusc(char **buf);
+bool gn_atem_command_plusg(char **buf);
+int gn_atem_num_get(char **p);
+void gn_atem_modem_result(int code);
+void gn_atem_call_passup(gn_call_status call_status, gn_call_info *call_info, struct gn_statemachine *state);
+void gn_atem_cid_out(gn_call_info *callinfo);
+bool gn_atem_command_diesis(char **buf);
+
+ /* Global variables */
+extern bool gn_atem_initialised;
+extern struct gn_statemachine *sm;
+extern gn_data data;
+
+ /* Definition of modem result codes - these are returned to "terminal"
+ numerically or as a string depending on the setting of S12 */
+
+ /* FIX ME - Numeric values for everything except OK and ERROR
+ are guesses as I've not got an AT reference handy. HAB */
+
+#define MR_OK (0)
+#define MR_ERROR (4)
+#define MR_NOCARRIER (5)
+#define MR_CARRIER (2)
+#define MR_CONNECT (3)
+#define MR_RING (6)
+
+#endif /* _gnokii_data_at_emulator_h */
Added: trunk/src/host/qemu-neo1973/gnokiigsm/bitmaps.h
===================================================================
--- trunk/src/host/qemu-neo1973/gnokiigsm/bitmaps.h 2007-05-16 22:38:21 UTC (rev 1986)
+++ trunk/src/host/qemu-neo1973/gnokiigsm/bitmaps.h 2007-05-17 00:24:48 UTC (rev 1987)
@@ -0,0 +1,92 @@
+/*
+
+ $Id: bitmaps.h,v 1.31 2006/11/08 19:45:37 dforsi Exp $
+
+ G N O K I I
+
+ A Linux/Unix toolset and driver for the mobile phones.
+
+ This file is part of gnokii.
+
+ Gnokii 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.
+
+ Gnokii 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 gnokii; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+ Copyright (C) 1999-2000 Hugh Blemings & Pavel Janík ml.
+ Copyright (C) 2000 Marcin Wiacek, Chris Kemp
+ Copyright (C) 2001-2003 Pawel Kot
+ Copyright (C) 2002 Pavel Machek
+
+ Functions for common bitmap operations.
+
+*/
+
+#ifndef _gnokii_bitmaps_h
+#define _gnokii_bitmaps_h
+
+#include <stdio.h>
+
+#include <error.h>
+#include <common.h>
+
+/* Bitmap types. These do *not* correspond to headers[] in gsm-sms.c. */
+
+typedef enum {
+ GN_BMP_None = 0,
+ GN_BMP_StartupLogo = 50,
+ GN_BMP_PictureMessage,
+ GN_BMP_OperatorLogo,
+ GN_BMP_CallerLogo,
+ GN_BMP_WelcomeNoteText,
+ GN_BMP_DealerNoteText,
+ GN_BMP_NewOperatorLogo,
+ GN_BMP_EMSPicture,
+ GN_BMP_EMSAnimation, /* First bitmap in animation should have this type */
+ GN_BMP_EMSAnimation2, /* ...second, third and fourth should have this type */
+} gn_bmp_types;
+
+#define GN_BMP_MAX_SIZE 1000
+
+/* Structure to hold incoming/outgoing bitmaps (and welcome-notes). */
+
+typedef struct {
+ unsigned char height; /* Bitmap height (pixels) */
+ unsigned char width; /* Bitmap width (pixels) */
+ unsigned int size; /* Bitmap size (bytes) */
+ gn_bmp_types type; /* Bitmap type */
+ char netcode[7]; /* Network operator code */
+ char text[256]; /* Text used for welcome-note or callergroup name */
+ char dealertext[256]; /* Text used for dealer welcome-note */
+ int dealerset; /* Is dealer welcome-note set now ? */
+ unsigned char bitmap[GN_BMP_MAX_SIZE]; /* Actual Bitmap */
+ char number; /* Caller group number */
+ int ringtone; /* Ringtone no sent with caller group */
+ unsigned char ringtone_id[6];
+} gn_bmp;
+
+GNOKII_API gn_error gn_file_bitmap_read(char *filename, gn_bmp *bitmap, gn_phone *info);
+GNOKII_API gn_error gn_file_bitmap_save(char *filename, gn_bmp *bitmap, gn_phone *info);
+GNOKII_API gn_error gn_file_bitmap_show(char *filename);
+
+GNOKII_API gn_error gn_bmp_null(gn_bmp *bmp, gn_phone *info);
+GNOKII_API void gn_bmp_point_set(gn_bmp *bmp, int x, int y);
+GNOKII_API void gn_bmp_point_clear(gn_bmp *bmp, int x, int y);
+GNOKII_API int gn_bmp_point(gn_bmp *bmp, int x, int y);
+GNOKII_API void gn_bmp_clear(gn_bmp *bmp);
+GNOKII_API void gn_bmp_resize(gn_bmp *bitmap, gn_bmp_types target, gn_phone *info);
+GNOKII_API void gn_bmp_print(gn_bmp *bitmap, FILE *f);
+
+GNOKII_API int gn_bmp_sms_encode(gn_bmp *bitmap, unsigned char *message);
+GNOKII_API gn_error gn_bmp_sms_read(int type, unsigned char *message, unsigned char *code, gn_bmp *bitmap);
+
+#endif /* _gnokii_bitmaps_h */
Added: trunk/src/host/qemu-neo1973/gnokiigsm/call.h
===================================================================
--- trunk/src/host/qemu-neo1973/gnokiigsm/call.h 2007-05-16 22:38:21 UTC (rev 1986)
+++ trunk/src/host/qemu-neo1973/gnokiigsm/call.h 2007-05-17 00:24:48 UTC (rev 1987)
@@ -0,0 +1,98 @@
+/*
+
+ $Id: call.h,v 1.13 2006/06/11 16:39:11 deller Exp $
+
+ G N O K I I
+
+ A Linux/Unix toolset and driver for the mobile phones.
+
+ This file is part of gnokii.
+
+ Gnokii 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.
+
+ Gnokii 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 gnokii; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+ Copyright (C) 1999-2000 Hugh Blemings, Pavel Janik
+ Copyright (C) 2002-2003 Pawel Kot, BORBELY Zoltan <bozo at andrews.hu>
+
+ Include file for the call management library.
+
+*/
+
+#ifndef _gnokii_call_h
+#define _gnokii_call_h
+
+#include <error.h>
+
+typedef enum {
+ GN_CALL_Voice, /* Voice call */
+ GN_CALL_NonDigitalData, /* Data call on non digital line */
+ GN_CALL_DigitalData /* Data call on digital line */
+} gn_call_type;
+
+typedef enum {
+ GN_CALL_Never, /* Never send my number */
+ GN_CALL_Always, /* Always send my number */
+ GN_CALL_Default /* Use the network default settings */
+} gn_call_send_number;
+
+typedef enum {
+ GN_CALL_Idle,
+ GN_CALL_Ringing,
+ GN_CALL_Dialing,
+ GN_CALL_Incoming, /* Incoming call */
+ GN_CALL_LocalHangup, /* Local end terminated the call */
+ GN_CALL_RemoteHangup, /* Remote end terminated the call */
+ GN_CALL_Established, /* Remote end answered the call */
+ GN_CALL_Held, /* Call placed on hold */
+ GN_CALL_Resumed /* Held call resumed */
+} gn_call_status;
+
+typedef struct {
+ gn_call_type type;
+ char number[GN_PHONEBOOK_NUMBER_MAX_LENGTH + 1];
+ char name[GN_PHONEBOOK_NAME_MAX_LENGTH + 1];
+ gn_call_send_number send_number;
+ int call_id;
+} gn_call_info;
+
+typedef struct {
+ int call_id;
+ int channel;
+ char number[GN_PHONEBOOK_NUMBER_MAX_LENGTH + 1];
+ char name[GN_PHONEBOOK_NAME_MAX_LENGTH + 1];
+ gn_call_status state;
+ gn_call_status prev_state;
+} gn_call_active;
+
+/* Call functions and structs */
+typedef struct {
+ struct gn_statemachine *state;
+ int call_id;
+ gn_call_status status;
+ gn_call_type type;
+ char remote_number[GN_PHONEBOOK_NUMBER_MAX_LENGTH + 1];
+ char remote_name[GN_PHONEBOOK_NAME_MAX_LENGTH + 1];
+ struct timeval start_time;
+ struct timeval answer_time;
+ int local_originated;
+} gn_call;
+
+#define GN_CALL_MAX_PARALLEL 2
+
+GNOKII_API void gn_call_notifier(gn_call_status call_status, gn_call_info *call_info, struct gn_statemachine *state);
+GNOKII_API gn_call *gn_call_get_active(int call_id);
+GNOKII_API gn_error gn_call_answer(int call_id);
+GNOKII_API gn_error gn_call_cancel(int call_id);
+
+#endif /* _gnokii_call_h */
Added: trunk/src/host/qemu-neo1973/gnokiigsm/common.h
===================================================================
--- trunk/src/host/qemu-neo1973/gnokiigsm/common.h 2007-05-16 22:38:21 UTC (rev 1986)
+++ trunk/src/host/qemu-neo1973/gnokiigsm/common.h 2007-05-17 00:24:48 UTC (rev 1987)
@@ -0,0 +1,806 @@
+/*
+
+ $Id: common.h,v 1.152 2007/05/04 19:41:34 pkot Exp $
+
+ G N O K I I
+
+ A Linux/Unix toolset and driver for Nokia the phones.
+
+ This file is part of gnokii.
+
+ Gnokii 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.
+
+ Gnokii 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 gnokii; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+ Copyright (C) 1999-2000 Hugh Blemings & Pavel Janík ml.
+ Copyright (C) 2001-2004 Pawel Kot, BORBELY Zoltan
+ Copyright (C) 2001 Manfred Jonsson, Marian Jancar, Chris Kemp, Marcin Wiacek
+ Copyright (C) 2001-2002 Pavel Machek
+ Copyright (C) 2002 Markus Plail
+
+ Header file for the definitions, enums etc. that are used by all models of
+ handset.
+
+*/
+
+#ifndef _gnokii_common_h
+#define _gnokii_common_h
+
+#include <rlp-common.h>
+
+/* Type of connection. Now we support serial connection with FBUS cable and
+ IR (only with 61x0 models) */
+typedef enum {
+ GN_CT_NONE = -1,/* no connection type (error) */
+ GN_CT_Serial, /* Serial connection. */
+ GN_CT_DAU9P, /* Serial connection using DAU9P cable; use only with 6210/7110 if you want faster initialization */
+ GN_CT_DLR3P, /* Serial connection using DLR3P cable */
+ GN_CT_Infrared, /* Infrared connection. */
+ GN_CT_Irda, /* Linux IrDA support */
+ GN_CT_Bluetooth,/* Linux Bluetooth support */
+ GN_CT_Tekram, /* Tekram Ir-Dongle */
+ GN_CT_TCP, /* TCP network connection */
+ GN_CT_M2BUS, /* Serial connection with M2BUS protocol */
+ GN_CT_DKU2, /* DKU2 usb connection using nokia_dku2 kernel driver */
+ GN_CT_DKU2LIBUSB /* DKU2 usb connection using libusb */
+} gn_connection_type;
+
+/* Maximum length of device name for serial port */
+
+#define GN_DEVICE_NAME_MAX_LENGTH (32)
+
+/* Define an enum for specifying memory types for retrieving phonebook
+ entries, SMS messages etc. This type is not mobile specific - the model
+ code should take care of translation to mobile specific numbers - see 6110
+ code.
+ 01/07/99: Two letter codes follow GSM 07.07 release 6.2.0
+*/
+typedef enum {
+ GN_MT_ME, /* Internal memory of the mobile equipment */
+ GN_MT_SM, /* SIM card memory */
+ GN_MT_FD, /* Fixed dial numbers */
+ GN_MT_ON, /* Own numbers */
+ GN_MT_EN, /* Emergency numbers */
+ GN_MT_DC, /* Dialled numbers */
+ GN_MT_RC, /* Received numbers */
+ GN_MT_MC, /* Missed numbers */
+ GN_MT_LD, /* Last dialed */
+ GN_MT_MT, /* combined ME and SIM phonebook */
+ GN_MT_TA, /* for compatibility only: TA=computer memory */
+ GN_MT_CB, /* Currently selected memory */
+ GN_MT_IN, /* Inbox for folder aware phones */
+ GN_MT_OU, /* Outbox */
+ GN_MT_AR, /* Archive */
+ GN_MT_TE, /* Templates */
+ GN_MT_F1, /* 1st CUSTOM FOLDER */
+ GN_MT_F2,
+ GN_MT_F3,
+ GN_MT_F4,
+ GN_MT_F5,
+ GN_MT_F6,
+ GN_MT_F7,
+ GN_MT_F8,
+ GN_MT_F9,
+ GN_MT_F10,
+ GN_MT_F11,
+ GN_MT_F12,
+ GN_MT_F13,
+ GN_MT_F14,
+ GN_MT_F15,
+ GN_MT_F16,
+ GN_MT_F17,
+ GN_MT_F18,
+ GN_MT_F19,
+ GN_MT_F20, /* 20th CUSTOM FOLDER */
+ GN_MT_XX = 0xff /* Error code for unknown memory type (returned by fbus-xxxx functions). */
+} gn_memory_type;
+
+/* Power source types */
+typedef enum {
+ GN_PS_ACDC = 1, /* AC/DC powered (charging) */
+ GN_PS_BATTERY /* Internal battery */
+} gn_power_source;
+
+/* Definition of security codes. */
+typedef enum {
+ GN_SCT_SecurityCode = 0x01, /* Security code. */
+ GN_SCT_Pin, /* PIN. */
+ GN_SCT_Pin2, /* PIN 2. */
+ GN_SCT_Puk, /* PUK. */
+ GN_SCT_Puk2, /* PUK 2. */
+ GN_SCT_None /* Code not needed. */
+} gn_security_code_type;
+
+/* Security code definition. */
+typedef struct {
+ gn_security_code_type type; /* Type of the code. */
+ char code[10]; /* Actual code. */
+ char new_code[10]; /* New code. */
+} gn_security_code;
+
+/* This structure is used to get the current network status */
+typedef struct {
+ char network_code[10]; /* GSM network code */
+ unsigned char cell_id[10]; /* CellID */
+ unsigned char LAC[10]; /* LAC */
+} gn_network_info;
+
+/* Limits for sizing of array in gn_phonebook_entry. Individual handsets may
+ not support these lengths so they have their own limits set. */
+#define GN_PHONEBOOK_NAME_MAX_LENGTH 61 /* For 6510 */
+#define GN_PHONEBOOK_NUMBER_MAX_LENGTH 49 /* For 6510 */
+#define GN_PHONEBOOK_SUBENTRIES_MAX_NUMBER 64 /* it was 10 for 6510, but modern phones supports more */
+ /* 7110 is able to have in one
+ * entry 5 numbers and 4
+ * texts [email,notice,postal,url].
+ * Dirk reported on gnokii-users that N70 has the following additional fields:
+ * - Company
+ * - Position
+ * - Aliasname
+ * - DTMF
+ * - User ID
+ * - all postal fields:
+ * - PO Box
+ * - Addition
+ * - Street
+ * - Zip Code
+ * - City
+ * - State/Province
+ * - Country
+ * - Birthday
+ */
+#define GN_PHONEBOOK_CALLER_GROUPS_MAX_NUMBER 5
+#define GN_PHONEBOOK_ENTRY_MAX_LENGTH 1024
+
+/* This data type is used to report the number of used and free positions in
+ memory (sim or internal). */
+typedef struct {
+ gn_memory_type memory_type; /* Type of the memory */
+ int used; /* Number of used positions */
+ int free; /* Number of free positions */
+} gn_memory_status;
+
+/* General date and time structure. It is used for the SMS, calendar, alarm
+ * settings, clock etc. */
+typedef struct {
+ int year; /* The complete year specification - e.g. 1999. Y2K :-) */
+ int month; /* January = 1 */
+ int day;
+ int hour;
+ int minute;
+ int second;
+ int timezone; /* The difference between local time and GMT.
+ Note that different SMSC software treat this field
+ in the different ways. */
+} gn_timestamp;
+
+/* Some phones (at the moment 7110/6510 series) supports extended phonebook
+ with additional data. Here we have structures for them */
+typedef enum {
+ GN_PHONEBOOK_NUMBER_None = 0x00,
+ GN_PHONEBOOK_NUMBER_Common = 0x01,
+ GN_PHONEBOOK_NUMBER_Home = 0x02,
+ GN_PHONEBOOK_NUMBER_Mobile = 0x03,
+ GN_PHONEBOOK_NUMBER_Fax = 0x04,
+ GN_PHONEBOOK_NUMBER_Work = 0x06,
+ GN_PHONEBOOK_NUMBER_General = 0x0a,
+} gn_phonebook_number_type;
+
+typedef enum {
+ GN_PHONEBOOK_ENTRY_Name = 0x07,
+ GN_PHONEBOOK_ENTRY_Email = 0x08,
+ GN_PHONEBOOK_ENTRY_Postal = 0x09,
+ GN_PHONEBOOK_ENTRY_Note = 0x0a,
+ GN_PHONEBOOK_ENTRY_Number = 0x0b,
+ GN_PHONEBOOK_ENTRY_Ringtone = 0x0c,
+ GN_PHONEBOOK_ENTRY_Date = 0x13, /* Date is used for DC,RC,etc (last calls) */
+ GN_PHONEBOOK_ENTRY_Pointer = 0x1a, /* Pointer to the other memory */
+ GN_PHONEBOOK_ENTRY_Logo = 0x1b,
+ GN_PHONEBOOK_ENTRY_LogoSwitch = 0x1c,
+ GN_PHONEBOOK_ENTRY_Group = 0x1e,
+ GN_PHONEBOOK_ENTRY_URL = 0x2c,
+ GN_PHONEBOOK_ENTRY_Location = 0x2f, /* ??? */
+ GN_PHONEBOOK_ENTRY_Image = 0x33,
+ GN_PHONEBOOK_ENTRY_RingtoneAdv = 0x37,
+ GN_PHONEBOOK_ENTRY_UserID = 0x38,
+ GN_PHONEBOOK_ENTRY_PTTAddress = 0x3f, /* string */
+ GN_PHONEBOOK_ENTRY_FirstName = 0x46,
+ GN_PHONEBOOK_ENTRY_LastName = 0x47,
+ GN_PHONEBOOK_ENTRY_PostalAddress = 0x4a,
+ GN_PHONEBOOK_ENTRY_ExtendedAddress = 0x4b,
+ GN_PHONEBOOK_ENTRY_Street = 0x4c,
+ GN_PHONEBOOK_ENTRY_City = 0x4d,
+ GN_PHONEBOOK_ENTRY_StateProvince = 0x4e,
+ GN_PHONEBOOK_ENTRY_ZipCode = 0x4f,
+ GN_PHONEBOOK_ENTRY_Country = 0x50,
+ GN_PHONEBOOK_ENTRY_FormalName = 0x52,
+ GN_PHONEBOOK_ENTRY_JobTitle = 0x54,
+ GN_PHONEBOOK_ENTRY_Company = 0x55,
+ GN_PHONEBOOK_ENTRY_Nickname = 0x56,
+ GN_PHONEBOOK_ENTRY_Birthday = 0x57,
+} gn_phonebook_entry_type;
+
+typedef enum {
+ GN_PHONEBOOK_GROUP_Family,
+ GN_PHONEBOOK_GROUP_Vips,
+ GN_PHONEBOOK_GROUP_Friends,
+ GN_PHONEBOOK_GROUP_Work,
+ GN_PHONEBOOK_GROUP_Others,
+ GN_PHONEBOOK_GROUP_None,
+} gn_phonebook_group_type;
+
+#define GN_PHONEBOOK_PERSON_MAX_LENGTH 64
+
+typedef struct {
+ int has_person;
+ char family_name[GN_PHONEBOOK_PERSON_MAX_LENGTH + 1]; /* GN_PHONEBOOK_ENTRY_LastName */
+ char given_name[GN_PHONEBOOK_PERSON_MAX_LENGTH + 1]; /* GN_PHONEBOOK_ENTRY_FirstName */
+ char additional_names[GN_PHONEBOOK_PERSON_MAX_LENGTH + 1];
+ char honorific_prefixes[GN_PHONEBOOK_PERSON_MAX_LENGTH + 1]; /* GN_PHONEBOOK_ENTRY_FormalName */
+ char honorific_suffixes[GN_PHONEBOOK_PERSON_MAX_LENGTH + 1];
+} gn_phonebook_person;
+
+#define GN_PHONEBOOK_ADDRESS_MAX_LENGTH 64
+
+typedef struct {
+ int has_address;
+ char post_office_box[GN_PHONEBOOK_ADDRESS_MAX_LENGTH + 1]; /* GN_PHONEBOOK_ENTRY_PostalAddress */
+ char extended_address[GN_PHONEBOOK_ADDRESS_MAX_LENGTH + 1]; /* GN_PHONEBOOK_ENTRY_ExtendedAddress */
+ char street[GN_PHONEBOOK_ADDRESS_MAX_LENGTH + 1]; /* GN_PHONEBOOK_ENTRY_Street */
+ char city[GN_PHONEBOOK_ADDRESS_MAX_LENGTH + 1]; /* GN_PHONEBOOK_ENTRY_City */
+ char state_province[GN_PHONEBOOK_ADDRESS_MAX_LENGTH + 1]; /* GN_PHONEBOOK_ENTRY_StateProvince */
+ char zipcode[GN_PHONEBOOK_ADDRESS_MAX_LENGTH + 1]; /* GN_PHONEBOOK_ENTRY_ZipCode */
+ char country[GN_PHONEBOOK_ADDRESS_MAX_LENGTH + 1]; /* GN_PHONEBOOK_ENTRY_Country */
+} gn_phonebook_address;
+
+typedef struct {
+ gn_phonebook_entry_type entry_type;
+ gn_phonebook_number_type number_type;
+ union {
+ char number[GN_PHONEBOOK_NAME_MAX_LENGTH + 1]; /* Number, Name, Address, eMail... */
+ /* GN_PHONEBOOK_ENTRY_Date
+ * GN_PHONEBOOK_ENTRY_Birthday
+ */
+ gn_timestamp date; /* or the last calls list */
+ /* GN_PHONEBOOK_ENTRY_Image
+ * GN_PHONEBOOK_ENTRY_RingtoneAdv
+ */
+ char fileid[6]; /* Bitmap or rigntone fileid */
+ } data;
+ int id;
+} gn_phonebook_subentry;
+
+/* Define datatype for phonebook entry, used for getting/writing phonebook
+ entries. */
+typedef struct {
+ int empty; /* Is this entry empty? */
+ char name[GN_PHONEBOOK_NAME_MAX_LENGTH + 1]; /* Plus 1 for
+ nullterminator. */
+ char number[GN_PHONEBOOK_NUMBER_MAX_LENGTH + 1]; /* Number */
+ gn_memory_type memory_type; /* Type of memory */
+ gn_phonebook_group_type caller_group; /* Caller group - gn_phonebook_group_type */
+ int location; /* Location */
+ gn_timestamp date; /* The record date and time
+ of the number. */
+ gn_phonebook_person person; /* Personal information */
+ gn_phonebook_address address; /* Address information */
+ gn_phonebook_subentry subentries[GN_PHONEBOOK_SUBENTRIES_MAX_NUMBER];
+ /* For phones with
+ * additional phonebook
+ * entries */
+ int subentries_count; /* Should be set to 0, if extended
+ phonebook is not used */
+} gn_phonebook_entry;
+
+/* This define speed dialing entries. */
+typedef struct {
+ int number; /* Which number is used to dialing? */
+ gn_memory_type memory_type; /* Memory type of the number. */
+ int location; /* Location of the number in MemoryType. */
+} gn_speed_dial;
+
+/* Define enum used to describe what sort of date/time support is
+ available. */
+typedef enum {
+ GN_DT_None, /* The mobile phone doesn't support time and date. */
+ GN_DT_TimeOnly, /* The mobile phone supports only time. */
+ GN_DT_DateOnly, /* The mobile phone supports only date. */
+ GN_DT_DateTime /* Wonderful phone - it supports date and time. */
+} gn_datetime_support;
+
+/* Define enums for RF units. GRF_CSQ asks for units in form used
+ in AT+CSQ command as defined by GSM 07.07 */
+typedef enum {
+ GN_RF_Arbitrary,
+ GN_RF_dBm,
+ GN_RF_mV,
+ GN_RF_uV,
+ GN_RF_CSQ,
+ GN_RF_Percentage
+} gn_rf_unit;
+
+/* Define enums for Battery units. */
+
+typedef enum {
+ GN_BU_Arbitrary,
+ GN_BU_Volts,
+ GN_BU_Minutes,
+ GN_BU_Percentage
+} gn_battery_unit;
+
+/* Define enums for Calendar Note types */
+typedef enum {
+ GN_CALNOTE_MEETING = 0x01, /* Meeting */
+ GN_CALNOTE_CALL = 0x02, /* Call */
+ GN_CALNOTE_BIRTHDAY = 0x04, /* Birthday */
+ GN_CALNOTE_REMINDER = 0x08, /* Reminder */
+ GN_CALNOTE_MEMO = 0x16, /* Memo */
+} gn_calnote_type;
+
+typedef enum {
+ GN_CALNOTE_NEVER = 0,
+ GN_CALNOTE_DAILY = 24,
+ GN_CALNOTE_WEEKLY = 168,
+ GN_CALNOTE_2WEEKLY = 336,
+ GN_CALNOTE_MONTHLY = 65534,
+ GN_CALNOTE_YEARLY = 65535
+} gn_calnote_recurrence;
+
+#define GN_CALNOTE_MAX_NUMBER 1024 /* FIXME how many are possible? */
+#define GN_CALNOTE_MAX_LENGTH 258
+#define GN_CALNOTE_NUMBER_MAX_LENGTH 49
+
+typedef struct {
+ int enabled; /* Is alarm set? */
+ int tone; /* Is alarm tone enabled? */
+ gn_timestamp timestamp;
+} gn_calnote_alarm;
+
+/* Calendar note type */
+typedef struct {
+ int location; /* The number of the note in the phone memory */
+ gn_calnote_type type; /* The type of the note */
+ gn_timestamp time; /* The time of the note */
+ gn_timestamp end_time; /* The end time of the note */
+ gn_calnote_alarm alarm; /* The alarm of the note */
+ char text[GN_CALNOTE_MAX_LENGTH]; /* The text of the note */
+ char phone_number[GN_CALNOTE_NUMBER_MAX_LENGTH]; /* For Call only: the phone number */
+ char mlocation[GN_CALNOTE_MAX_LENGTH]; /* For Meeting only: the location field */
+ gn_calnote_recurrence recurrence; /* Recurrence of the note */
+} gn_calnote;
+
+/* List of Calendar Notes in phone */
+typedef struct {
+ unsigned int number; /* The number of notes in phone */
+ unsigned int location[GN_CALNOTE_MAX_NUMBER]; /* Location of the nth note */
+ unsigned int last; /* Index of the last allocated note */
+} gn_calnote_list;
+
+/* ToDo things. It is only supported by the newer phones. */
+#define GN_TODO_MAX_LENGTH 256
+#define GN_TODO_MAX_NUMBER 512
+
+typedef enum {
+ GN_TODO_LOW = 3,
+ GN_TODO_MEDIUM = 2,
+ GN_TODO_HIGH = 1
+} gn_todo_priority;
+
+typedef struct {
+ int location; /* The number of the note in the phone memory */
+ char text[GN_TODO_MAX_LENGTH]; /* The text of the note */
+ gn_todo_priority priority;
+} gn_todo;
+
+/* List of ToDo Notes in phone */
+typedef struct {
+ int number; /* The number of notes in phone */
+ int location[GN_TODO_MAX_NUMBER]; /* Location of the nth note */
+} gn_todo_list;
+
+
+/* WAP */
+#define WAP_URL_MAX_LENGTH 258
+#define WAP_NAME_MAX_LENGTH 52
+#define WAP_SETTING_USERNAME_MAX_LENGTH 34
+#define WAP_SETTING_NAME_MAX_LENGTH 22
+#define WAP_SETTING_HOME_MAX_LENGTH 95
+#define WAP_SETTING_APN_MAX_LENGTH 102
+
+/* bookmarks */
+typedef struct {
+ int location;
+ char name[WAP_NAME_MAX_LENGTH];
+ char URL[WAP_URL_MAX_LENGTH];
+} gn_wap_bookmark;
+
+/* settings */
+typedef enum {
+ GN_WAP_SESSION_TEMPORARY = 0,
+ GN_WAP_SESSION_PERMANENT
+} gn_wap_session;
+
+typedef enum {
+ GN_WAP_AUTH_NORMAL = 0,
+ GN_WAP_AUTH_SECURE
+} gn_wap_authentication;
+
+typedef enum {
+ GN_WAP_BEARER_GSMDATA = 1,
+ GN_WAP_BEARER_GPRS = 3,
+ GN_WAP_BEARER_SMS = 7,
+ GN_WAP_BEARER_USSD = 9 /* FIXME real value? */
+} gn_wap_bearer;
+
+typedef enum {
+ GN_WAP_CALL_ANALOGUE,
+ GN_WAP_CALL_ISDN
+} gn_wap_call_type;
+
+typedef enum {
+ GN_WAP_CALL_AUTOMATIC,
+ GN_WAP_CALL_9600,
+ GN_WAP_CALL_14400
+} gn_wap_call_speed;
+
+typedef enum {
+ GN_WAP_LOGIN_MANUAL,
+ GN_WAP_LOGIN_AUTOLOG
+} gn_wap_login;
+
+typedef enum {
+ GN_WAP_GPRS_ALWAYS,
+ GN_WAP_GPRS_WHENNEEDED
+} gn_wap_gprs;
+
+typedef struct {
+ int read_before_write;
+ int location;
+ int successors[4];
+ char number [WAP_SETTING_NAME_MAX_LENGTH];
+ char gsm_data_ip [WAP_SETTING_NAME_MAX_LENGTH];
+ char gprs_ip [WAP_SETTING_NAME_MAX_LENGTH];
+ char name [WAP_SETTING_NAME_MAX_LENGTH];
+ char home [WAP_SETTING_HOME_MAX_LENGTH];
+ char gsm_data_username [WAP_SETTING_USERNAME_MAX_LENGTH];
+ char gsm_data_password [WAP_SETTING_NAME_MAX_LENGTH];
+ char gprs_username [WAP_SETTING_USERNAME_MAX_LENGTH];
+ char gprs_password [WAP_SETTING_NAME_MAX_LENGTH];
+ char access_point_name [WAP_SETTING_APN_MAX_LENGTH];
+ char sms_service_number [WAP_SETTING_NAME_MAX_LENGTH];
+ char sms_server_number [WAP_SETTING_NAME_MAX_LENGTH];
+ gn_wap_session session;
+ int security;
+ gn_wap_bearer bearer;
+ gn_wap_authentication gsm_data_authentication;
+ gn_wap_authentication gprs_authentication;
+ gn_wap_call_type call_type;
+ gn_wap_call_speed call_speed;
+ gn_wap_login gsm_data_login;
+ gn_wap_login gprs_login;
+ gn_wap_gprs gprs_connection;
+} gn_wap_setting;
+
+/* This structure is provided to allow common information about the particular
+ model to be looked up in a model independant way. Some of the values here
+ define minimum and maximum levels for values retrieved by the various Get
+ functions for example battery level. They are not defined as constants to
+ allow model specific code to set them during initialisation */
+typedef struct {
+ unsigned char *models; /* Models covered by this type, pipe '|' delimited. */
+
+ /* Minimum and maximum levels for RF signal strength. Units are as per the
+ setting of RFLevelUnits. The setting of RFLevelUnits indicates the
+ default or "native" units used. In the case of the 3110 and 6110 series
+ these are arbitrary, ranging from 0 to 4. */
+ float max_rf_level;
+ float min_rf_level;
+ gn_rf_unit rf_level_unit;
+
+ /* Minimum and maximum levels for battery level. Again, units are as per the
+ setting of GSM_BatteryLevelUnits. The value that BatteryLevelUnits is set
+ to indicates the "native" or default value that the phone supports. In the
+ case of the 3110 and 6110 series these are arbitrary, ranging from 0 to 4. */
+ float max_battery_level;
+ float min_battery_level;
+ gn_battery_unit battery_level_unit;
+
+ /* Information about date, time and alarm support. In case of alarm
+ information we provide value for the number of alarms supported. */
+ gn_datetime_support datetime_support;
+ gn_datetime_support alarm_support;
+ int maximum_alarms_number;
+
+ unsigned int startup_logo_height; /* Logo widths and heights - if supported */
+ unsigned int startup_logo_width;
+ unsigned int operator_logo_height;
+ unsigned int operator_logo_width;
+ unsigned int caller_logo_height;
+ unsigned int caller_logo_width;
+} gn_phone;
+
+typedef enum {
+ GN_PROFILE_MESSAGE_NoTone = 0x00,
+ GN_PROFILE_MESSAGE_Standard = 0x01,
+ GN_PROFILE_MESSAGE_Special = 0x02,
+ GN_PROFILE_MESSAGE_BeepOnce = 0x03,
+ GN_PROFILE_MESSAGE_Ascending = 0x04
+} gn_profile_message_type;
+
+typedef enum {
+ GN_PROFILE_WARNING_Off = 0xff,
+ GN_PROFILE_WARNING_On = 0x04
+} gn_profile_warning_type;
+
+typedef enum {
+ GN_PROFILE_VIBRATION_Off = 0x00,
+ GN_PROFILE_VIBRATION_On = 0x01
+} gn_profile_vibration_type;
+
+typedef enum {
+ GN_PROFILE_CALLALERT_Ringing = 0x01,
+ GN_PROFILE_CALLALERT_BeepOnce = 0x02,
+ GN_PROFILE_CALLALERT_Off = 0x04,
+ GN_PROFILE_CALLALERT_RingOnce = 0x05,
+ GN_PROFILE_CALLALERT_Ascending = 0x06,
+ GN_PROFILE_CALLALERT_CallerGroups = 0x07
+} gn_profile_callalert_type;
+
+typedef enum {
+ GN_PROFILE_KEYVOL_Off = 0xff,
+ GN_PROFILE_KEYVOL_Level1 = 0x00,
+ GN_PROFILE_KEYVOL_Level2 = 0x01,
+ GN_PROFILE_KEYVOL_Level3 = 0x02
+} gn_profile_keyvol_type;
+
+typedef enum {
+ GN_PROFILE_VOLUME_Level1 = 0x06,
+ GN_PROFILE_VOLUME_Level2 = 0x07,
+ GN_PROFILE_VOLUME_Level3 = 0x08,
+ GN_PROFILE_VOLUME_Level4 = 0x09,
+ GN_PROFILE_VOLUME_Level5 = 0x0a,
+} gn_profile_volume_type;
+
+/* Structure to hold profile entries. */
+typedef struct {
+ int number; /* The number of the profile. */
+ char name[40]; /* The name of the profile. */
+ int default_name; /* 0-6, when default name is used, -1, when not. */
+ int keypad_tone; /* Volume level for keypad tones. */
+ int lights; /* Lights on/off. */
+ int call_alert; /* Incoming call alert. */
+ int ringtone; /* Ringtone for incoming call alert. */
+ int volume; /* Volume of the ringing. */
+ int message_tone; /* The tone for message indication. */
+ int warning_tone; /* The tone for warning messages. */
+ int vibration; /* Vibration? */
+ int caller_groups; /* CallerGroups. */
+ int automatic_answer; /* Does the phone auto-answer incoming call? */
+} gn_profile;
+
+/* Limits for IMEI, Revision, Model and Manufacturer string storage. */
+#define GN_IMEI_MAX_LENGTH 20
+#define GN_REVISION_MAX_LENGTH 20
+#define GN_MODEL_MAX_LENGTH 32
+#define GN_MANUFACTURER_MAX_LENGTH 32
+
+#define GN_BCD_STRING_MAX_LENGTH 40
+
+/* This data-type is used to specify the type of the number. See the official
+ GSM specification 03.40, version 6.1.0, section 9.1.2.5, page 35-37. */
+typedef enum {
+ GN_GSM_NUMBER_Unknown = 0x81, /* Unknown number */
+ GN_GSM_NUMBER_International = 0x91, /* International number */
+ GN_GSM_NUMBER_National = 0xa1, /* National number */
+ GN_GSM_NUMBER_Network = 0xb1, /* Network specific number */
+ GN_GSM_NUMBER_Subscriber = 0xc1, /* Subscriber number */
+ GN_GSM_NUMBER_Alphanumeric = 0xd0, /* Alphanumeric number */
+ GN_GSM_NUMBER_Abbreviated = 0xe1 /* Abbreviated number */
+} gn_gsm_number_type;
+
+typedef struct {
+ gn_gsm_number_type type;
+ char number[GN_BCD_STRING_MAX_LENGTH];
+} gn_gsm_number;
+
+/* Data structures for the call divert */
+typedef enum {
+ GN_CDV_Busy = 0x01,
+ GN_CDV_NoAnswer,
+ GN_CDV_OutOfReach,
+ GN_CDV_NotAvailable,
+ GN_CDV_AllTypes
+} gn_call_divert_type;
+
+typedef enum {
+ GN_CDV_VoiceCalls = 0x01,
+ GN_CDV_FaxCalls,
+ GN_CDV_DataCalls,
+ GN_CDV_AllCalls
+} gn_call_divert_call_type;
+
+typedef enum {
+ GN_CDV_Disable = 0x00,
+ GN_CDV_Enable = 0x01,
+ GN_CDV_Query = 0x02,
+ GN_CDV_Register = 0x03,
+ GN_CDV_Erasure = 0x04
+} gn_call_divert_operation;
+
+typedef struct {
+ gn_call_divert_type type;
+ gn_call_divert_call_type ctype;
+ gn_call_divert_operation operation;
+ gn_gsm_number number;
+ unsigned int timeout;
+} gn_call_divert;
+
+typedef struct {
+ int full; /* indicates if we have full data read */
+ unsigned int length;
+ unsigned char *data;
+} gn_raw_data;
+
+/* This enum is used for display status. */
+typedef enum {
+ GN_DISP_Call_In_Progress, /* Call in progress. */
+ GN_DISP_Unknown, /* The meaning is unknown now :-( */
+ GN_DISP_Unread_SMS, /* There is Unread SMS. */
+ GN_DISP_Voice_Call, /* Voice call active. */
+ GN_DISP_Fax_Call, /* Fax call active. */
+ GN_DISP_Data_Call, /* Data call active. */
+ GN_DISP_Keyboard_Lock, /* Keyboard lock status. */
+ GN_DISP_SMS_Storage_Full /* Full SMS Memory. */
+} gn_display_status;
+
+#define GN_DRAW_SCREEN_MAX_WIDTH 27
+#define GN_DRAW_SCREEN_MAX_HEIGHT 6
+
+typedef enum {
+ GN_DISP_DRAW_Clear,
+ GN_DISP_DRAW_Text,
+ GN_DISP_DRAW_Status
+} gn_display_draw_command;
+
+typedef struct {
+ int x;
+ int y;
+ unsigned char text[GN_DRAW_SCREEN_MAX_WIDTH + 1];
+} gn_display_text;
+
+typedef struct {
+ gn_display_draw_command cmd;
+ union {
+ gn_display_text text;
+ gn_display_status status;
+ } data;
+} gn_display_draw_msg;
+
+typedef struct {
+ void (*output_fn)(gn_display_draw_msg *draw);
+ int state;
+ struct timeval last;
+} gn_display_output;
+
+typedef enum {
+ GN_KEY_NONE = 0x00,
+ GN_KEY_1 = 0x01,
+ GN_KEY_2,
+ GN_KEY_3,
+ GN_KEY_4,
+ GN_KEY_5,
+ GN_KEY_6,
+ GN_KEY_7,
+ GN_KEY_8,
+ GN_KEY_9,
+ GN_KEY_0,
+ GN_KEY_HASH,
+ GN_KEY_ASTERISK,
+ GN_KEY_POWER,
+ GN_KEY_GREEN,
+ GN_KEY_RED,
+ GN_KEY_INCREASEVOLUME,
+ GN_KEY_DECREASEVOLUME,
+ GN_KEY_UP = 0x17,
+ GN_KEY_DOWN,
+ GN_KEY_MENU,
+ GN_KEY_NAMES
+} gn_key_code;
+
+typedef struct {
+ int field;
+ char screen[50];
+} gn_netmonitor;
+
+typedef struct {
+ int userlock; /* TRUE = user lock, FALSE = factory lock */
+ int closed;
+ char data[12];
+ int counter;
+} gn_locks_info;
+
+typedef struct {
+ int frequency;
+ int volume;
+} gn_tone;
+
+#define GN_RINGTONE_MAX_NAME 20
+#define GN_RINGTONE_MAX_COUNT 256
+
+typedef struct {
+ int location;
+ char name[20];
+ int user_defined;
+ int readable;
+ int writable;
+} gn_ringtone_info;
+
+typedef struct {
+ int count;
+ int userdef_location;
+ int userdef_count;
+ gn_ringtone_info ringtone[GN_RINGTONE_MAX_COUNT];
+} gn_ringtone_list;
+
+typedef enum {
+ GN_LOG_T_NONE = 0,
+ GN_LOG_T_STDERR = 1
+} gn_log_target;
+
+
+typedef enum {
+ GN_FT_None = 0,
+ GN_FT_NOL,
+ GN_FT_NGG,
+ GN_FT_NSL,
+ GN_FT_NLM,
+ GN_FT_BMP,
+ GN_FT_OTA,
+ GN_FT_XPMF,
+ GN_FT_RTTTL,
+ GN_FT_OTT,
+ GN_FT_MIDI,
+ GN_FT_NOKRAW_TONE,
+ GN_FT_GIF,
+ GN_FT_JPG,
+ GN_FT_MID,
+ GN_FT_NRT,
+ GN_FT_PNG,
+} gn_filetypes;
+
+typedef struct {
+ gn_filetypes filetype; /* file type */
+ unsigned char *id; /* file id */
+ char name[512]; /* file name */
+ int year; /* datetime of creation/modification */
+ int month;
+ int day;
+ int hour;
+ int minute;
+ int second;
+ int file_length; /* size of the file */
+ int togo; /* amount of bytes to be sent yet */
+ int just_sent; /* ??? */
+ int folderId; /* folder id of the file */
+ unsigned char *file; /* file contents */
+} gn_file;
+
+#define GN_FILES_MAX_COUNT 1024
+
+typedef struct {
+ char path[512];
+ gn_file *files[GN_FILES_MAX_COUNT];
+ int file_count;
+} gn_file_list;
+
+#endif /* _gnokii_common_h */
Added: trunk/src/host/qemu-neo1973/gnokiigsm/compat.h
===================================================================
--- trunk/src/host/qemu-neo1973/gnokiigsm/compat.h 2007-05-16 22:38:21 UTC (rev 1986)
+++ trunk/src/host/qemu-neo1973/gnokiigsm/compat.h 2007-05-17 00:24:48 UTC (rev 1987)
@@ -0,0 +1,130 @@
+/*
+ * Copyright (c) 2007 OpenMoko, Inc.
+ * Modified for use in QEMU by Andrzej Zaborowski <andrew at openedhand.com>
+ */
+/*
+
+ $Id: compat.h,v 1.54 2007/05/08 19:41:35 pkot Exp $
+
+ G N O K I I
+
+ A Linux/Unix toolset and driver for the mobile phones.
+
+ This file is part of gnokii.
+
+ Gnokii 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.
+
+ Gnokii 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 gnokii; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+ Copyright (C) 1999-2000 Hugh Blemings, Pavel Janik
+ Copyright (C) 2002-2004 BORBELY Zoltan, Pawel Kot
+ Copyright (C) 2002 Feico de Boer, Markus Plail
+ Copyright (C) 2003 Marcus Godehardt, Ladis Michl
+
+ Header file for various platform compatibility.
+
+*/
+
+#ifndef _gnokii_compat_h
+#define _gnokii_compat_h
+
+#include <stdlib.h>
+
+#include <stdarg.h>
+#include <strings.h>
+#include <string.h>
+#include <stdint.h>
+#include <inttypes.h>
+#include <sys/types.h>
+#include <ctype.h>
+#include <sys/file.h>
+#include <sys/time.h>
+#include <sys/socket.h>
+#include <limits.h>
+#include <unistd.h>
+#include <termios.h>
+
+typedef uint8_t u8;
+typedef uint16_t u16;
+typedef uint32_t u32;
+
+#include "config-host.h"
+#define VERSION "QEMU " QEMU_VERSION
+
+struct gsmmodem_info_s {
+ void (*write)(void *opaque, const char *fmt, ...);
+ void *opaque;
+};
+
+#define GNOKII_API
+
+#undef timerisset
+#undef timerclear
+#undef timercmp
+#undef timeradd
+#undef timersub
+
+/* The following code is borrowed from glibc, please don't reindent it */
+
+/* Convenience macros for operations on timevals.
+ NOTE: `timercmp' does not work for >= or <=. */
+# define timerisset(tvp) ((tvp)->tv_sec || (tvp)->tv_usec)
+# define timerclear(tvp) ((tvp)->tv_sec = (tvp)->tv_usec = 0)
+# define timercmp(a, b, CMP) \
+ (((a)->tv_sec == (b)->tv_sec) ? \
+ ((a)->tv_usec CMP (b)->tv_usec) : \
+ ((a)->tv_sec CMP (b)->tv_sec))
+# define timeradd(a, b, result) \
+ do { \
+ (result)->tv_sec = (a)->tv_sec + (b)->tv_sec; \
+ (result)->tv_usec = (a)->tv_usec + (b)->tv_usec; \
+ if ((result)->tv_usec >= 1000000) \
+ { \
+ ++(result)->tv_sec; \
+ (result)->tv_usec -= 1000000; \
+ } \
+ } while (0)
+# define timersub(a, b, result) \
+ do { \
+ (result)->tv_sec = (a)->tv_sec - (b)->tv_sec; \
+ (result)->tv_usec = (a)->tv_usec - (b)->tv_usec; \
+ if ((result)->tv_usec < 0) { \
+ --(result)->tv_sec; \
+ (result)->tv_usec += 1000000; \
+ } \
+ } while (0)
+
+/*
+ * The following code was taken from W. Richard Stevens'
+ * "UNIX Network Programming", Volume 1, Second Edition.
+ *
+ * We need the newer CMSG_LEN() and CMSG_SPACE() macros, but few
+ * implementations support them today. These two macros really need
+ * an ALIGN() macro, but each implementation does this differently.
+ */
+
+#ifndef CMSG_LEN
+# define CMSG_LEN(size) (sizeof(struct cmsghdr) + (size))
+#endif
+
+#ifndef CMSG_SPACE
+# define CMSG_SPACE(size) (sizeof(struct cmsghdr) + (size))
+#endif
+
+/* Get rid of long defines. Use #if __unices__ */
+#define __unices__ defined(__svr4__) || defined(__FreeBSD__) || defined(__bsdi__) || defined(__MACH__) || defined(__OpenBSD__) || defined(__NetBSD__)
+
+#define _(x) (x)
+#define N_(x) (x)
+
+#endif
Added: trunk/src/host/qemu-neo1973/gnokiigsm/data.h
===================================================================
--- trunk/src/host/qemu-neo1973/gnokiigsm/data.h 2007-05-16 22:38:21 UTC (rev 1986)
+++ trunk/src/host/qemu-neo1973/gnokiigsm/data.h 2007-05-17 00:24:48 UTC (rev 1987)
@@ -0,0 +1,279 @@
+/*
+
+ $Id: data.h,v 1.80 2007/01/10 19:31:35 pkot Exp $
+
+ G N O K I I
+
+ A Linux/Unix toolset and driver for the mobile phones.
+
+ This file is part of gnokii.
+
+ Gnokii 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.
+
+ Gnokii 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 gnokii; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+ Copyright (C) 1999-2000 Hugh Blemings & Pavel Janík ml.
+ Copyright (C) 2002-2004 BORBELY Zoltan, Pawel Kot
+ Copyright (C) 2002 Ladis Michl, Markus Plail, Pavel Machek, Chris Kemp
+
+*/
+
+#ifndef _gnokii_data_h
+#define _gnokii_data_h
+
+#include <common.h>
+#include <sms.h>
+#include <call.h>
+#include <error.h>
+#include <rlp-common.h>
+
+/* For models table */
+typedef struct {
+ const char *model; /* e.g. 6310 */
+ const char *product_name; /* e.g. NPE-4 */
+ int flags;
+} gn_phone_model;
+
+/* For all 'AT+XXXX=?' commands */
+typedef char gn_choice[10];
+
+/* This is a generic holder for high level information - eg a gn_bmp */
+typedef struct {
+ gn_sms_folder *sms_folder;
+ gn_sms_folder_list *sms_folder_list;
+ gn_sms_raw *raw_sms; /* This is for phone driver, application using libgnokii should not touch this */
+ gn_sms *sms; /* This is for user communication, phone driver should not have to touch this one */
+ gn_phonebook_entry *phonebook_entry;
+ gn_speed_dial *speed_dial;
+ gn_memory_status *memory_status;
+ gn_sms_message_list *message_list[GN_SMS_MESSAGE_MAX_NUMBER][GN_SMS_FOLDER_MAX_NUMBER];
+ gn_sms_status *sms_status;
+ gn_sms_folder_stats *folder_stats[GN_SMS_FOLDER_MAX_NUMBER];
+ gn_sms_message_center *message_center;
+ char *imei;
+ char *revision;
+ char *model;
+ char *manufacturer;
+ gn_network_info *network_info;
+ gn_wap_bookmark *wap_bookmark;
+ gn_wap_setting *wap_setting;
+ gn_todo *todo;
+ gn_todo_list *todo_list;
+ gn_calnote *calnote;
+ gn_calnote_list *calnote_list;
+ gn_bmp *bitmap;
+ gn_ringtone *ringtone;
+ gn_profile *profile;
+ gn_battery_unit *battery_unit;
+ float *battery_level;
+ gn_rf_unit *rf_unit;
+ float *rf_level;
+ gn_display_output *display_output;
+ char *incoming_call_nr;
+ gn_power_source *power_source;
+ gn_timestamp *datetime;
+ gn_calnote_alarm *alarm;
+ gn_raw_data *raw_data;
+ gn_call_divert *call_divert;
+ gn_error (*on_sms)(gn_sms *message, struct gn_statemachine *state);
+ int *display_status;
+ void (*on_cell_broadcast)(gn_cb_message *message);
+ gn_netmonitor *netmonitor;
+ gn_call_info *call_info;
+ void (*call_notification)(gn_call_status call_status, gn_call_info *call_info,
+ struct gn_statemachine *state);
+ gn_rlp_f96_frame *rlp_frame;
+ int rlp_out_dtx;
+ void (*rlp_rx_callback)(gn_rlp_f96_frame *frame);
+ gn_security_code *security_code;
+ const char *dtmf_string;
+ unsigned char reset_type;
+ gn_key_code key_code;
+ unsigned char character;
+ gn_phone_model *phone;
+ gn_locks_info *locks_info;
+ gn_tone *tone;
+ gn_ringtone_list *ringtone_list;
+ gn_call_active *call_active;
+ gn_file_list *file_list;
+ gn_file *file;
+
+ gn_choice cscs;
+ gn_choice cmux;
+ gn_choice ws46;
+ gn_choice csta;
+ gn_choice cbst;
+ gn_choice crlp;
+ gn_choice cr;
+ gn_choice csns;
+ gn_choice creg;
+ gn_choice cpas;
+ gn_choice cops;
+ gn_choice cfun;
+ gn_choice cbc;
+ gn_choice band;
+ gn_choice cssn;
+} gn_data;
+
+/*
+ * A structure to hold information about the particular link
+ * The link comes 'under' the phone
+ */
+typedef struct {
+ /* A regularly called loop function. Timeout can be used to make the
+ * function block or not */
+ gn_error (*loop)(struct timeval *timeout, struct gn_statemachine *state);
+ /* A pointer to the function used to send out a message. This is used
+ * by the phone specific code to send a message over the link */
+ gn_error (*send_message)(unsigned int messagesize, unsigned char messagetype, unsigned char *message,
+ struct gn_statemachine *state);
+ void *link_instance;
+} gn_link;
+
+typedef struct {
+ char model[GN_MODEL_MAX_LENGTH]; /* Phone model */
+ char irda_string[GN_MODEL_MAX_LENGTH]; /* If IrDA connection used, string shown in the discovery log */
+ char port_device[GN_DEVICE_NAME_MAX_LENGTH]; /* Port device to use (e.g. /dev/ttyS0) */
+ gn_connection_type connection_type; /* Connection type (e.g. serial, ir) */
+ int init_length; /* Number of chars sent to sync the serial port */
+ int serial_baudrate; /* Baud rate to use */
+ int serial_write_usleep; /* Inter character delay or <0 to disable */
+ int hardware_handshake; /* Select between hardware and software handshake */
+ int require_dcd; /* DCD signal check */
+ int smsc_timeout; /* How many seconds should we wait for the SMSC response, defaults to 10 seconds */
+ char connect_script[256]; /* Script to run when device connection established */
+ char disconnect_script[256]; /* Script to run when device connection closed */
+ uint8_t rfcomm_cn; /* RFCOMM channel number to connect */
+ unsigned int sm_retry; /* Indicates whether statemachine should do retries. Defaults to off. */
+ /* Use with caution -- may break newer DCT4 phones */
+
+ /* do not change the following values from userspace */
+ char m_model[GN_MODEL_MAX_LENGTH];
+ char m_manufacturer[GN_MANUFACTURER_MAX_LENGTH];
+ char m_revision[GN_REVISION_MAX_LENGTH];
+ char m_imei[GN_IMEI_MAX_LENGTH];
+
+} gn_config;
+
+typedef struct {
+ int fd;
+ gn_connection_type type;
+ void *device_instance;
+} gn_device;
+
+typedef enum {
+ GN_OP_Init,
+ GN_OP_Terminate,
+ GN_OP_GetModel,
+ GN_OP_GetRevision,
+ GN_OP_GetImei,
+ GN_OP_GetManufacturer,
+ GN_OP_Identify,
+ GN_OP_GetBitmap,
+ GN_OP_SetBitmap,
+ GN_OP_GetBatteryLevel,
+ GN_OP_GetRFLevel,
+ GN_OP_DisplayOutput,
+ GN_OP_GetMemoryStatus,
+ GN_OP_ReadPhonebook,
+ GN_OP_WritePhonebook,
+ GN_OP_DeletePhonebook,
+ GN_OP_GetPowersource,
+ GN_OP_GetAlarm,
+ GN_OP_GetSMSStatus,
+ GN_OP_GetIncomingCallNr,
+ GN_OP_GetNetworkInfo,
+ GN_OP_GetSecurityCode,
+ GN_OP_CreateSMSFolder,
+ GN_OP_DeleteSMSFolder,
+ GN_OP_GetSMS,
+ GN_OP_GetSMSnoValidate,
+ GN_OP_GetSMSFolders,
+ GN_OP_GetSMSFolderStatus,
+ GN_OP_GetIncomingSMS,
+ GN_OP_GetUnreadMessages,
+ GN_OP_GetNextSMS,
+ GN_OP_DeleteSMSnoValidate,
+ GN_OP_DeleteSMS,
+ GN_OP_SendSMS,
+ GN_OP_GetSpeedDial,
+ GN_OP_GetSMSCenter,
+ GN_OP_SetSMSCenter,
+ GN_OP_GetDateTime,
+ GN_OP_GetToDo,
+ GN_OP_GetCalendarNote,
+ GN_OP_CallDivert,
+ GN_OP_OnSMS,
+ GN_OP_PollSMS,
+ GN_OP_SetAlarm,
+ GN_OP_SetDateTime,
+ GN_OP_GetProfile,
+ GN_OP_SetProfile,
+ GN_OP_WriteToDo,
+ GN_OP_DeleteAllToDos,
+ GN_OP_WriteCalendarNote,
+ GN_OP_DeleteCalendarNote,
+ GN_OP_SetSpeedDial,
+ GN_OP_GetDisplayStatus,
+ GN_OP_PollDisplay,
+ GN_OP_SaveSMS,
+ GN_OP_SetCellBroadcast,
+ GN_OP_NetMonitor,
+ GN_OP_MakeCall,
+ GN_OP_AnswerCall,
+ GN_OP_CancelCall,
+ GN_OP_SetCallNotification,
+ GN_OP_SendRLPFrame,
+ GN_OP_SetRLPRXCallback,
+ GN_OP_EnterSecurityCode,
+ GN_OP_GetSecurityCodeStatus,
+ GN_OP_ChangeSecurityCode,
+ GN_OP_SendDTMF,
+ GN_OP_Reset,
+ GN_OP_GetRingtone,
+ GN_OP_SetRingtone,
+ GN_OP_GetRawRingtone,
+ GN_OP_SetRawRingtone,
+ GN_OP_PressPhoneKey,
+ GN_OP_ReleasePhoneKey,
+ GN_OP_EnterChar,
+ GN_OP_Subscribe,
+ GN_OP_GetWAPBookmark,
+ GN_OP_WriteWAPBookmark,
+ GN_OP_DeleteWAPBookmark,
+ GN_OP_GetWAPSetting,
+ GN_OP_ActivateWAPSetting,
+ GN_OP_WriteWAPSetting,
+ GN_OP_GetLocksInfo,
+ GN_OP_GetActiveProfile,
+ GN_OP_SetActiveProfile,
+ GN_OP_PlayTone,
+ GN_OP_GetRingtoneList,
+ GN_OP_DeleteRingtone,
+ GN_OP_GetActiveCalls,
+ GN_OP_GetFileList,
+ GN_OP_GetFileId,
+ GN_OP_GetFile,
+ GN_OP_PutFile,
+ GN_OP_DeleteFile,
+ GN_OP_GetFileDetailsById,
+ GN_OP_GetFileById,
+ GN_OP_DeleteFileById,
+ GN_OP_Max, /* don't append anything after this entry */
+} gn_operation;
+
+/* Undefined functions in fbus/mbus files */
+extern gn_error gn_unimplemented(void);
+#define GN_UNIMPLEMENTED (void *) gn_unimplemented
+
+#endif /* _gnokii_data_h */
Added: trunk/src/host/qemu-neo1973/gnokiigsm/datapump.c
===================================================================
--- trunk/src/host/qemu-neo1973/gnokiigsm/datapump.c 2007-05-16 22:38:21 UTC (rev 1986)
+++ trunk/src/host/qemu-neo1973/gnokiigsm/datapump.c 2007-05-17 00:24:48 UTC (rev 1987)
@@ -0,0 +1,191 @@
+/*
+
+ $Id: datapump.c,v 1.25 2006/10/03 21:26:37 pkot Exp $
+
+ G N O K I I
+
+ A Linux/Unix toolset and driver for the mobile phones.
+
+ This file is part of gnokii.
+
+ Gnokii 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.
+
+ Gnokii 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 gnokii; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+ Copyright (C) 1999-2000 Hugh Blemings & Pavel Janík ml.
+ Copyright (C) 2001-2004 Pawel Kot
+ Copyright (C) 2002-2004 BORBELY Zoltan
+
+ This file provides routines to handle processing of data when connected in
+ fax or data mode. Converts data from/to GSM phone to virtual modem
+ interface.
+
+*/
+
+#define __data_datapump_c
+
+
+#include <stdio.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <signal.h>
+#include <termios.h>
+#include <grp.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+
+
+#include "misc.h"
+#include "gnokii.h"
+#include "compat.h"
+#include "device.h"
+#include "at-emulator.h"
+#include "datapump.h"
+
+/* Prototypes */
+static int DP_CallBack(rlp_user_inds ind, u8 *buffer, int length);
+static int DP_SendRLPFrame(gn_rlp_f96_frame *frame, bool out_dtx);
+
+/* Global variables */
+extern bool CommandMode;
+
+/* Local variables */
+static int PtyRDFD; /* File descriptor for reading and writing to/from */
+static int PtyWRFD; /* pty interface - only different in debug mode. */
+u8 pluscount;
+bool connected;
+
+bool dp_Initialise(int read_fd, int write_fd)
+{
+ PtyRDFD = read_fd;
+ PtyWRFD = write_fd;
+ rlp_initialise(DP_SendRLPFrame, DP_CallBack);
+ rlp_user_request_set(Attach_Req, true);
+ pluscount = 0;
+ connected = false;
+ data.rlp_rx_callback = rlp_f96_frame_display;
+ gn_sm_functions(GN_OP_SetRLPRXCallback, &data, sm);
+
+ return true;
+}
+
+
+static int DP_CallBack(rlp_user_inds ind, u8 *buffer, int length)
+{
+ int i, temp;
+
+ switch(ind) {
+ case Data:
+ if (CommandMode == false) write(PtyWRFD, buffer, length);
+ break;
+ case Conn_Ind:
+ if (CommandMode == false) gn_atem_modem_result(MR_CARRIER);
+ rlp_user_request_set(Conn_Req, true);
+ break;
+ case StatusChange:
+ if (buffer[0] == 0) {
+ connected = true;
+ if (CommandMode == false) gn_atem_modem_result(MR_CONNECT);
+ }
+ break;
+ case Disc_Ind:
+ if (CommandMode == false) gn_atem_modem_result(MR_NOCARRIER);
+ connected = false;
+ /* Set the call passup back to the at emulator */
+ data.call_notification = gn_atem_call_passup;
+ gn_sm_functions(GN_OP_SetCallNotification, &data, sm);
+ CommandMode = true;
+ break;
+ case Reset_Ind:
+ rlp_user_request_set(Reset_Resp, true);
+ break;
+ case GetData:
+ if (queue.n > 0) {
+ temp = queue.n < sizeof(buffer) ? queue.n : sizeof(buffer);
+ for (i = 0; i < temp; i++) {
+ buffer[i] = queue.buf[queue.head++];
+ queue.head %= sizeof(queue.buf);
+ queue.n--;
+ }
+
+ /* This will only check +++ and the beginning of a read */
+ /* But there should be a pause before it anyway */
+
+ if (buffer[0] == '+') {
+ pluscount++;
+ if (temp > 1) {
+ if (buffer[1] == '+') pluscount++;
+ else pluscount = 0;
+ if (temp > 2) {
+ if (buffer[2] == '+') pluscount++;
+ else pluscount = 0;
+ if (temp > 3) pluscount = 0;
+ }
+ }
+ } else pluscount = 0;
+
+ if (pluscount == 3) {
+ CommandMode = true;
+ /* Set the call passup back to the at emulator */
+ data.call_notification = gn_atem_call_passup;
+ gn_sm_functions(GN_OP_SetCallNotification, &data, sm);
+ gn_atem_string_out("\r\n");
+ gn_atem_modem_result(MR_OK);
+ break;
+ }
+
+ return temp;
+ }
+ break;
+ default:
+ break;
+ }
+ return 0;
+}
+
+void dp_CallPassup(gn_call_status CallStatus, gn_call_info *CallInfo, struct gn_statemachine *state)
+{
+ dprintf("dp_CallPassup called with %d\n", CallStatus);
+
+ switch (CallStatus) {
+ case GN_CALL_Established:
+ if (CommandMode == false) gn_atem_modem_result(MR_CARRIER);
+ rlp_user_request_set(Conn_Req, true);
+ connected = true;
+ break;
+ case GN_CALL_LocalHangup:
+ case GN_CALL_RemoteHangup:
+ CommandMode = true;
+ /* Set the call passup back to the at emulator */
+ data.call_notification = gn_atem_call_passup;
+ gn_sm_functions(GN_OP_SetCallNotification, &data, sm);
+ gn_atem_modem_result(MR_NOCARRIER);
+ rlp_user_request_set(Disc_Req, true);
+ connected = false;
+ /* send the hangup event to the at emulator */
+ gn_atem_call_passup(CallStatus, CallInfo, state);
+ break;
+ default:
+ break;
+ }
+}
+
+static int DP_SendRLPFrame(gn_rlp_f96_frame *frame, bool out_dtx)
+{
+ data.rlp_frame = frame;
+ data.rlp_out_dtx = out_dtx;
+
+ return gn_sm_functions(GN_OP_SendRLPFrame, &data, sm);
+}
Added: trunk/src/host/qemu-neo1973/gnokiigsm/datapump.h
===================================================================
--- trunk/src/host/qemu-neo1973/gnokiigsm/datapump.h 2007-05-16 22:38:21 UTC (rev 1986)
+++ trunk/src/host/qemu-neo1973/gnokiigsm/datapump.h 2007-05-17 00:24:48 UTC (rev 1987)
@@ -0,0 +1,41 @@
+/*
+
+ $Id: datapump.h,v 1.12 2003/03/06 21:31:08 pkot Exp $
+
+ G N O K I I
+
+ A Linux/Unix toolset and driver for Nokia mobile phones.
+
+ This file is part of gnokii.
+
+ Gnokii 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.
+
+ Gnokii 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 gnokii; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+ Copyright (C) 1999, 2000 Hugh Blemings & Pavel Janík ml.
+
+ Header file for data pump code.
+
+*/
+
+#ifndef _gnokii_data_datapump_h
+#define _gnokii_data_datapump_h
+
+#include "compat.h"
+#include "gnokii.h"
+
+/* Prototypes */
+bool dp_Initialise(int read_fd, int write_fd);
+void dp_CallPassup(gn_call_status call_status, gn_call_info *call_info, struct gn_statemachine *state);
+
+#endif /* _gnokii_data_datapump_h */
Added: trunk/src/host/qemu-neo1973/gnokiigsm/device.h
===================================================================
--- trunk/src/host/qemu-neo1973/gnokiigsm/device.h 2007-05-16 22:38:21 UTC (rev 1986)
+++ trunk/src/host/qemu-neo1973/gnokiigsm/device.h 2007-05-17 00:24:48 UTC (rev 1987)
@@ -0,0 +1,57 @@
+/*
+
+ $Id: device.h,v 1.27 2006/10/03 21:26:38 pkot Exp $
+
+ G N O K I I
+
+ A Linux/Unix toolset and driver for the mobile phones.
+
+ This file is part of gnokii.
+
+ Gnokii 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.
+
+ Gnokii 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 gnokii; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+ Copyright (C) 1999-2000 Hugh Blemings & Pavel Janík ml.
+ Copyright (C) 2002 BORBELY Zoltan, Ladis Michl, Pawel Kot, Chris Kemp
+ Header file device access code.
+
+*/
+
+#ifndef _gnokii_device_h
+#define _gnokii_device_h
+
+#include "compat.h"
+#include "misc.h"
+#include "gnokii.h"
+
+GNOKII_API int device_getfd(struct gn_statemachine *state);
+
+int device_open(const char *file, int with_odd_parity, int with_async,
+ int with_hw_handshake, gn_connection_type device_type,
+ struct gn_statemachine *state);
+void device_close(struct gn_statemachine *state);
+void device_reset(struct gn_statemachine *state);
+
+void device_setdtrrts(int dtr, int rts, struct gn_statemachine *state);
+void device_changespeed(int speed, struct gn_statemachine *state);
+
+size_t device_read(__ptr_t buf, size_t nbytes, struct gn_statemachine *state);
+size_t device_write(const __ptr_t buf, size_t n, struct gn_statemachine *state);
+
+int device_select(struct timeval *timeout, struct gn_statemachine *state);
+
+gn_error device_nreceived(int *n, struct gn_statemachine *state);
+gn_error device_flush(struct gn_statemachine *state);
+
+#endif /* _gnokii_device_h */
Added: trunk/src/host/qemu-neo1973/gnokiigsm/encoding.h
===================================================================
--- trunk/src/host/qemu-neo1973/gnokiigsm/encoding.h 2007-05-16 22:38:21 UTC (rev 1986)
+++ trunk/src/host/qemu-neo1973/gnokiigsm/encoding.h 2007-05-17 00:24:48 UTC (rev 1987)
@@ -0,0 +1,58 @@
+/*
+
+ $Id: encoding.h,v 1.20 2006/06/11 16:39:11 deller Exp $
+
+ G N O K I I
+
+ A Linux/Unix toolset and driver for the mobile phones.
+
+ This file is part of gnokii.
+
+ Gnokii 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.
+
+ Gnokii 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 gnokii; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+ Copyright (C) 1999-2000 Hugh Blemings, Pavel Janik
+ Copyright (C) 2001-2004 Pawel Kot
+
+ Include file for encoding functions.
+
+*/
+
+#ifndef _gnokii_encoding_h
+#define _gnokii_encoding_h
+
+GNOKII_API int gn_char_def_alphabet(unsigned char *string);
+
+/*
+ *
+ * Set encoding to use for exchanging data between Gnokii and the application
+ *
+ * Normally, when communicating with the application, Gnokii uses the
+ * encoding set with the setlocale() call. For the (standard) call
+ * setlocale(LC_ALL, ""), this is the encoding specified by the user in the
+ * LANG variable. This function can be used to override this behaviour. E.g.,
+ * to make Gnokii always interpret and return string values using the UTF-8
+ * charset, call gn_set_encoding("UTF-8").
+ *
+ * This has nothing to do with the encoding used to communicate with the
+ * phone itself, which is a totally different issue.
+ *
+ * Parameters:
+ * encoding The name of the encoding (length must not exceed 63 chars)
+ *
+ */
+GNOKII_API void gn_char_set_encoding(const char* encoding);
+GNOKII_API const char *gn_char_get_encoding();
+
+#endif /* _gnokii_encoding_h */
Added: trunk/src/host/qemu-neo1973/gnokiigsm/error.h
===================================================================
--- trunk/src/host/qemu-neo1973/gnokiigsm/error.h 2007-05-16 22:38:21 UTC (rev 1986)
+++ trunk/src/host/qemu-neo1973/gnokiigsm/error.h 2007-05-17 00:24:48 UTC (rev 1987)
@@ -0,0 +1,94 @@
+/*
+
+ $Id: error.h,v 1.21 2006/08/09 19:36:58 pkot Exp $
+
+ G N O K I I
+
+ A Linux/Unix toolset and driver for the mobile phones.
+
+ This file is part of gnokii.
+
+ Gnokii 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.
+
+ Gnokii 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 gnokii; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+ Copyright (C) 1999-2000 Hugh Blemings, Pavel Janik
+ Copyright (C) 2001-2004 BORBELY Zoltan, Pawel Kot
+
+ Error codes.
+
+*/
+
+#ifndef _gnokii_error_h
+#define _gnokii_error_h
+
+/*
+ * Define standard GSM error/return code values. These codes are also used for
+ * some internal functions such as SIM read/write in the model specific code.
+ */
+typedef enum {
+ /* General codes */
+ GN_ERR_NONE = 0, /* No error. */
+ GN_ERR_FAILED, /* Command failed. */
+ GN_ERR_UNKNOWNMODEL, /* Model specified isn't known/supported. */
+ GN_ERR_INVALIDSECURITYCODE, /* Invalid Security code. */
+ GN_ERR_INTERNALERROR, /* Problem occured internal to model specific code. */
+ GN_ERR_NOTIMPLEMENTED, /* Command called isn't implemented in model. */
+ GN_ERR_NOTSUPPORTED, /* Function not supported by the phone */
+ GN_ERR_USERCANCELED, /* User aborted the action. */
+ GN_ERR_UNKNOWN, /* Unknown error - well better than nothing!! */
+ GN_ERR_MEMORYFULL, /* The specified memory is full. */
+
+ /* Statemachine */
+ GN_ERR_NOLINK, /* Couldn't establish link with phone. */
+ GN_ERR_TIMEOUT, /* Command timed out. */
+ GN_ERR_TRYAGAIN, /* Try again. */
+ GN_ERR_WAITING, /* Waiting for the next part of the message. */
+ GN_ERR_NOTREADY, /* Device not ready. */
+ GN_ERR_BUSY, /* Command is still being executed. */
+
+ /* Locations */
+ GN_ERR_INVALIDLOCATION, /* The given memory location has not valid location. */
+ GN_ERR_INVALIDMEMORYTYPE, /* Invalid type of memory. */
+ GN_ERR_EMPTYLOCATION, /* The given location is empty. */
+
+ /* Format */
+ GN_ERR_ENTRYTOOLONG, /* The given entry is too long */
+ GN_ERR_WRONGDATAFORMAT, /* Data format is not valid */
+ GN_ERR_INVALIDSIZE, /* Wrong size of the object */
+
+ /* The following are here in anticipation of data call requirements. */
+ GN_ERR_LINEBUSY, /* Outgoing call requested reported line busy */
+ GN_ERR_NOCARRIER, /* No Carrier error during data call setup ? */
+
+ /* The following value signals the current frame is unhandled */
+ GN_ERR_UNHANDLEDFRAME, /* The current frame isn't handled by the incoming function */
+ GN_ERR_UNSOLICITED, /* Unsolicited message received. */
+
+ /* Other */
+ GN_ERR_NONEWCBRECEIVED, /* Attempt to read CB when no new CB received */
+ GN_ERR_SIMPROBLEM, /* SIM card missing or damaged */
+ GN_ERR_CODEREQUIRED, /* PIN or PUK code required */
+ GN_ERR_NOTAVAILABLE, /* The requested information is not available */
+
+ /* Config */
+ GN_ERR_NOCONFIG, /* Config file cannot be found */
+ GN_ERR_NOPHONE, /* Either global or given phone section cannot be found */
+ GN_ERR_NOLOG, /* Incorrect logging section configuration */
+ GN_ERR_NOMODEL, /* No phone model specified */
+ GN_ERR_NOPORT /* No port specified */
+} gn_error;
+
+GNOKII_API char *gn_error_print(gn_error e);
+
+#endif /* _gnokii_error_h */
Added: trunk/src/host/qemu-neo1973/gnokiigsm/gnokii-internal.h
===================================================================
--- trunk/src/host/qemu-neo1973/gnokiigsm/gnokii-internal.h 2007-05-16 22:38:21 UTC (rev 1986)
+++ trunk/src/host/qemu-neo1973/gnokiigsm/gnokii-internal.h 2007-05-17 00:24:48 UTC (rev 1987)
@@ -0,0 +1,175 @@
+/*
+
+ $Id: gnokii-internal.h,v 1.35 2007/04/14 19:36:35 pkot Exp $
+
+ G N O K I I
+
+ A Linux/Unix toolset and driver for the mobile phones.
+
+ This file is part of gnokii.
+
+ Gnokii 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.
+
+ Gnokii 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 gnokii; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+ Copyright (C) 1999-2000 Hugh Blemings, Pavel Janik
+ Copyright (C) 2000-2004 Pawel Kot, BORBELY Zoltan
+ Copyright (C) 2000 Marcin Wiacek, Chris Kemp
+ Copyright (C) 2002 Ladis Michl
+ Copyright (C) 2003 Osma Suominen, Martin Goldhahn
+
+ Internal API for libgnokii
+
+*/
+
+#ifndef _gnokii_internal_h
+#define _gnokii_internal_h
+
+#include "compat.h"
+#include "misc.h"
+
+#if !defined(GNOKII_DEPRECATED)
+# define GNOKII_DEPRECATED /* do not warn about deprecated functions here */
+#endif
+
+#include "gnokii.h"
+
+/* utils */
+gn_connection_type gn_get_connectiontype(const char *connection_type_string);
+
+/* SMS */
+gn_error sms_parse(int offset, gn_data *data);
+gn_error sms_request(gn_data *data, struct gn_statemachine *state);
+gn_error sms_prepare(gn_sms *sms, gn_sms_raw *rawsms);
+gn_timestamp *sms_timestamp_unpack(unsigned char *number, gn_timestamp *dt);
+unsigned char *sms_timestamp_pack(gn_timestamp *dt, unsigned char *number);
+
+/* Statemachine */
+gn_error sm_initialise(struct gn_statemachine *state);
+gn_error sm_message_send(u16 messagesize, u8 messagetype, void *message, struct gn_statemachine *state);
+gn_error sm_wait_for(unsigned char messagetype, gn_data *data, struct gn_statemachine *state);
+void sm_incoming_function(u8 messagetype, void *message, u16 messagesize, struct gn_statemachine *state);
+void sm_incoming_acknowledge(struct gn_statemachine *state);
+void sm_reset(struct gn_statemachine *state);
+gn_error sm_error_get(unsigned char messagetype, struct gn_statemachine *state);
+gn_error sm_block_timeout(int waitfor, int t, gn_data *data, struct gn_statemachine *state);
+gn_error sm_block(int waitfor, gn_data *data, struct gn_statemachine *state);
+gn_error sm_block_no_retry_timeout(int waitfor, int t, gn_data *data, struct gn_statemachine *state);
+gn_error sm_block_no_retry(int waitfor, gn_data *data, struct gn_statemachine *state);
+gn_error sm_block_ack(struct gn_statemachine *state);
+void sm_message_dump(gn_log_func_t lfunc, int messagetype, unsigned char *message, int length);
+void sm_unhandled_frame_dump(int messagetype, unsigned char *message, int length, struct gn_statemachine *state);
+
+extern void hex2bin(unsigned char *dest, const unsigned char *src, unsigned int len);
+extern void bin2hex(unsigned char *dest, const unsigned char *src, unsigned int len);
+
+int char_7bit_unpack(unsigned int offset, unsigned int in_length, unsigned int out_length,
+ unsigned char *input, unsigned char *output);
+int char_7bit_pack(unsigned int offset, unsigned char *input, unsigned char *output,
+ unsigned int *in_len);
+
+int char_mblen(const char *src);
+
+unsigned int char_unicode_decode(unsigned char* dest, const unsigned char* src, int len);
+unsigned int char_unicode_encode(unsigned char* dest, const unsigned char* src, int len);
+
+void char_ascii_decode(unsigned char* dest, const unsigned char* src, int len);
+size_t char_ascii_encode(char *dest, size_t dest_len, const char *src, size_t len);
+
+void char_hex_decode(unsigned char* dest, const unsigned char* src, int len);
+size_t char_hex_encode(char *dest, size_t dest_len, const char *src, size_t len);
+
+void char_ucs2_decode(unsigned char* dest, const unsigned char* src, int len);
+size_t char_ucs2_encode(char *dest, size_t dest_len, const char *src, size_t len);
+
+unsigned char char_def_alphabet_encode(unsigned char value);
+unsigned char char_def_alphabet_decode(unsigned char value);
+
+extern char *char_bcd_number_get(u8 *number);
+extern int char_semi_octet_pack(char *number, unsigned char *output, gn_gsm_number_type type);
+
+/* Ringtones */
+int vcal_time_get(gn_timestamp *dt, char *time);
+int calnote_fill(gn_calnote *note, char *type, char *text, char *desc,
+ char *time, char *alarm);
+int todo_fill(gn_todo *note, char *text, char *todo_priority);
+
+/* Ringtone Files */
+gn_error file_rtttl_save(FILE *file, gn_ringtone *ringtone);
+gn_error file_ott_save(FILE *file, gn_ringtone *ringtone);
+gn_error file_midi_save(FILE *file, gn_ringtone *ringtone);
+gn_error file_nokraw_save(FILE *file, gn_ringtone *ringtone, int dct4);
+
+gn_error file_rtttl_load(FILE *file, gn_ringtone *ringtone);
+gn_error file_ott_load(FILE *file, gn_ringtone *ringtone);
+gn_error file_midi_load(FILE *file, gn_ringtone *ringtone);
+gn_error file_nokraw_load(FILE *file, gn_ringtone *ringtone);
+
+/* Bitmap Files */
+
+void file_nol_save(FILE *file, gn_bmp *bitmap, gn_phone *info);
+void file_ngg_save(FILE *file, gn_bmp *bitmap, gn_phone *info);
+void file_nsl_save(FILE *file, gn_bmp *bitmap, gn_phone *info);
+void file_nlm_save(FILE *file, gn_bmp *bitmap);
+void file_ota_save(FILE *file, gn_bmp *bitmap);
+void file_bmp_save(FILE *file, gn_bmp *bitmap);
+
+#ifdef XPM
+void file_xpm_save(char *filename, gn_bmp *bitmap);
+#endif
+
+gn_error file_ngg_load(FILE *file, gn_bmp *bitmap, gn_phone *info);
+gn_error file_nol_load(FILE *file, gn_bmp *bitmap, gn_phone *info);
+gn_error file_nsl_load(FILE *file, gn_bmp *bitmap);
+gn_error file_nlm_load(FILE *file, gn_bmp *bitmap);
+gn_error file_ota_load(FILE *file, gn_bmp *bitmap, gn_phone *info);
+gn_error file_bmp_load(FILE *file, gn_bmp *bitmap);
+
+#ifdef XPM
+gn_error file_xpm_load(char *filename, gn_bmp *bitmap);
+#endif
+
+int ringtone_sms_encode(unsigned char *message, gn_ringtone *ringtone);
+int imelody_sms_encode(unsigned char *imelody, unsigned char *message);
+gn_error phonebook_decode(unsigned char *blockstart, int length,
+ gn_data *data, int blocks, int memtype, int speeddial_pos);
+gn_error calnote_decode(unsigned char *message, int length, gn_data *data);
+gn_error calnote_get_alarm(int alarmdiff, gn_timestamp *time, gn_timestamp *alarm);
+
+int sms_nokia_smart_message_part_pack(unsigned char *msg, unsigned int size,
+ unsigned int type, bool first);
+int sms_nokia_text_encode(unsigned char *text, unsigned char *message, bool first);
+int sms_nokia_bitmap_encode(gn_bmp *bitmap, unsigned char *message, bool first);
+
+struct gn_cfg_header *cfg_file_read(const char *filename);
+typedef void (*cfg_foreach_func)(const char *section, const char *key, const char *value);
+void cfg_foreach(const char *section, cfg_foreach_func func);
+char *cfg_set(struct gn_cfg_header *cfg, const char *section, const char *key, const char *value);
+int cfg_file_write(struct gn_cfg_header *cfg, const char *filename);
+
+gn_error isdn_cause2gn_error(char **src, char **msg, unsigned char loc, unsigned char cause);
+
+int utf8_decode(char *dest, size_t destlen, const char *src, size_t inlen);
+int utf8_encode(char *dest, int destlen, const char *src, int inlen);
+
+int string_base64(const char *instring);
+int base64_decode(char *dest, int destlen, const char *src, int inlen);
+int base64_encode(char *dest, int destlen, const char *src, int inlen);
+
+int utf8_base64_decode(char *dest, int destlen, const char *src, int inlen);
+int utf8_base64_encode(char *dest, int destlen, const char *src, int inlen);
+
+int add_slashes(char *dest, char *src, int maxlen, int len);
+int strip_slashes(char *dest, char *src, int maxlen, int len);
+
+#endif /* _gnokii_internal_h */
Added: trunk/src/host/qemu-neo1973/gnokiigsm/gnokii.h
===================================================================
--- trunk/src/host/qemu-neo1973/gnokiigsm/gnokii.h 2007-05-16 22:38:21 UTC (rev 1986)
+++ trunk/src/host/qemu-neo1973/gnokiigsm/gnokii.h 2007-05-17 00:24:48 UTC (rev 1987)
@@ -0,0 +1,306 @@
+/*
+
+ $Id: gnokii.h,v 1.108 2006/11/26 16:24:24 pkot Exp $
+
+ G N O K I I
+
+ A Linux/Unix toolset and driver for Nokia mobile phones.
+
+ This file is part of gnokii.
+
+ Gnokii 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.
+
+ Gnokii 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 gnokii; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+ Copyright (C) 1999-2000 Hugh Blemings & Pavel Janík ml.
+ Copyright (C) 2001-2005 Pawel Kot
+ Copyright (C) 2001 Chris Kemp
+ copyright (C) 2002 Markus Plail
+ Copyright (C) 2002-2003 BORBELY Zoltan, Ladis Michl
+ Copyright (C) 2004 Martin Goldhahn
+ Copyright (C) 2006 Helge Deller
+
+ Main header file for gnokii. Include just this file in your app.
+*/
+
+#ifndef _gnokii_h
+#define _gnokii_h
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Some portability definitions first */
+#if defined(__linux__) || defined(__GLIBC__)
+# include <stdint.h>
+# include <sys/time.h>
+#elif defined(__svr4__) || defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__bsdi__) || defined(__MACH__)
+# include <inttypes.h>
+# include <sys/time.h>
+#elif defined(_MSC_VER) && defined(WIN32)
+# include <Winsock.h> /* for struct timeval */
+typedef unsigned char uint8_t;
+#endif
+
+#include <stdarg.h>
+
+#ifndef GNOKII_API
+# define GNOKII_API
+#endif
+
+struct gn_statemachine;
+
+#include <error.h>
+#include <common.h>
+#include <data.h>
+#include <encoding.h>
+#include <sms.h>
+#include <call.h>
+#include <networks.h>
+#include <bitmaps.h>
+#include <ringtones.h>
+#include <virtmodem.h>
+#include <rlp-common.h>
+#include <wappush.h>
+
+#include <statemachine.h>
+
+/* Gnokii library functions - they all start with gn_lib_ */
+/* Get the current runtime version (LIBGNOKII_VERSION) of libgnokii - see LIBGNOKII_MAKE_VERSION() */
+GNOKII_API unsigned int gn_lib_version();
+
+/* free any resources which were used by libgnokii */
+GNOKII_API void gn_lib_library_free( void );
+
+/* return last error code from functions below */
+GNOKII_API gn_error gn_lib_lasterror( struct gn_statemachine *state );
+
+/* initialize gnokii library and structures for given phone.
+ configname is the name of the profile, if empty or NULL, [global] will be taken.
+ gn_lib_phoneprofile_load assumes default config file. */
+GNOKII_API gn_error gn_lib_phoneprofile_load_from_file( const char *configfile, const char *configname, struct gn_statemachine **state );
+GNOKII_API gn_error gn_lib_phoneprofile_load( const char *configname, struct gn_statemachine **state );
+
+/* Free any structures and resources which were loaded in this state machine. */
+GNOKII_API gn_error gn_lib_phoneprofile_free( struct gn_statemachine **state );
+
+/* opens connection to the phone. Necessary locking will be made */
+GNOKII_API gn_error gn_lib_phone_open( struct gn_statemachine *state );
+
+/* closes the connection to the phone */
+GNOKII_API gn_error gn_lib_phone_close( struct gn_statemachine *state );
+
+/* ask phone for static information (model, manufacturer, revision and imei) */
+GNOKII_API const char *gn_lib_get_phone_model ( struct gn_statemachine *state ); /* e.g. 6310 */
+GNOKII_API const char *gn_lib_get_phone_product_name( struct gn_statemachine *state ); /* e.g. NPE-4 */
+GNOKII_API const char *gn_lib_get_phone_manufacturer( struct gn_statemachine *state ); /* e.g. Nokia */
+GNOKII_API const char *gn_lib_get_phone_revision ( struct gn_statemachine *state ); /* e.g. V 04.20 */
+GNOKII_API const char *gn_lib_get_phone_imei ( struct gn_statemachine *state );
+
+/* Get the key value from the given section and the key name */
+GNOKII_API const char *gn_lib_cfg_get(const char *section, const char *key);
+
+/* Phone Addressbook functions */
+/* get number of used/free phone addressbook memory slots */
+GNOKII_API gn_error gn_lib_addressbook_memstat( struct gn_statemachine *state,
+ const gn_memory_type memory_type,
+ int *num_used, int *num_free );
+
+/* remove an addressbook entry physically from phone. */
+GNOKII_API gn_error gn_lib_phonebook_entry_delete( struct gn_statemachine *state,
+ const gn_memory_type memory_type, const int index );
+
+/* check if given addressbook entry is empty. Returns "true" if empty, 0 if not. */
+GNOKII_API int gn_lib_phonebook_entry_isempty( struct gn_statemachine *state,
+ const gn_memory_type memory_type, const int index );
+
+/* read given addressbook entry into internal structure. Afterwards ask for each value with functions below */
+GNOKII_API gn_error gn_lib_phonebook_read_entry( struct gn_statemachine *state,
+ const gn_memory_type memory_type, const int index );
+
+/* after reading an entry with gn_lib_phonebook_read_entry() ask for the values of the phonebook entry */
+GNOKII_API const char * gn_lib_get_pb_name ( struct gn_statemachine *state ); /* Mr. Miller */
+GNOKII_API const char * gn_lib_get_pb_number ( struct gn_statemachine *state ); /* +18001189383 */
+GNOKII_API gn_phonebook_group_type gn_lib_get_pb_caller_group ( struct gn_statemachine *state ); /* */
+GNOKII_API gn_memory_type gn_lib_get_pb_memtype ( struct gn_statemachine *state ); /* */
+GNOKII_API int gn_lib_get_pb_location ( struct gn_statemachine *state ); /* 1*/
+GNOKII_API gn_timestamp gn_lib_get_pb_date ( struct gn_statemachine *state ); /* */
+GNOKII_API int gn_lib_get_pb_num_subentries ( struct gn_statemachine *state ); /* */
+GNOKII_API gn_error gn_lib_get_pb_subentry( struct gn_statemachine *state, const int index,
+ gn_phonebook_entry_type *entry_type, gn_phonebook_number_type *number_type, const char **number );
+
+/* How to write to a phonebook entry with 3 steps:
+ a) call gn_lib_phonebook_prepare_write_entry() to initialize structures
+ b) call gn_lib_set_pb_*() to set values (do this for each value you want to set)
+ c) call gn_lib_phonebook_write_entry() to write it physically to phone
+ */
+
+/* initialize gnokii internal phonebook structure */
+GNOKII_API gn_error gn_lib_phonebook_prepare_write_entry( struct gn_statemachine *state );
+
+/* call each of the functions to set a specific value in current internal memory */
+GNOKII_API gn_error gn_lib_set_pb_name ( struct gn_statemachine *state, const char *name ); /* Mr. Miller */
+GNOKII_API gn_error gn_lib_set_pb_number ( struct gn_statemachine *state, const char *number ); /* +18001189383 */
+GNOKII_API gn_error gn_lib_set_pb_caller_group( struct gn_statemachine *state, gn_phonebook_group_type grouptype ); /* */
+GNOKII_API gn_error gn_lib_set_pb_memtype ( struct gn_statemachine *state, gn_memory_type memtype ); /* */
+GNOKII_API gn_error gn_lib_set_pb_location ( struct gn_statemachine *state, int location ); /* 1*/
+GNOKII_API gn_error gn_lib_set_pb_date ( struct gn_statemachine *state, gn_timestamp timestamp ); /* */
+GNOKII_API gn_error gn_lib_set_pb_subentry ( struct gn_statemachine *state, const int index, /* index=-1 appends it */
+ gn_phonebook_entry_type entry_type, gn_phonebook_number_type number_type, const char *number );
+
+/* and now write the addressbook entry physically to phone. */
+GNOKII_API gn_error gn_lib_phonebook_write_entry( struct gn_statemachine *state,
+ const gn_memory_type memory_type, const int index );
+
+GNOKII_API char *gn_subentrytype2string(gn_phonebook_entry_type entry_type, gn_phonebook_number_type number_type);
+
+/* standard helper functions */
+
+/* use this function to get list of all supported phone models.
+ Just start with num=0 and increase until you get back NULL */
+GNOKII_API const char *gn_lib_get_supported_phone_model( const int num );
+
+/* use this function to get list of all supported connection type strings.
+ Just start with num=0 and increase until you get back NULL */
+GNOKII_API const char *gn_lib_get_supported_connection( const int num );
+
+/* use this function to search for a phone which is connected to this
+ computer. Currently libgnokii will search only on IRDA and bluetooth.
+ The state variable will be initialized if a phone was found. */
+GNOKII_API gn_error gn_lib_search_one_connected_phone( struct gn_statemachine **state );
+
+/* Misc */
+GNOKII_API gn_memory_type gn_str2memory_type(const char *s);
+GNOKII_API const char *gn_memory_type2str(gn_memory_type mt);
+GNOKII_API int gn_timestamp_isvalid(const gn_timestamp dt);
+GNOKII_API void gn_timestamp_set(gn_timestamp *dt, int year, int month, int day,
+ int hour, int minute, int second, int timezone);
+GNOKII_API void gn_timestamp_get(gn_timestamp *dt, int *year, int *month, int *day,
+ int *hour, int *minute, int *second, int *timezone);
+
+
+
+/****************************************************************************/
+/* ALL FOLLOWING FUNCTIONS SHOULD BE USED BY GNOKII INTERNAL PROGRAMS ONLY */
+/****************************************************************************/
+
+#ifndef GNOKII_DEPRECATED
+#if __GNUC__ - 0 > 3 || (__GNUC__ - 0 == 3 && __GNUC_MINOR__ - 0 >= 2)
+ /* gcc >= 3.2 */
+# define GNOKII_DEPRECATED __attribute__ ((deprecated))
+#elif defined(_MSC_VER) && (_MSC_VER >= 1300) && (_MSC_VER < 1400)
+ /* msvc >= 7 */
+# define GNOKII_DEPRECATED __declspec(deprecated)
+#elif defined(_MSV_VER) && (_MSC_VER >= 1400)
+ /* MS Visual Studio 2005 */
+# define GNOKII_DEPRECATED
+#else
+# define GNOKII_DEPRECATED
+#endif
+#endif
+
+/* The global variable that keeps the current configuration. This should be
+ * filled in before the phone initialization */
+extern GNOKII_API struct gn_cfg_header *gn_cfg_info GNOKII_DEPRECATED;
+
+/* Files */
+GNOKII_API int gn_file_text_save(char *filename, char *text, int mode) GNOKII_DEPRECATED;
+
+/* Zero the gn_data structure */
+GNOKII_API void gn_data_clear(gn_data *data);
+extern GNOKII_API gn_phone *gn_gsm_info;
+extern GNOKII_API gn_error (*gn_gsm_f)(gn_operation op, gn_data *data,
+ struct gn_statemachine *state);
+/* Initialise the connection and setup the driver according to the current
+ * configuration */
+GNOKII_API gn_error gn_gsm_initialise(struct gn_statemachine *sm) GNOKII_DEPRECATED;
+
+/* Config handling */
+/* Get the key value from the given config, given section and the key name */
+GNOKII_API char *gn_cfg_get(struct gn_cfg_header *cfg, const char *section, const char *key) GNOKII_DEPRECATED;
+GNOKII_API gn_error gn_cfg_read(char **bindir) GNOKII_DEPRECATED;
+/* Read the config from the file filename */
+GNOKII_API gn_error gn_cfg_file_read(const char *filename) GNOKII_DEPRECATED;
+/* Read the config from the file already put into the memory */
+GNOKII_API gn_error gn_cfg_memory_read(const char **lines) GNOKII_DEPRECATED;
+/* Read the config from the standard $HOME/.gnokiirc or /etc/gnokiirc locations */
+GNOKII_API gn_error gn_cfg_read_default() GNOKII_DEPRECATED;
+/* free any resources which were used by libgnokii */
+GNOKII_API void gn_cfg_free_default() GNOKII_DEPRECATED;
+/* Use phone_iname section for the communication. Default is the global section */
+GNOKII_API gn_error gn_cfg_phone_load(const char *iname, struct gn_statemachine *state) GNOKII_DEPRECATED;
+
+/* In/Out routines, file formats */
+GNOKII_API int gn_phonebook2vcard(FILE *f, gn_phonebook_entry *entry, char *location);
+GNOKII_API int gn_vcard2phonebook(FILE *f, gn_phonebook_entry *entry);
+
+GNOKII_API int gn_phonebook2ldif(FILE *f, gn_phonebook_entry *entry);
+GNOKII_API int gn_ldif2phonebook(FILE *f, gn_phonebook_entry *entry);
+
+/* reads internal gnokii raw phonebook format */
+GNOKII_API gn_error gn_file_phonebook_raw_parse(gn_phonebook_entry *entry, char *buffer);
+GNOKII_API gn_error gn_file_phonebook_raw_write(FILE *f, gn_phonebook_entry *entry, char *memory_type_string);
+
+/* DEPRECATED */
+GNOKII_API int gn_vcal_file_event_read(char *filename, gn_calnote *cnote, int number) GNOKII_DEPRECATED;
+GNOKII_API int gn_vcal_file_todo_read(char *filename, gn_todo *ctodo, int number) GNOKII_DEPRECATED;
+
+GNOKII_API int gn_calnote2ical(FILE *f, gn_calnote *calnote);
+GNOKII_API int gn_ical2calnote(FILE *f, gn_calnote *calnote, int id);
+
+GNOKII_API int gn_todo2ical(FILE *f, gn_todo *ctodo);
+GNOKII_API int gn_ical2todo(FILE *f, gn_todo *ctodo, int id);
+
+GNOKII_API void gn_number_sanitize(char *number, int maxlen);
+GNOKII_API void gn_phonebook_entry_sanitize(gn_phonebook_entry *entry);
+
+/* Debugging */
+extern GNOKII_API gn_log_target gn_log_debug_mask;
+extern GNOKII_API gn_log_target gn_log_rlpdebug_mask;
+extern GNOKII_API gn_log_target gn_log_xdebug_mask;
+extern GNOKII_API void (*gn_elog_handler)(const char *fmt, va_list ap);
+GNOKII_API void gn_log_debug(const char *fmt, ...);
+GNOKII_API void gn_log_rlpdebug(const char *fmt, ...);
+GNOKII_API void gn_log_xdebug(const char *fmt, ...);
+GNOKII_API void gn_elog_write(const char *fmt, ...);
+typedef void (*gn_log_func_t)(const char *fmt, ...);
+
+GNOKII_API int gn_line_get(FILE *file, char *line, int count) GNOKII_DEPRECATED;
+
+/* Place a lock for the given device in /var/lock or /var/run */
+GNOKII_API char *gn_device_lock(const char *) GNOKII_DEPRECATED;
+/* Remove a lock for the given device from /var/lock or /var/run */
+GNOKII_API int gn_device_unlock(char *) GNOKII_DEPRECATED;
+
+GNOKII_API const char *gn_model_get(const char *product_name);
+GNOKII_API gn_phone_model *gn_phone_model_get(const char *product_name);
+
+/* SMS */
+GNOKII_API gn_error gn_sms_send(gn_data *data, struct gn_statemachine *state);
+GNOKII_API gn_error gn_sms_save(gn_data *data, struct gn_statemachine *state);
+GNOKII_API gn_error gn_sms_get(gn_data *data, struct gn_statemachine *state);
+GNOKII_API gn_error gn_sms_get_no_validate(gn_data *data, struct gn_statemachine *state);
+GNOKII_API gn_error gn_sms_get_folder_changes(gn_data *data, struct gn_statemachine *state,
+ int has_folders);
+GNOKII_API gn_error gn_sms_delete(gn_data *data, struct gn_statemachine *state);
+GNOKII_API gn_error gn_sms_delete_no_validate(gn_data *data, struct gn_statemachine *state);
+
+/* Call service */
+GNOKII_API gn_error gn_call_dial(int *call_id, gn_data *data, struct gn_statemachine *state);
+GNOKII_API gn_error gn_call_check_active(struct gn_statemachine *state);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _gnokii_h */
Added: trunk/src/host/qemu-neo1973/gnokiigsm/misc.h
===================================================================
--- trunk/src/host/qemu-neo1973/gnokiigsm/misc.h 2007-05-16 22:38:21 UTC (rev 1986)
+++ trunk/src/host/qemu-neo1973/gnokiigsm/misc.h 2007-05-17 00:24:48 UTC (rev 1987)
@@ -0,0 +1,135 @@
+/*
+
+ $Id: misc.h,v 1.54 2006/12/17 16:02:07 pkot Exp $
+
+ G N O K I I
+
+ A Linux/Unix toolset and driver for the mobile phones.
+
+ This file is part of gnokii.
+
+ Gnokii 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.
+
+ Gnokii 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 gnokii; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+ Copyright (C) 1999-2000 Hugh Blemings & Pavel Janík ml.
+ Copyright (C) 2000 Jan Derfinak
+ Copyright (C) 2001-2002 Chris Kemp, Pavel Machek
+ Copyright (C) 2001-2004 Pawel Kot, BORBELY Zoltan
+
+ Header file for miscellaneous defines, typedefs etc.
+
+*/
+
+#ifndef _gnokii_misc_h
+#define _gnokii_misc_h
+
+#include <stdio.h>
+#include <sys/types.h>
+
+#include "compat.h"
+
+/* Some general defines. */
+
+#ifndef false
+# define false (0)
+#endif
+
+#ifndef true
+# define true (!false)
+#endif
+
+#ifndef bool
+# define bool int
+#endif
+
+#define ARRAY_LEN(x) (sizeof((x)) / sizeof((x)[0]))
+
+#define SAFE_STRNCPY(dest, src, n) do { \
+ strncpy((dest), (src), (n)); \
+ if ((n) > 0) \
+ (dest)[(n)-1] = '\0'; \
+ } while (0)
+
+#define SAFE_STRNCPY_SIZEOF(dest,src) \
+ SAFE_STRNCPY((dest), (src), sizeof((dest)))
+
+/* If glib.h is included, G_GNUC_PRINTF is already defined. */
+#ifndef G_GNUC_PRINTF
+/* Stolen from <glib.h>: */
+# if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ > 4)
+# define G_GNUC_PRINTF( format_idx, arg_idx ) \
+ __attribute__((format (printf, format_idx, arg_idx)))
+# else /* !__GNUC__ */
+# define G_GNUC_PRINTF( format_idx, arg_idx )
+# endif /* !__GNUC__ */
+#endif
+
+
+#define GNOKII_MAX(a, b) (((a) > (b)) ? (a) : (b))
+#define GNOKII_MIN(a, b) (((a) < (b)) ? (a) : (b))
+
+/* A define to make debug printfs neat */
+#ifdef __GNUC__
+# ifndef DEBUG
+# define dprintf(a...) do { } while (0)
+# else
+# define dprintf(a...) do { gn_log_debug(a); } while (0)
+# endif /* DEBUG */
+# /* Use it for error reporting */
+# define dump(a...) do { gn_elog_write(a); } while (0)
+#else
+# ifndef DEBUG
+# define dump while (0)
+# define dprintf while (0)
+# else
+# define dump gn_elog_write
+# define dprintf gn_log_debug
+# endif /* DEBUG */
+#endif /* __GNUC__ */
+
+/* Use gsprintf instead of sprintf and sprintf */
+#define gsprintf snprintf
+#define gvsprintf vsnprintf
+#define gasprintf asprintf
+#define gvasprintf vasprintf
+
+/* This is for the bitmaps mostly, but may be useful also for the other
+ * things. Counts how many octets we need to cover the given ammount of
+ * the bits.
+ */
+#define ceiling_to_octet(x) ((x) + 7) / 8
+
+#define PM_OLD_DEFAULT PM_SPEEDDIAL | PM_SMS | PM_DTMF | PM_KEYBOARD | PM_CALENDAR
+#define PM_DEFAULT PM_OLD_DEFAULT | PM_CALLERGROUP | PM_EXTPBK | PM_FOLDERS
+
+#define PM_CALLERGROUP 0x0001
+#define PM_NETMONITOR 0x0002
+#define PM_KEYBOARD 0x0004
+#define PM_SMS 0x0008
+#define PM_CALENDAR 0x0010
+#define PM_DTMF 0x0020
+#define PM_DATA 0x0040
+#define PM_SPEEDDIAL 0x0080
+#define PM_EXTPBK 0x0100
+#define PM_AUTHENTICATION 0x0200
+#define PM_FOLDERS 0x0400
+#define PM_FULLPBK 0x0800
+/* This one indicated reported cases of breaking the phone by xgnokii
+ * in FBUS orver IrDA mode */
+#define PM_XGNOKIIBREAKAGE 0x8000
+
+char **gnokii_strsplit(const char *string, const char *delimiter, int tokens);
+void gnokii_strfreev(char **str_array);
+
+#endif /* _gnokii_misc_h */
Added: trunk/src/host/qemu-neo1973/gnokiigsm/networks.h
===================================================================
--- trunk/src/host/qemu-neo1973/gnokiigsm/networks.h 2007-05-16 22:38:21 UTC (rev 1986)
+++ trunk/src/host/qemu-neo1973/gnokiigsm/networks.h 2007-05-17 00:24:48 UTC (rev 1987)
@@ -0,0 +1,59 @@
+/*
+
+ $Id: networks.h,v 1.14 2006/06/11 16:39:11 deller Exp $
+
+ G N O K I I
+
+ A Linux/Unix toolset and driver for the mobile phones.
+
+ This file is part of gnokii.
+
+ Gnokii 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.
+
+ Gnokii 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 gnokii; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+ Copyright (C) 1999-2000 Hugh Blemings & Pavel Janík ml.
+ Copyright (C) 2002 Pawel Kot
+
+ Header file for GSM networks.
+
+*/
+
+#ifndef _gnokii_networks_h
+#define _gnokii_networks_h
+
+/* This type is used to hold information about various GSM networks. */
+typedef struct {
+ char *code; /* GSM network code */
+ char *name; /* GSM network name */
+} gn_network;
+
+/* This type is used to hold information about various GSM countries. */
+typedef struct {
+ char *code; /* GSM country code */
+ char *name; /* GSM country name */
+} gn_country;
+
+GNOKII_API char *gn_network_name_get(char *network_code);
+GNOKII_API char *gn_network_code_get(char *network_name);
+GNOKII_API char *gn_network_code_find(char *network_name, char *country_name);
+
+GNOKII_API char *gn_country_name_get(char *country_code);
+GNOKII_API char *gn_country_code_get(char *country_name);
+
+GNOKII_API int gn_network_get(gn_network *network, int index);
+GNOKII_API int gn_country_get(gn_country *country, int index);
+
+GNOKII_API char *gn_network2country(char *network);
+
+#endif /* _gnokii_networks_h */
Added: trunk/src/host/qemu-neo1973/gnokiigsm/ringtones.h
===================================================================
--- trunk/src/host/qemu-neo1973/gnokiigsm/ringtones.h 2007-05-16 22:38:21 UTC (rev 1986)
+++ trunk/src/host/qemu-neo1973/gnokiigsm/ringtones.h 2007-05-17 00:24:48 UTC (rev 1987)
@@ -0,0 +1,161 @@
+/*
+
+ $Id: ringtones.h,v 1.21 2006/06/11 16:39:11 deller Exp $
+
+ G N O K I I
+
+ A Linux/Unix toolset and driver for the mobile phones.
+
+ This file is part of gnokii.
+
+ Gnokii 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.
+
+ Gnokii 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 gnokii; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+ Copyright (C) 1999-2000 Hugh Blemings & Pavel Janík ml.
+ Copyright (C) 2000 Marcin Wiacek, Chris Kemp
+ Copyright (C) 2001-2003 Pawel Kot
+ Copyright (C) 2002-2003 BORBELY Zoltan
+
+ This file provides definitions of macros from the Smart Messaging
+ Specification. It is mainly rewrite of the spec to C :-) Viva Nokia!
+
+*/
+
+#ifndef _gnokii_ringtones_h
+#define _gnokii_ringtones_h
+
+#include <error.h>
+
+/* NoteValue is encoded as octave(scale)*14 + note */
+/* where for note: c=0, d=2, e=4 .... */
+/* ie. c#=1 and 5 and 13 are invalid */
+/* note=255 means a pause */
+
+#define GN_RINGTONE_MAX_NOTES 1024
+
+/* Structure to hold note of ringtone. */
+
+typedef struct {
+ unsigned char duration;
+ unsigned char note;
+} gn_ringtone_note;
+
+/* Structure to hold ringtones. */
+typedef struct {
+ int location;
+ char name[20];
+ unsigned char tempo;
+ unsigned int notes_count;
+ gn_ringtone_note notes[GN_RINGTONE_MAX_NOTES];
+} gn_ringtone;
+
+#define gn_ringtone_get_bit(stream, bitno) stream[(bitno) / 8] & 1 << (7 - ((bitno) % 8))
+#define gn_ringtone_set_bit(stream, bitno) stream[(bitno) / 8] |= 1 << (7 - ((bitno) % 8))
+#define gn_ringtone_clear_bit(stream, bitno) stream[(bitno) / 8] &= 255 - (1 << (7 - ((bitno) % 8)))
+
+/* These values are from Smart Messaging Specification Revision 2.0.0 pages
+ 3-23, ..., 3-29 */
+
+/* Command-Part Encoding */
+#define GN_RINGTONE_CancelCommand (0x05 << 1) /* binary 0000 101 */
+#define GN_RINGTONE_Programming (0x25 << 1) /* binary 0100 101 */
+#define GN_RINGTONE_Sound (0x1d << 1) /* binary 0011 101 */
+#define GN_RINGTONE_Unicode (0x22 << 1) /* binary 0100 010 */
+
+/* Song-Type Encoding */
+#define GN_RINGTONE_BasicSongType (0x01 << 5) /* binary 001 */
+#define GN_RINGTONE_TemporarySongType (0x02 << 5) /* binary 010 */
+#define GN_RINGTONE_MidiSongType (0x03 << 5) /* binary 011 */
+#define GN_RINGTONE_DigitizedSongType (0x04 << 5) /* binary 100 */
+
+/* Instruction ID Encoding */
+#define GN_RINGTONE_PatternHeaderId (0x00 << 5) /* binary 000 */
+#define GN_RINGTONE_NoteInstructionId (0x01 << 5) /* binary 001 */
+#define GN_RINGTONE_ScaleInstructionId (0x02 << 5) /* binary 010 */
+#define GN_RINGTONE_StyleInstructionId (0x03 << 5) /* binary 011 */
+#define GN_RINGTONE_TempoInstructionId (0x04 << 5) /* binary 100 */
+#define GN_RINGTONE_VolumeInstructionId (0x05 << 5) /* binary 101 */
+
+/* Style-Value Encoding*/
+#define GN_RINGTONE_NaturalStyle (0x00 << 6) /* binary 00 */
+#define GN_RINGTONE_ContinuousStyle (0x01 << 6) /* binary 01 */
+#define GN_RINGTONE_StaccatoStyle (0x02 << 6) /* binary 11 */
+
+/* Note-Scale Encoding */
+#define GN_RINGTONE_Scale1 (0x00 << 6) /* binary 00 */
+#define GN_RINGTONE_Scale2 (0x01 << 6) /* binary 01 */
+#define GN_RINGTONE_Scale3 (0x02 << 6) /* binary 10 */
+#define GN_RINGTONE_Scale4 (0x03 << 6) /* binary 11 */
+
+/* Note-Value Encoding */
+#define GN_RINGTONE_Note_Pause (0x00 << 4) /* binary 0000 */
+#define GN_RINGTONE_Note_C (0x01 << 4) /* binary 0001 */
+#define GN_RINGTONE_Note_Cis (0x02 << 4) /* binary 0010 */
+#define GN_RINGTONE_Note_D (0x03 << 4) /* binary 0011 */
+#define GN_RINGTONE_Note_Dis (0x04 << 4) /* binary 0100 */
+#define GN_RINGTONE_Note_E (0x05 << 4) /* binary 0101 */
+#define GN_RINGTONE_Note_F (0x06 << 4) /* binary 0110 */
+#define GN_RINGTONE_Note_Fis (0x07 << 4) /* binary 0111 */
+#define GN_RINGTONE_Note_G (0x08 << 4) /* binary 1000 */
+#define GN_RINGTONE_Note_Gis (0x09 << 4) /* binary 1001 */
+#define GN_RINGTONE_Note_A (0x0a << 4) /* binary 1010 */
+#define GN_RINGTONE_Note_Ais (0x0b << 4) /* binary 1011 */
+#define GN_RINGTONE_Note_H (0x0c << 4) /* binary 1100 */
+
+/* Note-Duration Encoding */
+#define GN_RINGTONE_Duration_Full (0x00 << 5) /* binary 000 */
+#define GN_RINGTONE_Duration_1_2 (0x01 << 5) /* binary 001 */
+#define GN_RINGTONE_Duration_1_4 (0x02 << 5) /* binary 010 */
+#define GN_RINGTONE_Duration_1_8 (0x03 << 5) /* binary 011 */
+#define GN_RINGTONE_Duration_1_16 (0x04 << 5) /* binary 100 */
+#define GN_RINGTONE_Duration_1_32 (0x05 << 5) /* binary 101 */
+
+/* Note-Duration-Specifier Encoding */
+#define GN_RINGTONE_NoSpecialDuration (0x00 << 6) /* binary 00 */
+#define GN_RINGTONE_DottedNote (0x01 << 6) /* binary 01 */
+#define GN_RINGTONE_DoubleDottedNote (0x02 << 6) /* binary 10 */
+#define GN_RINGTONE_Length_2_3 (0x03 << 6) /* binary 11 */
+
+/* Pattern ID Encoding */
+#define GN_RINGTONE_A_part (0x00 << 6) /* binary 00 */
+#define GN_RINGTONE_B_part (0x01 << 6) /* binary 01 */
+#define GN_RINGTONE_C_part (0x02 << 6) /* binary 10 */
+#define GN_RINGTONE_D_part (0x03 << 6) /* binary 11 */
+
+/* Command-End */
+#define GN_RINGTONE_CommandEnd (0x00) /* binary 00000000 */
+
+/* Definition of the Note type */
+typedef struct {
+ int scale;
+ int note_id;
+ int duration;
+ int duration_specifier;
+} gn_note;
+
+#define GN_RINGTONE_PACKAGE_MAX_LENGTH 200
+
+/* From PC Composer help */
+#define GN_RINGTONE_NOTES_MAX_NUMBER 130
+
+GNOKII_API gn_error gn_file_ringtone_read(char *filename, gn_ringtone *ringtone);
+GNOKII_API gn_error gn_file_ringtone_save(char *filename, gn_ringtone *ringtone);
+
+GNOKII_API unsigned char gn_ringtone_pack(gn_ringtone *ringtone, unsigned char *package, int *maxlength);
+GNOKII_API gn_error gn_ringtone_unpack(gn_ringtone *ringtone, unsigned char *package, int maxlength);
+GNOKII_API int gn_note_get(int number);
+GNOKII_API void gn_ringtone_get_tone(const gn_ringtone *ringtone, int n, int *freq, int *ulen);
+GNOKII_API void gn_ringtone_set_duration(gn_ringtone *ringtone, int n, int ulen);
+
+#endif /* _gnokii_ringtones_h */
Added: trunk/src/host/qemu-neo1973/gnokiigsm/rlp-common.c
===================================================================
--- trunk/src/host/qemu-neo1973/gnokiigsm/rlp-common.c 2007-05-16 22:38:21 UTC (rev 1986)
+++ trunk/src/host/qemu-neo1973/gnokiigsm/rlp-common.c 2007-05-17 00:24:48 UTC (rev 1987)
@@ -0,0 +1,1823 @@
+/*
+
+ $Id: rlp-common.c,v 1.16 2005/04/20 20:30:18 pkot Exp $
+
+ G N O K I I
+
+ A Linux/Unix toolset and driver for the mobile phones.
+
+ This file is part of gnokii.
+
+ Gnokii 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.
+
+ Gnokii 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 gnokii; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+ Copyright (C) 1999-2000 Hugh Blemings & Pavel Janík ml.
+ Copyright (C) 2001 Chris Kemp
+ Copyright (C) 2002-2004 BORBELY Zoltan
+
+ The development of RLP protocol is sponsored by SuSE CR, s.r.o. (Pavel use
+ the SIM card from SuSE for testing purposes).
+
+ Actual implementation of RLP protocol. Based on GSM 04.22 version 7.1.0,
+ downloadable from www.etsi.org (if you register with them)
+
+*/
+
+#include <stdio.h>
+#include <string.h>
+#include <ctype.h>
+#include <stdlib.h>
+
+#include "compat.h"
+#include "gnokii.h"
+#include "rlp-crc24.h"
+#include "misc.h" /* For u8, u32 etc. */
+
+#define INLINE inline
+
+#ifndef RLP_DEBUG
+# define rlpprintf(a...) do { } while (0)
+#else
+# define rlpprintf(a...) do { gn_log_rlpdebug(a); } while (0)
+#endif
+
+/* Our state machine which handles all of nine possible states of RLP
+ machine. */
+void MAIN_STATE_MACHINE(gn_rlp_f96_frame *frame, rlp_f96_header *header);
+
+/* This is the type we are just handling. */
+rlp_frame_types CurrentFrameType;
+
+/* Current state of RLP state machine. */
+rlp_state CurrentState=RLP_S0; /* We start at ADM and Detached */
+
+/* Next state of RLP state machine. */
+rlp_state NextState;
+
+/* Pointer to Send function that sends frame to phone. */
+bool (*RLP_SendFunction)(gn_rlp_f96_frame *frame, bool out_dtx);
+
+/* Pointer to Passup function which returns data/inds */
+int (*RLP_Passup)(rlp_user_inds ind, u8 *buffer, int length);
+
+
+/* State variables - see GSM 04.22, Annex A, section A.1.2 */
+
+rlp_state_variable UA_State;
+rlp_state_variable UI_State;
+rlp_state_variable Ackn_State;
+rlp_state_variable Poll_State;
+rlp_state_variable Poll_xchg;
+rlp_state_variable SABM_State;
+rlp_state_variable DISC_State;
+rlp_state_variable DM_State; /* FIXME - not handled */
+rlp_state_variable XI_R_State;
+rlp_state_variable XID_C_State;
+rlp_state_variable XID_R_State;
+rlp_state_variable TEST_R_State;
+
+u8 VR=0;
+u8 VA=0;
+u8 VS=0;
+u8 VD=0;
+u8 DISC_Count;
+
+u8 DTX_VR;
+rlp_frame_types DTX_SF;
+
+#define RLP_M 62
+
+rlp_data R[RLP_M];
+rlp_data S[RLP_M];
+
+rlp_state_variable SABM_State;
+int SABM_Count;
+
+rlp_user_request_store UserRequests;
+
+u8 Poll_Count = 0;
+
+/* For now timing is done based on a frame reception rate of 20ms */
+/* Serge has measured it as 18.4ms */
+#define RLP_T_Scaling 2
+
+/* Timers - a value of -1 means not set */
+/* To set, timer is loaded with RLP_Timeout1_Limit/RLP_T_Scaling. */
+/* Each received frame (including NULLS / errors) any >0 timer is decrease */
+
+int T;
+int T_RCVS[RLP_M];
+
+bool UA_FBit = true;
+bool Ackn_FBit = false;
+bool DM_FBit = false; /* FIXME - not handled */
+bool RRReady = false;
+bool LRReady = true; /* FIXME - not handled (as if we couldn't keep up with 9600bps :-) */
+bool DISC_PBit = false;
+
+u8 LastStatus = 0xff; /* Last Status byte */
+
+
+/* RLP Parameters. FIXME: Reset these - e.g. when entering state 0 */
+
+u8 RLP_SEND_WS = RLP_M-1;
+u8 RLP_RCV_WS = RLP_M-1;
+u8 RLP_Timeout1_Limit = 55;
+u8 RLP_N2 = 15; /* Maximum number of retransmisions. GSM spec says 6 here, but
+ Nokia will XID this. */
+u8 RLP_T2 = 0;
+u8 RLP_VersionNumber = 0;
+
+
+/****** Externally called functions ********/
+/*******************************************/
+
+
+/* Function to initialise RLP code. Main purpose for now is
+ to set the address of the RLP send function in the API code. */
+
+void rlp_initialise(bool (*rlp_send_function)(gn_rlp_f96_frame *frame, bool out_dtx), int (*rlp_passup)(rlp_user_inds ind, u8 *buffer, int length))
+{
+ int i;
+
+ RLP_SendFunction = rlp_send_function;
+ RLP_Passup = rlp_passup;
+ UserRequests.Conn_Req = false;
+ UserRequests.Attach_Req = false;
+ UserRequests.Conn_Req_Neg = false;
+ UserRequests.Reset_Resp = false;
+ UserRequests.Disc_Req = false;
+ CurrentState = RLP_S0;
+ T = -1;
+ for (i = 0; i < RLP_M; i++) T_RCVS[i] = -1;
+
+ UA_FBit = true;
+ Ackn_FBit = false;
+ DISC_PBit = false;
+ LastStatus = 0xff;
+ Poll_Count = 0;
+ VR = 0;
+ VA = 0;
+ VS = 0;
+ VD = 0;
+
+ RLP_SEND_WS = RLP_M-1;
+ RLP_RCV_WS = RLP_M-1;
+ RLP_Timeout1_Limit = 55;
+ RLP_N2 = 15;
+ RLP_T2 = 0;
+ RLP_VersionNumber = 0;
+}
+
+/* Set a user event */
+/* Called by user program for now */
+
+void rlp_user_request_set(rlp_user_requests type, bool value)
+{
+ switch (type) {
+ case Conn_Req:
+ UserRequests.Conn_Req = value;
+ break;
+ case Attach_Req:
+ UserRequests.Attach_Req = value;
+ break;
+ case Conn_Req_Neg:
+ UserRequests.Conn_Req_Neg = value;
+ break;
+ case Reset_Resp:
+ UserRequests.Reset_Resp = value;
+ break;
+ case Disc_Req:
+ UserRequests.Disc_Req = value;
+ break;
+ default:
+ break;
+ }
+}
+
+
+/***** Internal functions **********/
+/***********************************/
+
+
+/* Check whether a user event is set */
+
+bool rlp_user_request_get(rlp_user_requests type) {
+
+ bool result = false, *x;
+
+ switch (type) {
+ case Conn_Req:
+ x = &UserRequests.Conn_Req;
+ break;
+ case Attach_Req:
+ x = &UserRequests.Attach_Req;
+ break;
+ case Conn_Req_Neg:
+ x = &UserRequests.Conn_Req_Neg;
+ break;
+ case Reset_Resp:
+ x = &UserRequests.Reset_Resp;
+ break;
+ case Disc_Req:
+ x = &UserRequests.Disc_Req;
+ break;
+ default:
+ x = &result;
+ break;
+ }
+
+ result = *x;
+
+ if (*x == true)
+ *x = false;
+
+ return result;
+}
+
+void RLP_SetTimer(int *timer)
+{
+ *timer = (int)(RLP_Timeout1_Limit/RLP_T_Scaling);
+}
+
+
+/* Previous sequence number. */
+static INLINE u8 Decr(u8 x)
+{
+ if (x == 0)
+ return (RLP_M-1);
+ else
+ return (x-1);
+}
+
+/* Next sequence number. */
+static INLINE u8 Incr(u8 x)
+{
+ if (x == RLP_M-1)
+ return 0;
+ else
+ return (x+1);
+}
+
+/* Difference between sequence numbers. */
+
+/* FIXME: Not used now, so I have commented it out. PJ
+ * static INLINE u8 Diff(u8 x, u8 y)
+ * {
+ * int result = x-y;
+ * return (result >= 0) ? result : result + RLP_M;
+ * }
+*/
+
+/* Check value is within range */
+static bool InWindow(u8 val, u8 lower, u8 upper)
+{
+ /* allow for one level of wrapping round */
+ if (lower >= RLP_M) lower -= RLP_M;
+ if (upper >= RLP_M) upper -= RLP_M;
+ if (val >= RLP_M) val -= RLP_M;
+
+ /* .......L*****U....... */
+ if (lower <= upper)
+ return (val >= lower) && (val <= upper);
+
+ /* ******U.........L***** */
+ return (val <= upper) || (val >= lower);
+}
+
+void RLP_Init_link_vars(void)
+{
+ int i;
+
+ Ackn_State = _idle;
+ Poll_State = _idle;
+ Poll_Count = 0;
+ Poll_xchg = _idle;
+ SABM_State = _idle;
+ DISC_State = _idle;
+ RRReady = true; /* This seems a bit strange but it's what the spec says... */
+ VA = 0;
+ VR = 0;
+ VS = 0;
+ VD = 0;
+ LastStatus = 0xff;
+
+ for (i = 0; i < RLP_M; i++) {
+ R[i].State = _idle;
+ S[i].State = _idle;
+ }
+}
+
+
+void RLP_AddRingBufferDataToSlots(void)
+{
+ u8 buffer[24];
+ int size;
+
+ while ((S[VD].State == _idle)
+ && ((size = RLP_Passup(GetData,buffer,24)) != 0)) {
+ memset(S[VD].Data, 0xff, 25); /* FIXME - this isn't necessary - but makes debugging easier! */
+ if (size > 23) {
+ S[VD].Data[0] = 0x1e;
+ size = 24;
+ } else S[VD].Data[0] = size;
+
+ memcpy(&S[VD].Data[1], buffer, size);
+
+ if (size != 24) S[VD].Data[size+1] = 0x1f;
+
+ S[VD].State = _send;
+ VD = Incr(VD);
+ }
+}
+
+
+static void RLP_DumpF96Frame(gn_rlp_f96_frame *frame)
+{
+ rlp_f96_header header;
+
+ rlp_f96_header_decode(frame, &header);
+
+ switch (header.Type) {
+
+ case RLP_FT_U: /* Unnumbered frames. */
+ rlpprintf("Unnumbered Frame [$%02x%02x] M=%02x ", frame->Header[0],
+ frame->Header[1],
+ header.M);
+
+ switch (header.M) {
+ case RLP_U_SABM :
+ rlpprintf("Set Asynchronous Balanced Mode (SABM) ");
+ break;
+
+ case RLP_U_UA:
+ rlpprintf("Unnumbered Acknowledge (UA) ");
+ break;
+
+ case RLP_U_DISC:
+ rlpprintf("Disconnect (DISC) ");
+ break;
+
+ case RLP_U_DM:
+ rlpprintf("Disconnected Mode (DM) ");
+ break;
+
+ case RLP_U_UI:
+ rlpprintf("Unnumbered Information (UI) ");
+ break;
+
+ case RLP_U_XID:
+ rlpprintf("Exchange Information (XID) \n");
+ rlp_xid_display(frame->Data);
+ break;
+
+ case RLP_U_TEST:
+ rlpprintf("Test (TEST) ");
+ break;
+
+ case RLP_U_NULL:
+ rlpprintf("Null information (NULL) ");
+ break;
+
+ case RLP_U_REMAP:
+ rlpprintf("Remap (REMAP) ");
+ break;
+
+ default:
+ rlpprintf("Unknown!!! ");
+ break;
+ }
+ break;
+
+ case RLP_FT_S: /* Supervisory frames. */
+ rlpprintf("Supervisory Frame [$%02x%02x] S=0x%x N(R)=%d ",
+ frame->Header[0],
+ frame->Header[1],
+ header.S,
+ header.Nr);
+
+ switch (header.S) {
+ case RLP_S_RR:
+ rlpprintf("RR");
+ break;
+
+ case RLP_S_REJ:
+ rlpprintf("REJ");
+ break;
+
+ case RLP_S_RNR:
+ rlpprintf("RNR");
+ break;
+
+ case RLP_S_SREJ:
+ rlpprintf("SREJ");
+ break;
+
+ default:
+ rlpprintf("BAD");
+ break;
+ }
+ break;
+
+ default:
+ rlpprintf("Info+Supervisory Frame [$%02x%02x] S=0x%x N(S)=%d N(R)=%d ",
+ frame->Header[0],
+ frame->Header[1],
+ header.S,
+ header.Ns,
+ header.Nr);
+
+ switch (header.S) {
+ case RLP_S_RR:
+ rlpprintf("RR");
+ break;
+
+ case RLP_S_REJ:
+ rlpprintf("REJ");
+ break;
+
+ case RLP_S_RNR:
+ rlpprintf("RNR");
+ break;
+
+ case RLP_S_SREJ:
+ rlpprintf("SREJ");
+ break;
+
+ default:
+ rlpprintf("BAD");
+ break;
+ }
+
+ break;
+ }
+
+ /* Command/Response and Poll/Final bits. */
+ rlpprintf(" C/R=%d P/F=%d", header.CR, header.PF);
+
+ /* Information. */
+ /*
+ if (CurrentFrameType != RLP_FT_U_NULL) {
+
+ dprintf("\n");
+
+ for (count = 0; count < 25; count ++) {
+
+ if (isprint(frame->Data[count]))
+ dprintf("[%02x%c]", frame->Data[count], frame->Data[count]);
+ else
+ dprintf("[%02x ]", frame->Data[count]);
+
+ if (count == 15)
+ dprintf("\n");
+ }
+ }
+ */
+
+ /* FCS. */
+ rlpprintf(" FCS: %02x %02x %02x\n\n", frame->FCS[0],
+ frame->FCS[1],
+ frame->FCS[2]);
+}
+
+/* FIXME: Remove this after finishing. */
+void X(gn_rlp_f96_frame *frame)
+{
+ int i;
+
+ for (i = 0; i < 30; i++)
+ dprintf("byte[%2d]: %02x\n", i, *( (u8 *)frame + i));
+}
+
+
+void ResetAllT_RCVS(void)
+{
+ int i;
+ for (i = 0; i < RLP_M; i++) T_RCVS[i] = -1;
+}
+
+
+/* This function is used for sending RLP frames to the phone. */
+void RLP_SendF96Frame(rlp_frame_types FrameType,
+ bool OutCR, bool OutPF,
+ u8 OutNR, u8 OutNS,
+ u8 *OutData, u8 OutDTX)
+{
+
+ gn_rlp_f96_frame frame;
+ int i;
+
+ frame.Header[0] = 0;
+ frame.Header[1] = 0;
+
+#define SetCRBit frame.Header[0] |= 0x01;
+#define SetPFBit frame.Header[1] |= 0x02;
+
+#define ClearCRBit frame.Header[0] &= (~0x01);
+#define ClearPFBit frame.Header[1] &= (~0x02);
+
+ /* If Command/Response bit is set, set it in the header. */
+ if (OutCR) SetCRBit;
+
+ /* If Poll/Final bit is set, set it in the header. */
+ if (OutPF) SetPFBit;
+
+ /* If OutData is not specified (ie. is NULL) we want to clear frame.Data
+ array for the user. */
+ if (!OutData) {
+ frame.Data[0] = 0x00; /* 0x1f */
+ for (i = 1; i < 25; i++)
+ frame.Data[i] = 0;
+ } else {
+ for (i = 0; i < 25; i++)
+ frame.Data[i] = OutData[i];
+ }
+
+#define PackM(x) frame.Header[1] |= ((x) << 2);
+#define PackS(x) frame.Header[0]|=((x) << 1);
+#define PackNR frame.Header[1] |= (OutNR << 2);
+#define PackNS frame.Header[0] |= (OutNS << 3); frame.Header[1] |= (OutNS >> 5);
+
+ switch (FrameType) {
+
+ /* Unnumbered frames. Be careful - some commands are used as commands
+ only, so we have to set C/R bit later. We should not allow user for
+ example to send SABM as response because in the spec is: The SABM
+ encoding is used as command only. */
+ case RLP_FT_U_SABM:
+ frame.Header[0] |= 0xf8; /* See page 11 of the GSM 04.22 spec - 0 X X 1 1 1 1 1 */
+ frame.Header[1] |= 0x01; /* 1 P/F M1 M2 M3 M4 M5 X */
+ SetCRBit; /* The SABM encoding is used as a command only. */
+ SetPFBit; /* It is always used with the P-bit set to "1". */
+ PackM(RLP_U_SABM);
+ break;
+
+ case RLP_FT_U_UA:
+ frame.Header[0] |= 0xf8;
+ frame.Header[1] |= 0x01;
+ ClearCRBit; /* The UA encoding is used as a response only. */
+ PackM(RLP_U_UA);
+ break;
+
+ case RLP_FT_U_DISC:
+ frame.Header[0] |= 0xf8;
+ frame.Header[1] |= 0x01;
+ SetCRBit; /* The DISC encoding is used as a command only. */
+ PackM(RLP_U_DISC);
+ break;
+
+ case RLP_FT_U_DM:
+ frame.Header[0] |= 0xf8;
+ frame.Header[1] |= 0x01;
+ ClearCRBit; /* The DM encoding is used as a response only. */
+ PackM(RLP_U_DM);
+ break;
+
+ case RLP_FT_U_NULL:
+ frame.Header[0] |= 0xf8;
+ frame.Header[1] |= 0x01;
+ PackM(RLP_U_NULL);
+ break;
+
+ case RLP_FT_U_UI:
+ frame.Header[0] |= 0xf8;
+ frame.Header[1] |= 0x01;
+ PackM(RLP_U_UI);
+ break;
+
+ case RLP_FT_U_XID:
+ frame.Header[0] |= 0xf8;
+ frame.Header[1] |= 0x01;
+ SetPFBit; /* XID frames are always used with the P/F-bit set to "1". */
+ PackM(RLP_U_XID);
+ break;
+
+ case RLP_FT_U_TEST:
+ frame.Header[0] |= 0xf8;
+ frame.Header[1] |= 0x01;
+ PackM(RLP_U_TEST);
+ break;
+
+ case RLP_FT_U_REMAP:
+ frame.Header[0] |= 0xf8;
+ frame.Header[1] |= 0x01;
+ ClearPFBit; /* REMAP frames are always used with P/F-bit set to "0". */
+ PackM(RLP_U_REMAP);
+ break;
+
+ case RLP_FT_S_RR:
+ frame.Header[0] |= 0xf0; /* See page 11 of the GSM 04.22 spec - 0 X X 1 1 1 1 1 */
+ frame.Header[1] |= 0x01; /* 1 P/F ...N(R)... */
+ PackNR;
+ PackS(RLP_S_RR);
+ break;
+
+ case RLP_FT_S_REJ:
+ frame.Header[0] |= 0xf0;
+ frame.Header[1] |= 0x01;
+ PackNR;
+ PackS(RLP_S_REJ);
+ break;
+
+ case RLP_FT_S_RNR:
+ frame.Header[0] |= 0xf0;
+ frame.Header[1] |= 0x01;
+ PackNR;
+ PackS(RLP_S_RNR);
+ break;
+
+ case RLP_FT_S_SREJ:
+ frame.Header[0] |= 0xf0;
+ frame.Header[1] |= 0x01;
+ PackNR;
+ PackS(RLP_S_SREJ);
+ break;
+
+ case RLP_FT_SI_RR:
+ PackNR;
+ PackNS;
+ PackS(RLP_S_RR);
+ break;
+
+ case RLP_FT_SI_REJ:
+ PackNR;
+ PackNS;
+ PackS(RLP_S_REJ);
+ break;
+
+ case RLP_FT_SI_RNR:
+ PackNR;
+ PackNS;
+ PackS(RLP_S_RNR);
+ break;
+
+ case RLP_FT_SI_SREJ:
+ PackNR;
+ PackNS;
+ PackS(RLP_S_SREJ);
+ break;
+
+ default:
+ break;
+ }
+
+ /* Store FCS in the frame. */
+ rlp_crc24checksum_calculate((u8 *)&frame, 27, frame.FCS);
+
+ /* X(&frame); */
+
+ rlpprintf("S ");
+ RLP_DumpF96Frame(&frame);
+
+ if (RLP_SendFunction)
+ RLP_SendFunction(&frame, OutDTX);
+}
+
+/* Check_input_PDU in Serge's code. */
+void rlp_f96_frame_display(gn_rlp_f96_frame *frame)
+{
+ int count;
+ rlp_f96_header header;
+
+ if (T >= 0) T--;
+ for (count = 0; count < RLP_M; count++)
+ if (T_RCVS[count] >= 0) T_RCVS[count]--;
+
+ CurrentFrameType = RLP_FT_BAD;
+
+ if (!frame) {
+ /* no frame provided, drop through to state machine anyway */
+ } else if (rlp_crc24fcs_check((u8 *)frame, 30) == true) {
+
+ /* Here we have correct RLP frame so we can parse the field of the header
+ to out structure. */
+
+ rlpprintf("R ");
+ RLP_DumpF96Frame(frame);
+
+ rlp_f96_header_decode(frame, &header);
+
+ switch (header.Type) {
+
+ case RLP_FT_U: /* Unnumbered frames. */
+
+ switch (header.M) {
+ case RLP_U_SABM :
+ if (header.CR == 0 || header.PF == 0) break;
+ CurrentFrameType = RLP_FT_U_SABM;
+ break;
+
+ case RLP_U_UA:
+ if (header.CR == 1) break;
+ CurrentFrameType = RLP_FT_U_UA;
+ break;
+
+ case RLP_U_DISC:
+ if (header.CR == 0) break;
+ CurrentFrameType = RLP_FT_U_DISC;
+ break;
+
+ case RLP_U_DM:
+ if (header.CR == 1) break;
+ CurrentFrameType = RLP_FT_U_DM;
+ break;
+
+ case RLP_U_UI:
+ CurrentFrameType = RLP_FT_U_UI;
+ break;
+
+ case RLP_U_XID:
+ CurrentFrameType = RLP_FT_U_XID;
+ break;
+
+ case RLP_U_TEST:
+ CurrentFrameType = RLP_FT_U_TEST;
+ break;
+
+ case RLP_U_NULL:
+ CurrentFrameType = RLP_FT_U_NULL;
+ break;
+
+ case RLP_U_REMAP:
+ CurrentFrameType = RLP_FT_U_REMAP;
+ break;
+
+ default:
+ CurrentFrameType = RLP_FT_BAD;
+ break;
+ }
+ break;
+
+ case RLP_FT_S: /* Supervisory frames. */
+
+ switch (header.S) {
+ case RLP_S_RR:
+ CurrentFrameType = RLP_FT_S_RR;
+ break;
+
+ case RLP_S_REJ:
+ CurrentFrameType = RLP_FT_S_REJ;
+ break;
+
+ case RLP_S_RNR:
+ CurrentFrameType = RLP_FT_S_RNR;
+ break;
+
+ case RLP_S_SREJ:
+ CurrentFrameType = RLP_FT_S_SREJ;
+ break;
+
+ default:
+ CurrentFrameType = RLP_FT_BAD;
+ break;
+ }
+ break;
+
+ default:
+
+ switch (header.S) {
+ case RLP_S_RR:
+ CurrentFrameType = RLP_FT_SI_RR;
+ break;
+
+ case RLP_S_REJ:
+ CurrentFrameType = RLP_FT_SI_REJ;
+ break;
+
+ case RLP_S_RNR:
+ CurrentFrameType = RLP_FT_SI_RNR;
+ break;
+
+ case RLP_S_SREJ:
+ CurrentFrameType = RLP_FT_SI_SREJ;
+ break;
+
+ default:
+ CurrentFrameType = RLP_FT_BAD;
+ break;
+ }
+
+ break;
+ }
+
+ } else {
+ /* RLP Checksum failed - don't we need some statistics about these
+ failures? Nothing is printed, because in the first stage of connection
+ there are too many bad RLP frames... */
+ dprintf("Frame FCS is bad. Ignoring...\n");
+ }
+
+ MAIN_STATE_MACHINE(frame, &header);
+ /*
+ Y:= outblock();
+ */
+ return;
+}
+
+/* FIXME: real TEST_Handling - we do not handle TEST yet. */
+void TEST_Handling()
+{
+ return;
+}
+
+/* FIXME: better XID_handling - but this will answer a XID command. */
+bool XID_Handling (gn_rlp_f96_frame *frame, rlp_f96_header *header)
+{
+ u8 count;
+ u8 type;
+ u8 length;
+
+ if (CurrentFrameType == RLP_FT_U_XID) {
+ count = 0;
+ while (frame->Data[count] != 0) {
+
+ type = frame->Data[count] >> 4;
+ length = frame->Data[count] & 0x0f;
+ count++;
+
+ switch (type) {
+
+ case 0x01: /* RLP Version Number */
+ RLP_VersionNumber = frame->Data[count];
+ count += length;
+ break;
+ case 0x02: /* Interworking Function (IWF) to Mobile Station (MS) window size */
+ if (frame->Data[count] >= 1 && frame->Data[count] < RLP_M)
+ RLP_RCV_WS = frame->Data[count];
+ count += length;
+ break;
+ case 0x03: /* MS to IWF window size */
+ if (frame->Data[count] >= 1 && frame->Data[count] < RLP_M)
+ RLP_SEND_WS = frame->Data[count];
+ count += length;
+ break;
+ case 0x04: /* Acknowledgement Timer (T1). */
+ RLP_Timeout1_Limit = frame->Data[count];
+ count += length;
+ break;
+ case 0x05: /* Retransmission attempts (N2). */
+ RLP_N2 = frame->Data[count];
+ count += length;
+ break;
+ case 0x06: /* Reply delay (T2). */
+ RLP_T2 = frame->Data[count];
+ count += length;
+ break;
+ case 0x07: /* Compression - not yet! */
+ break;
+ default:
+ count += length;
+ break;
+ }
+ }
+
+ /* Now reassemble a reply */
+ count = 0;
+ memset(frame->Data, 0x00, 25); /* Makes debugging easier */
+
+ /* Version Number - force to 0 for now */
+ RLP_VersionNumber = 0;
+ frame->Data[count++] = 0x11;
+ frame->Data[count++] = RLP_VersionNumber;
+
+ /* Window sizes */
+ frame->Data[count++] = 0x21;
+ frame->Data[count++] = RLP_RCV_WS;
+ frame->Data[count++] = 0x31;
+ frame->Data[count++] = RLP_SEND_WS;
+
+ /* Acknowledgement Timer (T1). */
+ frame->Data[count++] = 0x41;
+ frame->Data[count++] = RLP_Timeout1_Limit;
+
+ /* Retransmission attempts (N2). */
+ frame->Data[count++] = 0x51;
+ frame->Data[count++] = RLP_N2;
+
+ /* Reply delay (T2). */
+ frame->Data[count++] = 0x61;
+ frame->Data[count++] = RLP_T2;
+
+ XID_R_State = _send;
+
+ return true;
+ }
+
+ return false;
+}
+
+
+bool Send_TXU(gn_rlp_f96_frame *frame, rlp_f96_header *header)
+{
+ dprintf("Send_TXU()\n");
+ dprintf("XID_R_State=%d\n", XID_R_State);
+
+ /*
+ if (RLP_UserEvent(TEST_R_State)) {
+ RLP_SendF96Frame(RLP_FT_U_TEST, false, TEST_R_FBit, 0, 0, TEST_R_Data, false);
+ return true;
+ } else
+ */
+
+ if (XID_R_State == _send && frame) {
+ RLP_SendF96Frame(RLP_FT_U_XID, false, true, 0, 0, frame->Data, false);
+ XID_R_State = _idle;
+ return true;
+ }
+
+ /*
+ else if ((XID_C_State == _send ) && (Poll_xchg == _idle)) {
+ RLP_SendF96Frame(RLP_FT_U_XID, true, true, 0, 0, XID_C_Data, false);
+ XID_C_State = _wait;
+ T_XID = 1;
+ Poll_xchg = _wait;
+ return true;
+ } else if (RLP_UserEvent(UI_State)) {
+ RLP_SendF96Frame(RLP_FT_U_UI, true, false, 0, 0, NULL, false);
+ return true;
+ }
+ */
+
+ return false;
+}
+
+
+/* Deliver data */
+
+void RLP_DeliverAllInSeqIF()
+{
+ int i,j;
+
+ do {
+ if ((R[VR].Data[0] & 0xE0) != LastStatus) {
+ LastStatus = (R[VR].Data[0] & 0xE0);
+ RLP_Passup(StatusChange, &LastStatus, 0);
+ }
+
+ j = 0;
+ i = R[VR].Data[0] & 0x1f;
+ if (i == 0x1e) j = 24;
+ if (i < 0x18) j = i;
+
+ /* FIXME - should check for more data in the frame */
+
+ RLP_Passup(Data, R[VR].Data+1, j);
+
+ R[VR].State = _idle;
+ VR = Incr(VR);
+
+ } while (R[VR].State == _rcvd);
+}
+
+
+/* Mark any missing information frames between VR and Ns */
+void RLP_MarkMissingIF(u8 Ns)
+{
+ u8 i;
+ for (i = VR; i != Ns; i = Incr(i)) {
+ if (R[i].State == _idle) R[i].State = _srej; /* bug in spec, fig A.23 */
+ }
+}
+
+
+/* Information frame handler */
+
+bool RLP_I_Handler(gn_rlp_f96_frame *frame, rlp_f96_header *header)
+{
+ if ((header->CR) && (header->PF))
+ return true;
+
+ /* If the window size is 61, a received frame must have a sequence
+ number between VR and VR+60 */
+ if (!InWindow(header->Ns, VR, VR + RLP_RCV_WS - 1))
+ return true;
+
+ if (header->Ns == VR) {
+ /* This is not in the spec but I think it is necessary */
+ if (R[header->Ns].State == _wait) T_RCVS[header->Ns] = -1;
+ R[VR].State = _rcvd;
+ memcpy(R[VR].Data, frame->Data, 25);
+ RLP_DeliverAllInSeqIF();
+ Ackn_State = _send;
+ } else { /* Out of sequence, cause a SREJ */
+ if (R[header->Ns].State == _wait) T_RCVS[header->Ns] = -1;
+ R[header->Ns].State = _rcvd;
+ memcpy(R[header->Ns].Data, frame->Data, 25);
+ RLP_MarkMissingIF(header->Ns);
+ }
+ return false;
+}
+
+
+/* Mark acknowledged send frames */
+void RLP_AdvanceVA(u8 Nr)
+{
+ while (VA != Nr) {
+ S[VA].State = _idle;
+ VA = Incr(VA);
+ }
+}
+
+
+/* Decrease VS back down to Nr since these have not been acknowledged */
+void RLP_DecreaseVS(u8 Nr)
+{
+ while (VS != Nr) {
+ VS = Decr(VS);
+ S[VS].State = _send;
+ }
+}
+
+/* Supervisory frame handling */
+void RLP_S_Handler(gn_rlp_f96_frame *frame, rlp_f96_header *header)
+{
+ u8 i;
+
+ if ((header->CR) && (header->PF)) {
+ /* Special exchange (ie. error) - counter? */
+ rlpprintf("Got Poll command\n");
+ Ackn_State = _send;
+ Ackn_FBit = true;
+ for (i = 0; i < RLP_M; i++) R[i].State = _idle;
+ ResetAllT_RCVS();
+ }
+ if (Poll_State != _idle) {
+ if (header->PF == 0) return;
+ if ((CurrentFrameType == RLP_FT_S_SREJ) || (CurrentFrameType == RLP_FT_S_REJ) ||
+ (CurrentFrameType == RLP_FT_SI_SREJ) || (CurrentFrameType == RLP_FT_SI_REJ)) return;
+ RLP_DecreaseVS(header->Nr);
+ Poll_State = _idle;
+ Poll_xchg = _idle;
+ }
+
+ switch (CurrentFrameType) {
+ case RLP_FT_S_RR:
+ case RLP_FT_SI_RR:
+ RLP_AdvanceVA(header->Nr);
+ RRReady = true;
+ break;
+ case RLP_FT_S_RNR:
+ case RLP_FT_SI_RNR:
+ RLP_AdvanceVA(header->Nr);
+ RRReady = false;
+ break;
+ case RLP_FT_S_REJ:
+ case RLP_FT_SI_REJ:
+ RLP_AdvanceVA(header->Nr);
+ RRReady = true;
+ RLP_DecreaseVS(header->Nr);
+ break;
+ case RLP_FT_S_SREJ:
+ case RLP_FT_SI_SREJ:
+ S[header->Nr].State = _send;
+ T = -1;
+ return;
+ default:
+ break;
+ }
+
+ if (VA == VS) T = -1;
+}
+
+
+/* Find the first SREJ frame */
+bool RLP_SREJSlot(u8 *x)
+{
+ u8 i;
+
+ for (i = Incr(VR); i != VR; i = Incr(i))
+ if (R[i].State == _srej) {
+ *x = i;
+ return true;
+ }
+
+ return false;
+}
+
+
+/* Check if any SREJ frames need sending, if not send the next in line */
+bool RLP_PrepareDataToTransmit(u8 *p)
+{
+ u8 i;
+
+ for (i = VA; i != VS; i = Incr(i))
+ if (S[i].State == _send) {
+ *p = i;
+ S[i].State = _wait;
+ return true;
+ }
+ if (S[VS].State != _send) return false;
+ if (!InWindow(VS, VA, VA + RLP_SEND_WS - 1))
+ return false;
+ *p = VS;
+ S[VS].State = _wait;
+ VS = Incr(VS);
+ return true;
+}
+
+
+/* Send a SREJ command */
+void RLP_SendSREJ(u8 x)
+{
+ u8 k;
+
+ if ((Poll_xchg == _idle) && (Poll_State == _send)) {
+ rlpprintf("Sending SREJ with poll\n");
+ RLP_SendF96Frame(RLP_FT_S_SREJ, true, true, x, 0, NULL, false);
+ R[x].State = _wait;
+ RLP_SetTimer(&T_RCVS[x]);
+ Poll_Count++;
+ Poll_State = _wait;
+ Poll_xchg = _wait;
+ RLP_SetTimer(&T);
+ } else if (RRReady && RLP_PrepareDataToTransmit(&k)) {
+ rlpprintf("Sending SREJ for %d along with frame %d\n", x, k);
+ RLP_SendF96Frame(RLP_FT_SI_SREJ, true, false, x , k , S[k].Data, false);
+ R[x].State = _wait;
+ RLP_SetTimer(&T_RCVS[x]);
+ RLP_SetTimer(&T);
+ } else {
+ rlpprintf("Sending SREJ for %d\n",x);
+ RLP_SendF96Frame(RLP_FT_S_SREJ, true, false, x, 0, NULL, false);
+ R[x].State = _wait;
+ RLP_SetTimer(&T_RCVS[x]);
+ }
+}
+
+
+/* Send a command */
+void RLP_Send_XX_Cmd(rlp_frame_types type)
+{
+ u8 k;
+
+ if ((Poll_xchg != _wait) && (Poll_State == _send)) {
+ RLP_SendF96Frame(type, true, true, VR, 0, NULL, false);
+ rlpprintf("Sending Comd %x with Poll\n",type);
+ Ackn_State = _idle;
+ Poll_Count++;
+ Poll_State = _wait;
+ Poll_xchg = _wait;
+ RLP_SetTimer(&T);
+ } else if (RRReady && RLP_PrepareDataToTransmit(&k)) {
+ rlpprintf("Sending Comd %x with frame %d\n", type, k);
+ RLP_SendF96Frame(type + 4, true, false, VR, k, S[k].Data, false);
+ Ackn_State = _idle;
+ RLP_SetTimer(&T);
+ } else {
+ if (type != 9)
+ rlpprintf("Sending Comd %x\n",type);
+ RLP_SendF96Frame(type, true, false, VR, 0, NULL, false);
+ Ackn_State = _idle;
+ DTX_SF = type;
+ DTX_VR = VR; /* As v7.1.0 spec */
+ }
+}
+
+
+/* Send a Response */
+void RLP_Send_XX_Resp(rlp_frame_types type)
+{
+ u8 k;
+
+ if (RRReady && RLP_PrepareDataToTransmit(&k)) {
+ rlpprintf("Sending Resp %x with frame %d\n",type+4,k);
+ RLP_SendF96Frame(type + 4, false, true, VR, k, S[k].Data, false);
+ Ackn_State = _idle;
+ Ackn_FBit = false;
+ RLP_SetTimer(&T);
+ } else {
+ rlpprintf("Sending Resp %x\n",type);
+ RLP_SendF96Frame(type, false, true, VR, 0, NULL, false);
+ Ackn_State = _idle;
+ Ackn_FBit = false;
+ }
+}
+
+
+/* Decide which frame to use and send it - currently only used in state 4 */
+void RLP_SendData()
+{
+ u8 x;
+
+ if (UA_State == _send) {
+ RLP_SendF96Frame(RLP_FT_U_UA, false, UA_FBit, 0, 0, NULL, false);
+ UA_State = _idle;
+ } else if (Ackn_FBit == true) {
+ rlpprintf("About to send Poll resp\n");
+ if (LRReady) RLP_Send_XX_Resp(RLP_FT_S_RR);
+ else RLP_Send_XX_Resp(RLP_FT_S_RNR);
+ } else if (RLP_SREJSlot(&x)) RLP_SendSREJ(x);
+ else if (LRReady) RLP_Send_XX_Cmd(RLP_FT_S_RR);
+ else RLP_Send_XX_Cmd(RLP_FT_S_RNR);
+}
+
+void MAIN_STATE_MACHINE(gn_rlp_f96_frame *frame, rlp_f96_header *header)
+{
+ int i;
+
+ switch (CurrentState) {
+ /***** RLP State 0. *****/
+
+ /* ADM and Detached.
+
+ This is the initial state after power on.
+
+ As long as the RLP entity is "Detached", DISC(P) and/or SABM at the
+ lower interface is acted upon by sending DM(P) or DM(1). Any other
+ stimulus at the lower interface is ignored.
+
+ This state can be exited only with Attach_Req. */
+
+ case RLP_S0:
+ dprintf("RLP state 0.\n");
+
+ switch (CurrentFrameType) {
+
+ case RLP_FT_U_DISC:
+ RLP_SendF96Frame(RLP_FT_U_DM, false, header->PF, 0, 0, NULL, false);
+ break;
+
+ case RLP_FT_U_SABM:
+ RLP_SendF96Frame(RLP_FT_U_DM, false, true, 0, 0, NULL, false);
+ break;
+
+ default:
+ RLP_SendF96Frame(RLP_FT_U_NULL, false, false, 0, 0, NULL, false);
+ if (rlp_user_request_get(Attach_Req)) {
+ NextState = RLP_S1;
+ UA_State = _idle;
+ }
+ break;
+ }
+
+ break;
+
+ /***** RLP State 1. *****/
+
+ /* ADM and Attached.
+
+ The RLP entity is ready to established a connection, either by
+ initiating the connection itself (Conn_Req) or by responding to an
+ incoming connection request (SABM).
+
+ Upon receiving a DISC PDU, the handling of the UA response is
+ initiated. */
+
+ case RLP_S1:
+ dprintf("RLP state 1.\n");
+
+ if (!XID_Handling(frame, header)) {
+
+ switch(CurrentFrameType) {
+
+ case RLP_FT_U_TEST:
+ TEST_Handling();
+ break;
+
+ case RLP_FT_U_SABM:
+ RLP_Passup(Conn_Ind, NULL, 0);
+ NextState = RLP_S3;
+ break;
+
+ case RLP_FT_U_DISC:
+ UA_State = _send;
+ UA_FBit = header->PF;
+ break;
+
+ case RLP_FT_BAD: /* If we get a bad frame we can still respond with SABM */
+ default:
+ if (rlp_user_request_get(Conn_Req)) {
+ SABM_State = _send;
+ SABM_Count = 0;
+ NextState = RLP_S2;
+ }
+ break;
+ }
+
+ }
+ if (!Send_TXU(frame, header)) {
+
+ if (UA_State == _send) {
+ RLP_SendF96Frame(RLP_FT_U_UA, false, UA_FBit, 0, 0, NULL, false);
+ UA_State = _idle;
+ } else
+ RLP_SendF96Frame(RLP_FT_U_NULL, false, false, 0, 0, NULL, false);
+ }
+ break;
+
+ /***** RLP State 2. *****/
+
+ case RLP_S2:
+ dprintf("RLP state 2.\n");
+
+ if (!XID_Handling(frame, header)) {
+
+ switch(CurrentFrameType) {
+
+ case RLP_FT_U_TEST:
+ TEST_Handling();
+ break;
+
+ case RLP_FT_U_SABM:
+ /*
+ Conn_Conf = true;
+ */
+ T = -1;
+ UA_State = _send;
+ UA_FBit = true;
+ RLP_Init_link_vars();
+ NextState = RLP_S4;
+ break;
+
+ case RLP_FT_U_DISC:
+ T = -1;
+ RLP_Passup(Disc_Ind, NULL, 0);
+ UA_State = _send;
+ UA_FBit = header->PF;
+ NextState = RLP_S1;
+ break;
+
+ case RLP_FT_U_UA:
+ dprintf("UA received in RLP state 2.\n");
+
+ if (SABM_State == _wait && header->PF) {
+ T = -1;
+ /* Conn_Conf = true; */
+ RLP_Init_link_vars();
+ NextState = RLP_S4;
+ }
+ break;
+
+ case RLP_FT_U_DM:
+ if (SABM_State == _wait && header->PF) {
+ Poll_xchg = _idle;
+ /* Conn_Conf_Neg = true; */
+ NextState = RLP_S1;
+ }
+ break;
+
+ default:
+ if (T == RLP_Timeout1_Limit || T == 0) {
+ Poll_xchg = _idle;
+ if (SABM_Count > RLP_N2)
+ NextState = RLP_S8;
+ SABM_State = _send;
+ }
+ break;
+ }
+ }
+
+ if (!Send_TXU(frame, header)) {
+
+ if (SABM_State == _send && Poll_xchg == _idle) {
+ RLP_SendF96Frame(RLP_FT_U_SABM, true, true, 0, 0, NULL, false);
+ SABM_State = _wait;
+ SABM_Count++;
+ Poll_xchg = _wait;
+ RLP_SetTimer(&T);
+ } else
+ RLP_SendF96Frame(RLP_FT_U_NULL, false, false, 0, 0, NULL, false);
+ }
+
+ if (rlp_user_request_get(Disc_Req)) {
+ T = -1;
+ DISC_State = _send;
+ DISC_Count = 0;
+ DISC_PBit = (Poll_xchg == _idle);
+ NextState = 5;
+ }
+
+ break;
+
+ /***** RLP State 3. *****/
+
+ case RLP_S3:
+ dprintf("RLP state 3.\n");
+
+ if (!XID_Handling(frame, header)) {
+
+ switch(CurrentFrameType) {
+
+ case RLP_FT_U_TEST:
+ TEST_Handling();
+ break;
+
+ case RLP_FT_U_DISC:
+ RLP_Passup(Disc_Ind, NULL, 0);
+ UA_State = _send;
+ UA_FBit = header->PF;
+ NextState = RLP_S1;
+ break;
+
+ default:
+ if (rlp_user_request_get(Conn_Req)) {
+ UA_State = _send;
+ UA_FBit = true;
+ NextState = RLP_S4;
+ RLP_Init_link_vars();
+ } else if (rlp_user_request_get(Conn_Req_Neg)) {
+ DM_State = _send; /* FIXME - code to handle DM_State - missing from spec? */
+ DM_FBit = true;
+ NextState = RLP_S1;
+ }
+ break;
+ }
+ }
+
+ if (!Send_TXU(frame, header)) {
+ if (UA_State == _send) {
+ RLP_SendF96Frame(RLP_FT_U_UA, false, UA_FBit, 0, 0, NULL, false);
+ UA_State = _idle;
+ } else
+ RLP_SendF96Frame(RLP_FT_U_NULL, false, false, 0, 0, NULL, false);
+ }
+
+ if (rlp_user_request_get(Disc_Req)) {
+ T = -1;
+ DISC_State = _send;
+ DISC_Count = 0;
+ DISC_PBit = (Poll_xchg == _idle);
+ NextState = 5;
+ }
+ break;
+
+ /***** RLP State 4. *****/
+
+ case RLP_S4:
+ dprintf("RLP state 4.\n");
+
+ if (!XID_Handling(frame, header)) {
+
+ switch (CurrentFrameType) {
+
+ case RLP_FT_U_TEST:
+ TEST_Handling();
+ break;
+ case RLP_FT_U_DISC:
+ T = -1;
+ ResetAllT_RCVS();
+ RLP_Passup(Disc_Ind, NULL, 0);
+ UA_State = _send;
+ UA_FBit = header->PF;
+ NextState = RLP_S1;
+ break;
+ case RLP_FT_U_SABM:
+ T = -1;
+ ResetAllT_RCVS();
+ RLP_Passup(Reset_Ind, NULL, 0);
+ NextState = RLP_S7;
+ break;
+ case RLP_FT_S_RR:
+ case RLP_FT_S_RNR:
+ case RLP_FT_S_REJ:
+ case RLP_FT_S_SREJ:
+ /* Should check here for unsolicited Fbit */
+ /* Spec says: "Nr must be within the set of not yet
+ acknowledged I-frames or it must be the next possible
+ frame number." That's VA..VS-1 or VS, i.e. VA..VS */
+ if (!InWindow(header->Nr, VA, VS))
+ break;
+ RLP_S_Handler(frame, header);
+ break;
+ case RLP_FT_SI_RR:
+ case RLP_FT_SI_RNR:
+ case RLP_FT_SI_REJ:
+ case RLP_FT_SI_SREJ:
+ /* Should check here for unsolicited Fbit */
+ if (!InWindow(header->Nr, VA, VS))
+ break;
+ if (!RLP_I_Handler(frame, header)) RLP_S_Handler(frame, header);
+ break;
+ default:
+ break;
+ }
+ }
+ for (i = 0; i < RLP_M; i++)
+ if (T_RCVS[i] == 0) {
+ rlpprintf("T_RCVS[%d] Timeout in State 4\n", i);
+ R[i].State = _srej;
+ }
+ if (T == 0) {
+ T = -1;
+ rlpprintf("T Timeout in State 4\n");
+
+ Poll_xchg = _idle;
+ if (Poll_State == _idle) {
+ Poll_State = _send;
+ Poll_Count = 0;
+ } else {
+ if (Poll_Count > RLP_N2)
+ rlpprintf("N2 Errors in State 4\n");
+ Poll_State = _send;
+ Poll_Count++;
+ }
+ }
+
+ if (!Send_TXU(frame, header)) {
+ if (UA_State == _send) {
+ RLP_SendF96Frame(RLP_FT_U_UA, false, UA_FBit, 0, 0, NULL, false);
+ UA_State = _idle;
+ } else RLP_SendData();
+ }
+
+ /* Load any data from the Send ringbuffer into the send slots */
+ RLP_AddRingBufferDataToSlots();
+
+ rlpprintf("VD=%d, VA=%d, VS=%d, VR=%d\n", VD, VA, VS, VR);
+#ifdef RLP_DEBUG_STATE
+ {
+ int zzz;
+
+ if (UA_State != _idle) rlpprintf("[UA_State %d]", UA_State);
+ if (UI_State != _idle) rlpprintf("[UI_State %d]", UI_State);
+ if (Ackn_State != _idle) rlpprintf("[Ackn_State %d]", Ackn_State);
+ if (Poll_State != _idle) rlpprintf("[Poll_State %d]", Poll_State);
+ if (Poll_xchg != _idle) rlpprintf("[Poll_xchg %d]", Poll_xchg);
+ if (SABM_State != _idle) rlpprintf("[SABM_State %d]", SABM_State);
+ if (DISC_State != _idle) rlpprintf("[DISC_State %d]", DISC_State);
+ if (DM_State != _idle) rlpprintf("[DM_State %d]", DM_State);
+ if (XI_R_State != _idle) rlpprintf("[XI_R_State %d]", XI_R_State);
+ if (XID_C_State != _idle) rlpprintf("[XID_C_State %d]", XID_C_State);
+ if (XID_R_State != _idle) rlpprintf("[XID_R_State %d]", XID_R_State);
+ if (TEST_R_State != _idle) rlpprintf("[TEST_R_State %d]", TEST_R_State);
+
+ rlpprintf("S: ");
+ for (zzz = 0; zzz < RLP_M; zzz++) rlpprintf("%d ", S[zzz].State);
+ rlpprintf("\nR: ");
+ for (zzz = 0; zzz < RLP_M; zzz++) rlpprintf("%d ", R[zzz].State);
+ rlpprintf("\nT: %d, T_RCVS: ", T);
+ for (zzz = 0; zzz < RLP_M; zzz++) rlpprintf("%d ", T_RCVS[zzz]);
+ rlpprintf("\n");
+ }
+#endif
+
+ if (rlp_user_request_get(Disc_Req)) {
+ T = -1;
+ ResetAllT_RCVS();
+ DISC_State = _send;
+ DISC_Count = 0;
+ DISC_PBit = (Poll_xchg == _idle);
+ NextState = 5;
+ }
+
+ break;
+
+ /***** RLP State 5. *****/
+
+ case RLP_S5:
+ dprintf("RLP state 5.\n");
+
+ if (!XID_Handling(frame, header)) {
+
+ switch (CurrentFrameType) {
+
+ case RLP_FT_U_UA:
+ case RLP_FT_U_DM:
+ if ((DISC_State == _wait) && (DISC_PBit == header->PF)) {
+ if (DISC_PBit == true) Poll_xchg = _idle;
+ T = -1;
+ NextState = 1;
+ }
+ break;
+ case RLP_FT_U_DISC:
+ T = -1;
+ UA_State = _send;
+ UA_FBit = header->PF;
+ NextState = 1;
+ break;
+ default:
+ break;
+ }
+ }
+
+ if (!Send_TXU(frame, header)) {
+ if ((DISC_State != _wait) && !((DISC_PBit == true) && (Poll_xchg == _wait))) {
+ RLP_SendF96Frame(RLP_FT_U_DISC, true, DISC_PBit, 0, 0, NULL, false);
+ if (DISC_PBit == true) Poll_xchg = _wait;
+ DISC_State = _wait;
+ DISC_Count++;
+ RLP_SetTimer(&T);
+ } else
+ RLP_SendF96Frame(RLP_FT_U_NULL, false, false, 0, 0, NULL, false);
+ }
+
+ if (T == 0) {
+ if (DISC_PBit == 1) Poll_xchg = _idle;
+ DISC_Count++;
+ if (DISC_Count > RLP_N2)
+ rlpprintf("N2 error in State 5!\n");
+ DISC_State = _send;
+ }
+
+ break;
+
+ /***** RLP State 6. *****/
+ /* We should only get here after a Reset_Req which is not yet supported */
+
+ case RLP_S6:
+ dprintf("RLP state 6 - not yet implemented!\n");
+
+ if (!XID_Handling(frame, header)) {
+
+ switch (CurrentFrameType) {
+ default:
+ break;
+ }
+
+ }
+
+ if (!Send_TXU(frame,header)) {
+ }
+
+ if (rlp_user_request_get(Disc_Req)) {
+ T = -1;
+ DISC_State = _send;
+ DISC_Count = 0;
+ DISC_PBit = (Poll_xchg == _idle);
+ NextState = 5;
+ }
+
+ break;
+
+ /***** RLP State 7. *****/
+
+ case RLP_S7:
+ dprintf("RLP state 7.\n");
+
+ if (!XID_Handling(frame, header)) {
+
+ switch (CurrentFrameType) {
+ case RLP_FT_U_DISC:
+ RLP_Passup(Disc_Ind, NULL, 0);
+ UA_State = _send;
+ UA_FBit = header->PF;
+ NextState = RLP_S1;
+ break;
+ default:
+ break;
+ }
+ }
+
+ if (rlp_user_request_get(Reset_Resp)) {
+ UA_State = _send;
+ UA_FBit = 1;
+ RLP_Init_link_vars();
+ NextState = RLP_S4;
+ }
+
+ if (!Send_TXU(frame, header)) {
+ RLP_SendF96Frame(RLP_FT_U_NULL, false, false, 0, 0, NULL, false);
+ }
+
+ if (rlp_user_request_get(Disc_Req)) {
+ T = -1;
+ DISC_State = _send;
+ DISC_Count = 0;
+ DISC_PBit = (Poll_xchg == _idle);
+ NextState = 5;
+ }
+ break;
+
+ default:
+ dprintf("DEBUG: Unknown RLP state!\n");
+ break;
+ }
+
+ CurrentState = NextState;
+}
+
+/* Given a pointer to an RLP XID frame, display contents in human readable
+ form. Note for now only Version 0 and 1 are supported. Fields can appear
+ in any order and are delimited by a zero type field. This function is the
+ exact implementation of section 5.2.2.6, Exchange Identification, XID of
+ the GSM specification 04.22. */
+void rlp_xid_display(u8 *frame)
+{
+ int count = 25; /* Sanity check */
+ u8 type, length;
+
+ fprintf(stdout, "XID: ");
+
+ while ((*frame != 0) && (count >= 0)) {
+ type = *frame >> 4;
+ length = *frame & 0x0f;
+
+ switch (type) {
+
+ case 0x01: /* RLP Version Number, probably 1 for Nokia. */
+ frame += length;
+ fprintf(stdout, "Ver %d ", *frame);
+ break;
+
+ case 0x02: /* IWF to MS window size */
+ frame += length;
+ fprintf(stdout, "IWF-MS %d ", *frame);
+ break;
+
+ case 0x03: /* MS to IWF window size. */
+ frame += length;
+ fprintf(stdout, "MS-IWF %d ", *frame);
+ break;
+
+ case 0x04: /* Acknowledgement Timer (T1). */
+ frame += length;
+ fprintf(stdout, "T1 %dms ", *frame * 10);
+ break;
+
+ case 0x05: /* Retransmission attempts (N2). */
+ frame += length;
+ fprintf(stdout, "N2 %d ", *frame);
+ break;
+
+ case 0x06: /* Reply delay (T2). */
+ frame += length;
+ fprintf(stdout, "T2 %dms ", *frame * 10);
+ break;
+
+ case 0x07: /* Compression. */
+ frame ++;
+ fprintf(stdout, "Comp [Pt=%d ", (*frame >> 4) );
+ fprintf(stdout, "P0=%d ", (*frame & 0x03) );
+ frame ++;
+ fprintf(stdout, "P1l=%d ", *frame);
+ frame ++;
+ fprintf(stdout, "P1h=%d ", *frame);
+ frame ++;
+ fprintf(stdout, "P2=%d] ", *frame);
+ break;
+
+ default:
+ frame += length;
+ fprintf(stdout, "Unknown! type=%02x, length=%02x", type, length);
+ break;
+ }
+ count--;
+ frame++;
+ }
+
+ fprintf(stdout, "\n");
+
+ return;
+}
+
+/* Given a pointer to an F9.6 Frame, split data out into component parts of
+ header and determine frame type. */
+void rlp_f96_header_decode(gn_rlp_f96_frame *frame, rlp_f96_header *header)
+{
+ /* Poll/Final bit. */
+ if ((frame->Header[1] & 0x02))
+ header->PF = true;
+ else
+ header->PF = false;
+
+ /* Command/Response bit. */
+ if ((frame->Header[0] & 0x01))
+ header->CR = true;
+ else
+ header->CR = false;
+
+ /* Send Sequence Number. */
+ header->Ns = frame->Header[0] >> 3;
+
+ if ((frame->Header[1] & 0x01))
+ header->Ns |= 0x20; /* Most significant bit. */
+
+ /* Determine frame type. See the section 5.2.1 in the GSM 04.22
+ specification. */
+ switch (header->Ns) {
+
+ case 0x3f: /* Frames of type U, unnumbered frames. */
+ /* U frames have M1, ..., M5 stored in the place of N(R). */
+ header->Type = RLP_FT_U;
+ header->M = (frame->Header[1] >> 2) & 0x1f;
+ return; /* For U frames, we do not need N(R) and bits S1 and S2. */
+
+ case 0x3e: /* Frames of type S, supervisory frames. */
+ header->Type = RLP_FT_S;
+ break;
+
+ default: /* Frames of type I+S, numbered information transfer ans
+ supervisory frames combined. */
+ header->Type = RLP_FT_IS;
+ break;
+ }
+
+ /* Receive Sequence Number N(R). */
+ header->Nr = frame->Header[1] >> 2;
+
+ /* Status bits (S1 and S2). */
+ header->S = (frame->Header[0] >> 1) & 0x03;
+
+ return;
+}
Added: trunk/src/host/qemu-neo1973/gnokiigsm/rlp-common.h
===================================================================
--- trunk/src/host/qemu-neo1973/gnokiigsm/rlp-common.h 2007-05-16 22:38:21 UTC (rev 1986)
+++ trunk/src/host/qemu-neo1973/gnokiigsm/rlp-common.h 2007-05-17 00:24:48 UTC (rev 1987)
@@ -0,0 +1,176 @@
+/*
+
+ $Id: rlp-common.h,v 1.12 2005/04/24 19:41:23 pkot Exp $
+
+ G N O K I I
+
+ A Linux/Unix toolset and driver for the mobile phones.
+
+ This file is part of gnokii.
+
+ Gnokii 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.
+
+ Gnokii 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 gnokii; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+ Copyright (C) 1999-2000 Hugh Blemings & Pavel Janík ml.
+ Copyright (C) 2001 Chris Kemp, Pavel Machek
+ Copyright (C) 2003 Pawel Kot
+
+ The development of RLP protocol was sponsored by SuSE CR, s.r.o. (Pavel use
+ the SIM card from SuSE for testing purposes).
+
+ Header file for RLP protocol.
+
+*/
+
+#ifndef _gnokii_rlp_common_h
+#define _gnokii_rlp_common_h
+
+/* Typedef for frame type - they are the same for RLP version 0, 1 and 2. */
+typedef enum {
+ RLP_FT_X, /* Unknown. */
+ RLP_FT_U, /* Unnumbered frame. */
+ RLP_FT_S, /* Supervisory frame. */
+ RLP_FT_IS /* Information plus Supervisory (I+S) frame. */
+} rlp_frame_type;
+
+/* Define the various Unnumbered frame types. Numbering is bit reversed
+ relative to ETSI GSM 04.22 for easy parsing. */
+typedef enum {
+ RLP_U_SABM = 0x07, /* Set Asynchronous Balanced Mode. */
+ RLP_U_UA = 0x0c, /* Unnumbered Acknowledge. */
+ RLP_U_DISC = 0x08, /* Disconnect. */
+ RLP_U_DM = 0x03, /* Disconnected Mode. */
+ RLP_U_NULL = 0x0f, /* Null information. */
+ RLP_U_UI = 0x00, /* Unnumbered Information. */
+ RLP_U_XID = 0x17, /* Exchange Identification. */
+ RLP_U_TEST = 0x1c, /* Test. */
+ RLP_U_REMAP = 0x11 /* Remap. */
+} rlp_uframe_type;
+
+/* Define supervisory frame field. */
+typedef enum {
+ RLP_S_RR = 0x00, /* Receive Ready. */
+ RLP_S_REJ = 0x02, /* Reject. */
+ RLP_S_RNR = 0x01, /* Receive Not Ready. */
+ RLP_S_SREJ = 0x03 /* Selective Reject. */
+} rlp_sframe_field;
+
+/* Used for CurrentFrameType. */
+typedef enum {
+ RLP_FT_U_SABM = 0x00,
+ RLP_FT_U_UA,
+ RLP_FT_U_DISC,
+ RLP_FT_U_DM,
+ RLP_FT_U_NULL,
+ RLP_FT_U_UI,
+ RLP_FT_U_XID,
+ RLP_FT_U_TEST,
+ RLP_FT_U_REMAP,
+ RLP_FT_S_RR,
+ RLP_FT_S_REJ,
+ RLP_FT_S_RNR,
+ RLP_FT_S_SREJ,
+ RLP_FT_SI_RR,
+ RLP_FT_SI_REJ,
+ RLP_FT_SI_RNR,
+ RLP_FT_SI_SREJ,
+ RLP_FT_BAD
+} rlp_frame_types;
+
+/* Frame definition for TCH/F9.6 frame. */
+typedef struct {
+ unsigned char Header[2];
+ unsigned char Data[25];
+ unsigned char FCS[3];
+} gn_rlp_f96_frame;
+
+/* Header data "split up" for TCH/F9.6 frame. */
+typedef struct {
+ unsigned char Ns; /* Send sequence number. */
+ unsigned char Nr; /* Receive sequence number. */
+ unsigned char M; /* Unumbered frame type. */
+ unsigned char S; /* Status. */
+ int PF; /* Poll/Final. */
+ int CR; /* Command/Response. */
+ rlp_frame_type Type; /* Frame type. */
+} rlp_f96_header;
+
+
+/* RLP User requests */
+typedef struct {
+ int Conn_Req;
+ int Attach_Req;
+ int Conn_Req_Neg;
+ int Reset_Resp;
+ int Disc_Req;
+} rlp_user_request_store;
+
+typedef enum {
+ Conn_Req,
+ Attach_Req,
+ Conn_Req_Neg,
+ Reset_Resp,
+ Disc_Req
+} rlp_user_requests;
+
+typedef enum {
+ Conn_Ind,
+ Conn_Conf,
+ Disc_Ind,
+ Reset_Ind,
+ Data, /* FIXME: This should really be called RLP_Data, otherwise it hogs name "Data"! */
+ StatusChange,
+ GetData
+} rlp_user_inds;
+
+/* RLP (main) states. See GSM specification 04.22 Annex A, Section A.1.1. */
+typedef enum {
+ RLP_S0, /* ADM and Detached */
+ RLP_S1, /* ADM and Attached */
+ RLP_S2, /* Pending Connect Request */
+ RLP_S3, /* Pending Connect Indication */
+ RLP_S4, /* ABM and Connection Established */
+ RLP_S5, /* Disconnect Initiated */
+ RLP_S6, /* Pending Reset Request */
+ RLP_S7, /* Pending Reset Indication */
+ RLP_S8 /* Error */
+} rlp_state;
+
+/* RLP specification defines several states in which variables can be. */
+typedef enum {
+ _idle=0,
+ _send,
+ _wait,
+ _rcvd,
+ _ackn,
+ _rej,
+ _srej
+} rlp_state_variable;
+
+/* RLP Data */
+typedef struct {
+ unsigned char Data[25];
+ rlp_state_variable State;
+} rlp_data;
+
+/* Prototypes for functions. */
+void rlp_f96_frame_display(gn_rlp_f96_frame *frame);
+void rlp_f96_header_decode(gn_rlp_f96_frame *frame, rlp_f96_header *header);
+void rlp_xid_display(unsigned char *frame);
+void rlp_initialise(int (*rlp_send_function)(gn_rlp_f96_frame *frame, int out_dtx), int (*rlp_passup)(rlp_user_inds ind, unsigned char *buffer, int length));
+void rlp_link_vars_init(void);
+void rlp_user_request_set(rlp_user_requests type, int value);
+void rlp_send(char *buffer, int length);
+
+#endif /* _gnokii_rlp_common_h */
Added: trunk/src/host/qemu-neo1973/gnokiigsm/rlp-crc24.c
===================================================================
--- trunk/src/host/qemu-neo1973/gnokiigsm/rlp-crc24.c 2007-05-16 22:38:21 UTC (rev 1986)
+++ trunk/src/host/qemu-neo1973/gnokiigsm/rlp-crc24.c 2007-05-17 00:24:48 UTC (rev 1987)
@@ -0,0 +1,124 @@
+/*
+
+ $Id: rlp-crc24.c,v 1.7 2005/04/20 20:30:18 pkot Exp $
+
+ G N O K I I
+
+ A Linux/Unix toolset and driver for the mobile phones.
+
+ This file is part of gnokii.
+
+ Gnokii 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.
+
+ Gnokii 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 gnokii; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+ Copyright (C) 1999-2000 Hugh Blemings & Pavel Janík ml.
+ Copyright (C) 2001-2004 Pawel Kot
+ Copyright (C) 2002-2004 BORBELY Zoltan
+
+ CRC24 (aka FCS) implementation in RLP.
+
+*/
+
+#include "rlp-crc24.h"
+
+/* CRC-24 table is used for computation of RLP checksum. */
+
+const u32 CRC24_Table[256] = {
+ 0x00000000, 0x00D6A776, 0x00F64557, 0x0020E221, 0x00B78115, 0x00612663,
+ 0x0041C442, 0x00976334, 0x00340991, 0x00E2AEE7, 0x00C24CC6, 0x0014EBB0,
+ 0x00838884, 0x00552FF2, 0x0075CDD3, 0x00A36AA5, 0x00681322, 0x00BEB454,
+ 0x009E5675, 0x0048F103, 0x00DF9237, 0x00093541, 0x0029D760, 0x00FF7016,
+ 0x005C1AB3, 0x008ABDC5, 0x00AA5FE4, 0x007CF892, 0x00EB9BA6, 0x003D3CD0,
+ 0x001DDEF1, 0x00CB7987, 0x00D02644, 0x00068132, 0x00266313, 0x00F0C465,
+ 0x0067A751, 0x00B10027, 0x0091E206, 0x00474570, 0x00E42FD5, 0x003288A3,
+ 0x00126A82, 0x00C4CDF4, 0x0053AEC0, 0x008509B6, 0x00A5EB97, 0x00734CE1,
+ 0x00B83566, 0x006E9210, 0x004E7031, 0x0098D747, 0x000FB473, 0x00D91305,
+ 0x00F9F124, 0x002F5652, 0x008C3CF7, 0x005A9B81, 0x007A79A0, 0x00ACDED6,
+ 0x003BBDE2, 0x00ED1A94, 0x00CDF8B5, 0x001B5FC3, 0x00FB4733, 0x002DE045,
+ 0x000D0264, 0x00DBA512, 0x004CC626, 0x009A6150, 0x00BA8371, 0x006C2407,
+ 0x00CF4EA2, 0x0019E9D4, 0x00390BF5, 0x00EFAC83, 0x0078CFB7, 0x00AE68C1,
+ 0x008E8AE0, 0x00582D96, 0x00935411, 0x0045F367, 0x00651146, 0x00B3B630,
+ 0x0024D504, 0x00F27272, 0x00D29053, 0x00043725, 0x00A75D80, 0x0071FAF6,
+ 0x005118D7, 0x0087BFA1, 0x0010DC95, 0x00C67BE3, 0x00E699C2, 0x00303EB4,
+ 0x002B6177, 0x00FDC601, 0x00DD2420, 0x000B8356, 0x009CE062, 0x004A4714,
+ 0x006AA535, 0x00BC0243, 0x001F68E6, 0x00C9CF90, 0x00E92DB1, 0x003F8AC7,
+ 0x00A8E9F3, 0x007E4E85, 0x005EACA4, 0x00880BD2, 0x00437255, 0x0095D523,
+ 0x00B53702, 0x00639074, 0x00F4F340, 0x00225436, 0x0002B617, 0x00D41161,
+ 0x00777BC4, 0x00A1DCB2, 0x00813E93, 0x005799E5, 0x00C0FAD1, 0x00165DA7,
+ 0x0036BF86, 0x00E018F0, 0x00AD85DD, 0x007B22AB, 0x005BC08A, 0x008D67FC,
+ 0x001A04C8, 0x00CCA3BE, 0x00EC419F, 0x003AE6E9, 0x00998C4C, 0x004F2B3A,
+ 0x006FC91B, 0x00B96E6D, 0x002E0D59, 0x00F8AA2F, 0x00D8480E, 0x000EEF78,
+ 0x00C596FF, 0x00133189, 0x0033D3A8, 0x00E574DE, 0x007217EA, 0x00A4B09C,
+ 0x008452BD, 0x0052F5CB, 0x00F19F6E, 0x00273818, 0x0007DA39, 0x00D17D4F,
+ 0x00461E7B, 0x0090B90D, 0x00B05B2C, 0x0066FC5A, 0x007DA399, 0x00AB04EF,
+ 0x008BE6CE, 0x005D41B8, 0x00CA228C, 0x001C85FA, 0x003C67DB, 0x00EAC0AD,
+ 0x0049AA08, 0x009F0D7E, 0x00BFEF5F, 0x00694829, 0x00FE2B1D, 0x00288C6B,
+ 0x00086E4A, 0x00DEC93C, 0x0015B0BB, 0x00C317CD, 0x00E3F5EC, 0x0035529A,
+ 0x00A231AE, 0x007496D8, 0x005474F9, 0x0082D38F, 0x0021B92A, 0x00F71E5C,
+ 0x00D7FC7D, 0x00015B0B, 0x0096383F, 0x00409F49, 0x00607D68, 0x00B6DA1E,
+ 0x0056C2EE, 0x00806598, 0x00A087B9, 0x007620CF, 0x00E143FB, 0x0037E48D,
+ 0x001706AC, 0x00C1A1DA, 0x0062CB7F, 0x00B46C09, 0x00948E28, 0x0042295E,
+ 0x00D54A6A, 0x0003ED1C, 0x00230F3D, 0x00F5A84B, 0x003ED1CC, 0x00E876BA,
+ 0x00C8949B, 0x001E33ED, 0x008950D9, 0x005FF7AF, 0x007F158E, 0x00A9B2F8,
+ 0x000AD85D, 0x00DC7F2B, 0x00FC9D0A, 0x002A3A7C, 0x00BD5948, 0x006BFE3E,
+ 0x004B1C1F, 0x009DBB69, 0x0086E4AA, 0x005043DC, 0x0070A1FD, 0x00A6068B,
+ 0x003165BF, 0x00E7C2C9, 0x00C720E8, 0x0011879E, 0x00B2ED3B, 0x00644A4D,
+ 0x0044A86C, 0x00920F1A, 0x00056C2E, 0x00D3CB58, 0x00F32979, 0x00258E0F,
+ 0x00EEF788, 0x003850FE, 0x0018B2DF, 0x00CE15A9, 0x0059769D, 0x008FD1EB,
+ 0x00AF33CA, 0x007994BC, 0x00DAFE19, 0x000C596F, 0x002CBB4E, 0x00FA1C38,
+ 0x006D7F0C, 0x00BBD87A, 0x009B3A5B, 0x004D9D2D
+};
+
+void rlp_crc24polinomial_calculate(u8 *data, int length, u32 *polinomial)
+{
+
+ int i;
+ u8 cur;
+
+ *polinomial = 0x00ffffff;
+
+ for (i = 0; i < length; i++) {
+ cur = (*polinomial & 0x0000ffff) ^ data[i];
+ *polinomial = (*polinomial >> 8) ^ CRC24_Table[cur];
+ }
+
+ *polinomial = ((~*polinomial) & 0x00ffffff);
+}
+
+
+void rlp_crc24checksum_calculate(u8 *data, int length, u8 *crc)
+{
+ u32 polinomial;
+
+ rlp_crc24polinomial_calculate(data, length, &polinomial);
+ crc[0] = polinomial & 0x0000ffff;
+ crc[1] = (polinomial >> 8) & 0x0000ffff;
+ crc[2] = (polinomial >> 16) & 0x0000ffff;
+
+}
+
+bool rlp_crc24fcs_check(u8 *data, int length)
+{
+
+ u8 crc[] = { 0x00, 0x00, 0x00 };
+
+ rlp_crc24checksum_calculate(data, length - 3, crc);
+
+ if (((data[length - 3] == crc[0]) &&
+ (data[length - 2] == crc[1]) &&
+ (data[length - 1] == crc[2]))) {
+ return (true);
+ }
+ return (false);
+}
Added: trunk/src/host/qemu-neo1973/gnokiigsm/rlp-crc24.h
===================================================================
--- trunk/src/host/qemu-neo1973/gnokiigsm/rlp-crc24.h 2007-05-16 22:38:21 UTC (rev 1986)
+++ trunk/src/host/qemu-neo1973/gnokiigsm/rlp-crc24.h 2007-05-17 00:24:48 UTC (rev 1987)
@@ -0,0 +1,40 @@
+/*
+
+ $Id: rlp-crc24.h,v 1.5 2002/12/10 23:27:19 pkot Exp $
+
+ G N O K I I
+
+ A Linux/Unix toolset and driver for Nokia mobile phones.
+
+ This file is part of gnokii.
+
+ Gnokii 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.
+
+ Gnokii 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 gnokii; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+ Copyright (C) 1999, 2000 Hugh Blemings & Pavel Janík ml.
+
+ Header file for CRC24 (aka FCS) implementation in RLP.
+
+*/
+
+#ifndef _gnokii_data_rlp_crc24_h
+#define _gnokii_data_rlp_crc24_h
+
+#include "misc.h"
+
+/* Prototypes for functions */
+void rlp_crc24checksum_calculate(u8 *data, int length, u8 *crc);
+bool rlp_crc24fcs_check(u8 *data, int length);
+
+#endif
Added: trunk/src/host/qemu-neo1973/gnokiigsm/sms.h
===================================================================
--- trunk/src/host/qemu-neo1973/gnokiigsm/sms.h 2007-05-16 22:38:21 UTC (rev 1986)
+++ trunk/src/host/qemu-neo1973/gnokiigsm/sms.h 2007-05-17 00:24:48 UTC (rev 1987)
@@ -0,0 +1,488 @@
+/*
+
+ $Id: sms.h,v 1.67 2006/11/08 19:45:37 dforsi Exp $
+
+ G N O K I I
+
+ A Linux/Unix toolset and driver for the mobile phones.
+
+ This file is part of gnokii.
+
+ Gnokii 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.
+
+ Gnokii 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 gnokii; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+ Copyright (C) 1999-2000 Hugh Blemings, Pavel Janik
+ Copyright (C) 2001-2003 Pawel Kot
+ Copyright (C) 2002 Pavel Machek, Markus Plail, BORBELY Zoltan
+ Copyright (C) 2003 Ladis Michl
+
+ Include file for the SMS library.
+
+*/
+
+#ifndef _gnokii_sms_h
+#define _gnokii_sms_h
+
+#include <error.h>
+#include <common.h>
+#include <bitmaps.h>
+#include <ringtones.h>
+#include <encoding.h>
+
+/* Maximum length of SMS center name */
+#define GN_SMS_CENTER_NAME_MAX_LENGTH 20
+
+/* Limits of SMS messages. */
+#define GN_SMS_MAX_LENGTH 160
+#define GN_SMS_8BIT_MAX_LENGTH 140
+#define GN_SMS_LONG_MAX_LENGTH 10240
+
+#define GN_SMS_PART_MAX_NUMBER 3
+
+/* FIXME: what value should be here? (Pawel Kot) */
+#define GN_SMS_UDH_MAX_NUMBER 10
+
+/* Maximal number of SMS folders */
+#define GN_SMS_FOLDER_MAX_NUMBER 24
+#define GN_SMS_MESSAGE_MAX_NUMBER 190
+
+#define GN_SMS_DATETIME_MAX_LENGTH 7
+#define GN_SMS_SMSC_NUMBER_MAX_LENGTH 20
+#define GN_SMS_NUMBER_MAX_LENGTH 20
+#define GN_SMS_USER_DATA_MAX_LENGTH 512
+#define GN_SMS_VP_MAX_LENGTH 8
+
+/*** MEMORY INFO ***/
+typedef struct {
+ int Unread; /* Number of unread messages */
+ int Number; /* Number of all messages */
+} gn_sms_memory_status;
+
+typedef struct {
+ /* Number of message we get from GetSMSStatus */
+ unsigned int number;
+ /* Number of unread messages we get from GetSMSStatus */
+ unsigned int unread;
+ /* when a message is moved between folders status wouldn't change */
+ unsigned int changed;
+ /* Number of Folders we get from GetFolders */
+ unsigned int folders_count;
+ /* Message store used for new received messages (this is used
+ * internally by AT_SetSMSMemoryType() in common/phones/atgen.c). */
+ gn_memory_type new_message_store;
+} gn_sms_status;
+
+
+/*** USER DATA HEADER ***/
+/* types of User Data Header */
+typedef enum {
+ GN_SMS_UDH_None = 0x00,
+ GN_SMS_UDH_ConcatenatedMessages = 0x01,
+ GN_SMS_UDH_Ringtone = 0x02,
+ GN_SMS_UDH_OpLogo = 0x03,
+ GN_SMS_UDH_CallerIDLogo = 0x04,
+ GN_SMS_UDH_MultipartMessage = 0x05,
+ GN_SMS_UDH_WAPvCard = 0x06,
+ GN_SMS_UDH_WAPvCalendar = 0x07,
+ GN_SMS_UDH_WAPvCardSecure = 0x08,
+ GN_SMS_UDH_WAPvCalendarSecure = 0x09,
+ GN_SMS_UDH_VoiceMessage = 0x0a,
+ GN_SMS_UDH_FaxMessage = 0x0b,
+ GN_SMS_UDH_EmailMessage = 0x0c,
+ GN_SMS_UDH_WAPPush = 0x0d,
+ GN_SMS_UDH_OtherMessage = 0x0e,
+ GN_SMS_UDH_Unknown = 0x0f
+} gn_sms_udh_type;
+
+typedef struct {
+ gn_sms_udh_type type;
+ union {
+ struct {
+ unsigned short reference_number;
+ unsigned short maximum_number;
+ unsigned short current_number;
+ } concatenated_short_message; /* SMS_ConcatenatedMessages */
+ struct {
+ int store;
+ unsigned short message_count;
+ } special_sms_message_indication; /* GN_SMS_VoiceMessage, GN_SMS_FaxMessage,
+ GN_SMS_EmailMessage, GN_SMS_OtherMessage */
+ struct {
+ char network_code[6];
+ unsigned int width, height;
+ } logo; /* GN_SMS_OpLogo, GN_SMS_CallerIDLogo */
+ struct {
+ unsigned int notes; /* Number of the notes */
+ } ringtone; /* GN_SMS_Ringtone */
+ } u;
+} gn_sms_udh_info;
+
+typedef struct {
+ unsigned int number; /* Number of the present UDH */
+ unsigned int length;
+ gn_sms_udh_info udh[GN_SMS_UDH_MAX_NUMBER];
+} gn_sms_udh;
+
+typedef enum {
+ GN_SMS_MW_PID, /* Set Protocol Identifier to `Return Call Message' */
+ GN_SMS_MW_DCS, /* Set Data Coding Scheme "to indicate the type of
+ * message waiting and whether there are some messages
+ * or no messages" */
+ GN_SMS_MW_UDH /* Use User Data Header - Special SMS Message
+ * Indication; the maximium level of information,
+ * may not be supported by all phones */
+} gn_sms_message_waiting_type;
+
+/*** DATA CODING SCHEME ***/
+typedef enum {
+ GN_SMS_DCS_GeneralDataCoding,
+ GN_SMS_DCS_MessageWaiting
+} gn_sms_dcs_type;
+
+typedef enum {
+ GN_SMS_DCS_DefaultAlphabet = 0x00,
+ GN_SMS_DCS_8bit = 0x01,
+ GN_SMS_DCS_UCS2 = 0x02
+} gn_sms_dcs_alphabet_type;
+
+typedef enum {
+ GN_SMS_DCS_VoiceMail = 0x00,
+ GN_SMS_DCS_Fax = 0x01,
+ GN_SMS_DCS_Email = 0x02,
+ GN_SMS_DCS_Text = 0x03,
+ GN_SMS_DCS_Other = 0x04
+} gn_sms_dcs_indication_type;
+
+typedef struct {
+ gn_sms_dcs_type type;
+ union {
+ struct {
+ /* Message class:
+ * 0 - no class
+ * 1 - Class 0
+ * 2 - Class 1
+ * 3 - Class 2
+ * 4 - Class 3 */
+ unsigned short m_class;
+ int compressed;
+ gn_sms_dcs_alphabet_type alphabet;
+ } general;
+ struct {
+ int discard;
+ gn_sms_dcs_alphabet_type alphabet; /* ucs16 not supported */
+ int active;
+ gn_sms_dcs_indication_type type;
+ } message_waiting;
+ } u;
+} gn_sms_dcs;
+
+/*** VALIDITY PERIOD ***/
+typedef enum {
+ GN_SMS_VP_None = 0x00,
+ GN_SMS_VP_EnhancedFormat = 0x01,
+ GN_SMS_VP_RelativeFormat = 0x02,
+ GN_SMS_VP_AbsoluteFormat = 0x03
+} gn_sms_vp_format;
+
+typedef enum {
+ GN_SMS_VPE_None = 0x00,
+ GN_SMS_VPE_RelativeFormat = 0x01,
+ GN_SMS_VPE_RelativeSeconds = 0x02, /* Only one octet more is used */
+ GN_SMS_VPE_RelativeSemiOctet = 0x03 /* 3 octets contain relative time in hours, minutes and seconds in semi-octet representation */
+} gn_sms_vp_enhanced_type;
+
+typedef struct {
+ int extension; /* we need to set it to 0 at the moment; FIXME: how to handle `1' here? */
+ int single_shot;
+ gn_sms_vp_enhanced_type type;
+ union {
+ unsigned short relative;
+ unsigned short seconds;
+ gn_timestamp hms;
+ } period;
+} gn_sms_vp_enhanced;
+
+/* Validity of SMS Messages. */
+typedef enum {
+ GN_SMS_VP_1H = 0x0b,
+ GN_SMS_VP_6H = 0x47,
+ GN_SMS_VP_24H = 0xa7,
+ GN_SMS_VP_72H = 0xa9,
+ GN_SMS_VP_1W = 0xad,
+ GN_SMS_VP_Max = 0xff
+} gn_sms_vp_time;
+
+typedef struct {
+ gn_sms_vp_format vpf;
+ union {
+ gn_sms_vp_enhanced enhanced;
+ gn_sms_vp_time relative; /* 8 bit */
+ gn_timestamp absolute;
+ } u;
+} gn_sms_vp;
+
+
+/*** MESSAGE CENTER ***/
+
+typedef enum {
+ GN_SMS_MF_Text = 0x00, /* Plain text message. */
+ GN_SMS_MF_Fax = 0x22, /* Fax message. */
+ GN_SMS_MF_Voice = 0x24, /* Voice mail message. */
+ GN_SMS_MF_ERMES = 0x25, /* ERMES message. */
+ GN_SMS_MF_Paging = 0x26, /* Paging. */
+ GN_SMS_MF_UCI = 0x2d, /* Email message in 8110i. */
+ GN_SMS_MF_Email = 0x32, /* Email message. */
+ GN_SMS_MF_X400 = 0x31 /* X.400 message. */
+} gn_sms_message_format;
+
+typedef struct {
+ int id; /* Number of the SMSC in the phone memory. */
+ char name[GN_SMS_CENTER_NAME_MAX_LENGTH]; /* Name of the SMSC. */
+ int default_name; /* >= 1 if default name used, otherwise -1 */
+ gn_sms_message_format format; /* SMS is sent as text/fax/paging/email. */
+ gn_sms_vp_time validity; /* Validity of SMS Message. */
+ gn_gsm_number smsc; /* Number of the SMSC. */
+ gn_gsm_number recipient; /* Number of the default recipient. */
+} gn_sms_message_center;
+
+/*** SHORT MESSAGE CORE ***/
+
+typedef enum {
+ /* First 2 digits are taken from GSM 03.40 version 6.1.0 Release 1997
+ * Section 9.2.3.1; 3rd digit is to mark a report. */
+ GN_SMS_MT_Deliver = 0x00, /* 00 0 */
+ GN_SMS_MT_DeliveryReport = 0x01, /* 00 1 */
+ GN_SMS_MT_Submit = 0x02, /* 01 0 */
+ GN_SMS_MT_SubmitReport = 0x03, /* 01 1 */
+ GN_SMS_MT_Command = 0x04, /* 10 0 */
+ GN_SMS_MT_StatusReport = 0x05, /* 10 1 */
+ /* Looks like Happy N*kia Engineers invention. Text, picture, outbox
+ * sent templates are needed for Nokia 6510 and family. */
+ GN_SMS_MT_Picture = 0x07,
+ GN_SMS_MT_TextTemplate = 0x08,
+ GN_SMS_MT_PictureTemplate = 0x09,
+ GN_SMS_MT_SubmitSent = 0x0a
+} gn_sms_message_type;
+
+typedef enum {
+ GN_SMS_CT_Enquiry = 0x00, /* Enquiry relating to previosly
+ submitted short message; sets
+ SRR to 1 */
+ GN_SMS_CT_CancelStatusReport = 0x01, /* Cancel Status Report Request
+ relating to previously submitted
+ short message; sets SRR to 0 */
+ GN_SMS_CT_DeleteSM = 0x02, /* Delete previously submitted
+ Short Message; sets SRR to 0 */
+ GN_SMS_CT_EnableStatusReport = 0x03 /* Enable Status Report Request
+ relating to previously submitted
+ short message; sets SRR to 0 */
+} gn_sms_command_type;
+
+typedef struct {
+ gn_sms_command_type type;
+} gn_sms_message_command;
+
+/* Datatype for SMS status */
+typedef enum {
+ GN_SMS_Read = 0x01,
+ GN_SMS_Unread = 0x03,
+ GN_SMS_Sent = 0x05,
+ GN_SMS_Unsent = 0x07
+} gn_sms_message_status;
+
+typedef enum {
+ GN_SMS_DATA_None = 0x00,
+ GN_SMS_DATA_Text = 0x01,
+ GN_SMS_DATA_Bitmap = 0x02,
+ GN_SMS_DATA_Ringtone = 0x03,
+ GN_SMS_DATA_iMelody = 0x04,
+ GN_SMS_DATA_Multi = 0x05,
+ GN_SMS_DATA_NokiaText = 0x06,
+ GN_SMS_DATA_Animation = 0x07,
+ GN_SMS_DATA_Concat = 0x08,
+ GN_SMS_DATA_WAPPush = 0x09,
+ GN_SMS_DATA_Other = 0x0a
+} gn_sms_data_type;
+
+/*** FOLDER INFO ***/
+
+typedef enum {
+ GN_SMS_FLD_Old = 0x00,
+ GN_SMS_FLD_New = 0x01,
+ GN_SMS_FLD_Deleted = 0x02,
+ GN_SMS_FLD_ToBeRemoved = 0x03,
+ GN_SMS_FLD_NotRead = 0x04,
+ GN_SMS_FLD_NotReadHandled = 0x05,
+ GN_SMS_FLD_Changed = 0x06
+} gn_sms_location_status;
+
+typedef struct {
+ gn_sms_location_status status; /* deleted, new, old, ToBeRemoved */
+ unsigned int location;
+ gn_sms_message_type message_type;
+} gn_sms_message_list;
+
+typedef struct {
+ int number; /* -1 if folder is not supported by the phone */
+ unsigned int unread; /* only valid for INBOX */
+ unsigned int changed;
+ unsigned int used; /* because 'Used' can vary from 'Number' when we have deleted messages */
+} gn_sms_folder_stats;
+
+typedef struct {
+ unsigned char binary[GN_SMS_MAX_LENGTH];
+ int curr, total; /* Number of this part, total number of parts */
+} gn_sms_multi;
+
+typedef struct {
+ int curr, total, serial;
+} gn_sms_concat;
+
+typedef struct {
+ gn_sms_data_type type;
+ unsigned int length;
+ union {
+ unsigned char text[10 * GN_SMS_MAX_LENGTH + 1];
+ gn_sms_multi multi;
+ gn_bmp bitmap;
+ gn_ringtone ringtone;
+ gn_bmp animation[4];
+ gn_sms_concat concat;
+ } u;
+} gn_sms_user_data;
+
+/* Define datatype for SMS messages exported to the user applications. */
+typedef struct {
+ /* General fields */
+ gn_sms_message_type type; /* Type of the message. */
+ int delivery_report; /* Do we request the delivery report? Only for setting. */
+ gn_sms_message_status status; /* Status of the message read/unread/sent/unsent. */
+ unsigned int validity; /* Message validity in minutes. Only for setting. */
+ gn_memory_type memory_type ; /* Memory type where the message is/should be stored. */
+ unsigned int number; /* Location of the message in the memory/folder. */
+
+ /* Number related fields */
+ gn_gsm_number smsc; /* SMSC Number. */
+ gn_gsm_number remote; /* Remote (sender/recipient) number. */
+
+ /* Data format fields */
+ gn_sms_dcs dcs;
+ gn_sms_user_data user_data[GN_SMS_PART_MAX_NUMBER];
+ gn_sms_udh udh;
+
+ /* Date fields */
+ gn_timestamp smsc_time; /* SMSC Timestamp. Only for reading. */
+ gn_timestamp time; /* Delivery timestamp. Only for reading. */
+} gn_sms;
+
+/* Define datatype for SMS messages, describes precisely GSM Spec 03.40 */
+typedef struct {
+ unsigned int type; /* Message Type Indicator - 2 bits (9.2.3.1) */
+ int more_messages; /* More Messages to Send (9.2.3.2) */
+ int reply_via_same_smsc; /* Reply Path (9.2.3.17) - `Reply via same centre' in the phone */
+ int reject_duplicates; /* Reject Duplicates (9.2.3.25) */
+ int report; /* Status Report (9.2.3.4, 9.2.3.5 & 9.2.3.26) - `Delivery reports' in the phone */
+
+ unsigned int number; /* Message Number - 8 bits (9.2.3.18) */
+ unsigned int reference; /* Message Reference - 8 bit (9.2.3.6) */
+ unsigned int pid; /* Protocol Identifier - 8 bit (9.2.3.9) */
+ unsigned int report_status; /* Status - 8 bit (9.2.3.15), Failure Cause (9.2.3.22) */
+
+ unsigned char smsc_time[GN_SMS_DATETIME_MAX_LENGTH]; /* Service Centre Time Stamp (9.2.3.11) */
+ unsigned char time[GN_SMS_DATETIME_MAX_LENGTH]; /* Discharge Time (9.2.3.13) */
+ unsigned char message_center[GN_SMS_SMSC_NUMBER_MAX_LENGTH];/* SMSC Address (9.2.3.7, 9.2.3.8, 9.2.3.14) */
+ unsigned char remote_number[GN_SMS_NUMBER_MAX_LENGTH]; /* Origination, destination, Recipient Address (9.2.3.7, 9.2.3.8, 9.2.3.14) */
+
+ unsigned int dcs; /* Data Coding Scheme (9.2.3.10) */
+ unsigned int length; /* User Data Length (9.2.3.16), Command Data Length (9.2.3.20) */
+ int udh_indicator;
+ unsigned char user_data[GN_SMS_LONG_MAX_LENGTH]; /* User Data (9.2.3.24), Command Data (9.2.3.21), extended to Nokia Multipart Messages from Smart Messaging Specification 3.0.0 */
+ int user_data_length; /* Length of just previous field */
+
+ gn_sms_vp_format validity_indicator;
+ unsigned char validity[GN_SMS_VP_MAX_LENGTH]; /* Validity Period Format & Validity Period (9.2.3.3 & 9.2.3.12) - `Message validity' in the phone */
+
+ /* Other fields */
+ unsigned int memory_type; /* MemoryType (for 6210/7110): folder indicator */
+ unsigned int status; /* Status of the message: sent/read or unsent/unread */
+} gn_sms_raw;
+
+
+/*** FOLDERS ***/
+
+/*** Datatype for SMS folders in 6210/7110 ***/
+/* Max name length is 15 characters and trailing \0 */
+#define GN_SMS_FOLDER_NAME_MAX_LENGTH 16
+typedef struct {
+ /* Name for SMS folder. */
+ char name[GN_SMS_FOLDER_NAME_MAX_LENGTH];
+ /* if folder contains sender, SMSC number and sending date */
+ int sms_data;
+ /* locations of SMS messages in that folder (6210 specific) */
+ unsigned int locations[GN_SMS_MESSAGE_MAX_NUMBER];
+ /* number of SMS messages in that folder*/
+ unsigned int number;
+ /* ID od fthe current folder */
+ unsigned int folder_id;
+} gn_sms_folder;
+
+typedef struct {
+ gn_sms_folder folder[GN_SMS_FOLDER_MAX_NUMBER];
+ /* ID specific for this folder and phone. Used in internal functions.
+ * Do not use it. */
+ unsigned int folder_id[GN_SMS_FOLDER_MAX_NUMBER];
+ /* number of SMS folders */
+ unsigned int number;
+} gn_sms_folder_list;
+
+/*** CELL BROADCAST ***/
+
+#define GN_CM_MESSAGE_MAX_LENGTH 160
+
+/* Define datatype for Cell Broadcast message */
+typedef struct {
+ int channel;
+ char message[GN_CM_MESSAGE_MAX_LENGTH + 1];
+ int is_new;
+} gn_cb_message;
+
+GNOKII_API void gn_sms_default_submit(gn_sms *sms);
+GNOKII_API void gn_sms_default_deliver(gn_sms *sms);
+
+/* WAPPush */
+
+typedef struct {
+ unsigned char wsp_tid;
+ unsigned char wsp_pdu;
+ unsigned char wsp_hlen;
+ unsigned char wsp_content_type;
+
+ unsigned char version; /* wbxml version */
+ unsigned char public_id;
+ unsigned char charset; /* default 106 = UTF-8 */
+ unsigned char stl;
+} gn_wap_push_header;
+
+typedef struct {
+ gn_wap_push_header header;
+ char *url;
+ char *text;
+ char *data;
+ int data_len;
+} gn_wap_push;
+
+GNOKII_API void gn_wap_push_init(gn_wap_push *wp);
+GNOKII_API gn_error gn_wap_push_encode(gn_wap_push *wp);
+
+#endif /* _gnokii_sms_h */
Added: trunk/src/host/qemu-neo1973/gnokiigsm/statemachine.h
===================================================================
--- trunk/src/host/qemu-neo1973/gnokiigsm/statemachine.h 2007-05-16 22:38:21 UTC (rev 1986)
+++ trunk/src/host/qemu-neo1973/gnokiigsm/statemachine.h 2007-05-17 00:24:48 UTC (rev 1987)
@@ -0,0 +1,106 @@
+/*
+
+ $Id: statemachine.h,v 1.25 2006/06/11 16:39:11 deller Exp $
+
+ G N O K I I
+
+ A Linux/Unix toolset and driver for the mobile phones.
+
+ This file is part of gnokii.
+
+ Gnokii 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.
+
+ Gnokii 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 gnokii; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+ Copyright (C) 1999-2000 Hugh Blemings & Pavel Janík ml.
+ Copyright (C) 2002-2003 Pawel Kot, BORBELY Zoltan
+
+ Header file for the statemachine.
+
+*/
+
+#ifndef _gnokii_statemachine_h
+#define _gnokii_statemachine_h
+
+#include <error.h>
+#include <data.h>
+
+/* Small structure used in gn_driver */
+/* Messagetype is passed to the function in case it is a 'generic' one */
+typedef struct {
+ unsigned char message_type;
+ gn_error (*functions)(int messagetype, unsigned char *buffer, int length,
+ gn_data *data, struct gn_statemachine *state);
+} gn_incoming_function_type;
+
+/* This structure contains the 'callups' needed by the statemachine */
+/* to deal with messages from the phone and other information */
+typedef struct {
+ /* These make up a list of functions, one for each message type and NULL terminated */
+ gn_incoming_function_type *incoming_functions;
+ gn_error (*default_function)(int messagetype, unsigned char *buffer, int length, struct gn_statemachine *state);
+ gn_phone phone;
+ gn_error (*functions)(gn_operation op, gn_data *data, struct gn_statemachine *state);
+ void *driver_instance;
+} gn_driver;
+
+/* How many message types we can wait for at one moment */
+#define GN_SM_WAITINGFOR_MAX_NUMBER 3
+
+/* The states the statemachine can take */
+typedef enum {
+ GN_SM_Startup, /* Not yet initialised */
+ GN_SM_Initialised, /* Ready! */
+ GN_SM_MessageSent, /* A command has been sent to the link(phone) */
+ GN_SM_WaitingForResponse, /* We are waiting for a response from the link(phone) */
+ GN_SM_ResponseReceived /* A response has been received - waiting for the phone layer to collect it */
+} gn_state;
+
+/* All properties of the state machine */
+struct gn_statemachine {
+ gn_state current_state;
+ gn_config config;
+ gn_device device;
+ gn_link link;
+ gn_driver driver;
+ char *lockfile;
+
+ /* Store last message for resend purposes */
+ unsigned char last_msg_type;
+ unsigned int last_msg_size;
+ void *last_msg;
+
+ /* The responses we are waiting for */
+ unsigned char waiting_for_number;
+ unsigned char received_number;
+ unsigned char waiting_for[GN_SM_WAITINGFOR_MAX_NUMBER];
+ gn_error response_error[GN_SM_WAITINGFOR_MAX_NUMBER];
+ /* Data structure to be filled in with the response */
+ gn_data *data[GN_SM_WAITINGFOR_MAX_NUMBER];
+
+ /* libfunctions internal data structure */
+ gn_error lasterror;
+ gn_data sm_data;
+ union {
+ gn_phonebook_entry pb_entry;
+ } u;
+
+ struct gsmmodem_info_s *info;
+};
+
+GNOKII_API gn_state gn_sm_loop(int timeout, struct gn_statemachine *state);
+
+/* General way to call any driver function */
+GNOKII_API gn_error gn_sm_functions(gn_operation op, gn_data *data, struct gn_statemachine *sm);
+
+#endif /* _gnokii_statemachine_h */
Added: trunk/src/host/qemu-neo1973/gnokiigsm/virtmodem.c
===================================================================
--- trunk/src/host/qemu-neo1973/gnokiigsm/virtmodem.c 2007-05-16 22:38:21 UTC (rev 1986)
+++ trunk/src/host/qemu-neo1973/gnokiigsm/virtmodem.c 2007-05-17 00:24:48 UTC (rev 1987)
@@ -0,0 +1,218 @@
+/*
+
+ $Id: virtmodem.c,v 1.49 2006/10/19 16:05:35 dforsi Exp $
+
+ G N O K I I
+
+ A Linux/Unix toolset and driver for the mobile phones.
+
+ This file is part of gnokii.
+
+ Gnokii 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.
+
+ Gnokii 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 gnokii; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+ Copyright (C) 1999-2000 Hugh Blemings & Pavel Janík ml.
+ Copyright (C) 2002 Ladis Michl, Manfred Jonsson, Jan Kratochvil
+ Copyright (C) 2001-2004 Pawel Kot
+ Copyright (C) 2002-2003 BORBELY Zoltan
+
+ This file provides a virtual modem interface to the GSM phone by calling
+ code in gsm-api.c, at-emulator.c and datapump.c. The code here provides
+ the overall framework and coordinates switching between command mode
+ (AT-emulator) and "online" mode where the data pump code translates data
+ from/to the GSM handset and the modem data/fax stream.
+
+*/
+
+#include <sys/types.h>
+#include <stdio.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <signal.h>
+#include <termios.h>
+#include <grp.h>
+#include <string.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/time.h>
+#include <sys/socket.h>
+#include <sys/wait.h>
+#include <sys/uio.h>
+#include <sys/param.h>
+
+#include "compat.h"
+#include "misc.h"
+#include "gnokii-internal.h"
+#include "at-emulator.h"
+#include "datapump.h"
+#include "device.h"
+
+/* Defines */
+
+#ifndef AF_LOCAL
+# ifdef AF_UNIX
+# define AF_LOCAL AF_UNIX
+# else
+# error AF_LOCAL not defined
+# endif
+#endif
+
+/* Prototypes */
+static int VM_PtySetup();
+static gn_error VM_GSMInitialise(struct gn_statemachine *sm);
+
+/* Global variables */
+
+extern bool GTerminateThread;
+int ConnectCount;
+bool CommandMode;
+
+/* Local variables */
+
+static int PtyRDFD; /* File descriptor for reading and writing to/from */
+static int PtyWRFD; /* pty interface - only different in debug mode. */
+
+struct vm_queue queue;
+
+/* If initialised in debug mode, stdin/out is used instead
+ of ptys for interface. */
+bool gn_vm_initialise(const char *iname, bool GSMInit)
+{
+ static struct gn_statemachine State;
+ sm = &State;
+ queue.n = 0;
+ queue.head = 0;
+ queue.tail = 0;
+
+ CommandMode = true;
+
+ if (GSMInit) {
+ dprintf("Initialising GSM\n");
+ if (gn_cfg_phone_load(iname, sm) != GN_ERR_NONE) return false;
+ if ((VM_GSMInitialise(sm) != GN_ERR_NONE)) {
+ fprintf (stderr, _("gn_vm_initialise - VM_GSMInitialise failed!\n"));
+ return (false);
+ }
+ }
+ GSMInit = false;
+
+ if (VM_PtySetup() < 0) {
+ fprintf (stderr, _("gn_vm_initialise - VM_PtySetup failed!\n"));
+ return (false);
+ }
+
+ if (gn_atem_initialise(PtyRDFD, PtyWRFD, sm) != true) {
+ fprintf (stderr, _("gn_vm_initialise - gn_atem_initialise failed!\n"));
+ return (false);
+ }
+
+ if (dp_Initialise(PtyRDFD, PtyWRFD) != true) {
+ fprintf (stderr, _("gn_vm_Initialise - dp_Initialise failed!\n"));
+ return (false);
+ }
+
+ return (true);
+}
+
+void gn_vm_loop(void)
+{
+ fd_set rfds;
+ struct timeval tv;
+ int res;
+ int nfd;
+ int i, n;
+ char buf[256], *d;
+
+ nfd = PtyRDFD + 1;
+
+ while (!GTerminateThread) {
+ if (CommandMode && gn_atem_initialised && queue.n > 0) {
+ d = queue.buf + queue.head;
+ queue.head = (queue.head + 1) % sizeof(queue.buf);
+ queue.n--;
+ gn_atem_incoming_data_handle(d, 1);
+ continue;
+ }
+
+ FD_ZERO(&rfds);
+ if ( queue.n < sizeof(queue.buf) ) {
+ FD_SET(PtyRDFD, &rfds);
+ }
+ tv.tv_sec = 0;
+ tv.tv_usec = 500000;
+ res = select(nfd, &rfds, NULL, NULL, &tv);
+
+ switch (res) {
+ case 0: /* Timeout */
+ continue;
+
+ case -1:
+ perror("gn_vm_loop - select");
+ exit (-1);
+
+ default:
+ break;
+ }
+
+ if (FD_ISSET(PtyRDFD, &rfds)) {
+ n = sizeof(queue.buf) - queue.n < sizeof(buf) ?
+ sizeof(queue.buf) - queue.n :
+ sizeof(buf);
+ if ( (n = read(PtyRDFD, buf, n)) <= 0 ) gn_vm_terminate();
+
+ for (i = 0; i < n; i++) {
+ queue.buf[queue.tail++] = buf[i];
+ queue.tail %= sizeof(queue.buf);
+ queue.n++;
+ }
+ }
+ }
+}
+
+/* Application should call gn_vm_terminate to shut down
+ the virtual modem thread */
+void gn_vm_terminate(void)
+{
+ /* Request termination of thread */
+ GTerminateThread = true;
+
+ close (PtyRDFD);
+ close (PtyWRFD);
+
+ /* Shutdown device */
+ gn_sm_functions(GN_OP_Terminate, NULL, sm);
+}
+
+/* Open pseudo tty interface and (in due course create a symlink
+ to be /dev/gnokii etc. ) */
+static int VM_PtySetup()
+{
+ PtyRDFD = STDIN_FILENO;
+ PtyWRFD = STDOUT_FILENO;
+ return (0);
+}
+
+/* Initialise GSM interface, returning gn_error as appropriate */
+static gn_error VM_GSMInitialise(struct gn_statemachine *sm)
+{
+ gn_error error;
+
+ /* Initialise the code for the GSM interface. */
+ error = gn_gsm_initialise(sm);
+
+ if (error != GN_ERR_NONE)
+ fprintf(stderr, _("GSM/FBUS init failed! (Unknown model?). Quitting.\n"));
+
+ return (error);
+}
Added: trunk/src/host/qemu-neo1973/gnokiigsm/virtmodem.h
===================================================================
--- trunk/src/host/qemu-neo1973/gnokiigsm/virtmodem.h 2007-05-16 22:38:21 UTC (rev 1986)
+++ trunk/src/host/qemu-neo1973/gnokiigsm/virtmodem.h 2007-05-17 00:24:48 UTC (rev 1987)
@@ -0,0 +1,50 @@
+/*
+
+ $Id: virtmodem.h,v 1.18 2006/06/11 16:39:11 deller Exp $
+
+ G N O K I I
+
+ A Linux/Unix toolset and driver for the mobile phones.
+
+ This file is part of gnokii.
+
+ Gnokii 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.
+
+ Gnokii 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 gnokii; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+ Copyright (C) 1999-2000 Hugh Blemings & Pavel Janík ml.
+ Copyright (C) 2001 Chris Kemp
+ Copyright (C) 2002-2003 Pawel Kot, BORBELY Zoltan
+
+ Header file for virtmodem code in virtmodem.c
+
+*/
+
+#ifndef _gnokii_virtmodem_h
+#define _gnokii_virtmodem_h
+
+struct vm_queue {
+ int n;
+ int head;
+ int tail;
+ unsigned char buf[256];
+};
+
+extern struct vm_queue queue;
+
+/* Prototypes */
+GNOKII_API int gn_vm_initialise(const char *iname, int gn_init);
+GNOKII_API void gn_vm_loop(void);
+GNOKII_API void gn_vm_terminate(void);
+
+#endif /* _gnokii_virtmodem_h */
Added: trunk/src/host/qemu-neo1973/gnokiigsm/wappush.h
===================================================================
--- trunk/src/host/qemu-neo1973/gnokiigsm/wappush.h 2007-05-16 22:38:21 UTC (rev 1986)
+++ trunk/src/host/qemu-neo1973/gnokiigsm/wappush.h 2007-05-17 00:24:48 UTC (rev 1987)
@@ -0,0 +1,70 @@
+/*
+ $Id: wappush.h,v 1.1 2006/07/05 12:57:13 thrull Exp $
+
+ G N O K I I
+
+ A Linux/Unix toolset and driver for the mobile phones.
+
+ This file is part of gnokii.
+
+ Gnokii 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.
+
+ Gnokii 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 gnokii; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+ Copyright (C) 2006 Igor Popik
+
+ Include file for the binary SMS push functions.
+
+ Based on wapforum document WAP-167-ServiceInd-20010731-a
+
+*/
+
+#define WBXML_VERSION 0x01
+#define WAPPush_CHARSET 0x6a /* UTF-8 106 */
+#define PDU_TYPE_Push 0x06
+#define CONTENT_TYPE 0xae /* application/vnd.wap.sic */
+
+/* wbxml tag tokens masks */
+typedef enum {
+ TOKEN_KNOWN = 0x00, /* token known */
+ TOKEN_KNOWN_C = 0x40, /* token known with content */
+ TOKEN_KNOWN_A = 0x80, /* token known with attributes */
+ TOKEN_KNOWN_AC = 0xC0 /* token known with attr & content */
+} gn_wap_push_tokens_masks;
+
+/* Service indication tag tokens */
+typedef enum {
+ TAG_END = 0x01, /* end of TAG,ATTR list */
+ TAG_INLINE = 0x03, /* inline string */
+ TAG_SI = 0x05, /* public ID */
+ TAG_INDICATION = 0x06, /* indication */
+ TAG_INFO = 0x07, /* info */
+ TAG_ITEM = 0x08 /* item */
+} gn_wap_push_tag_tokens;
+
+typedef enum {
+ ATTR_ACT_SIGNAL_NONE = 0x05, /* action - signal-none */
+ ATTR_ACT_SIGNAL_LOW = 0x06, /* action - signal-low */
+ ATTR_ACT_SIGNAL_MEDIUM = 0x07, /* action - signal-medium */
+ ATTR_ACT_SIGNAL_HIGH = 0x08, /* action - signal-high */
+ ATTR_ACT_DELETE = 0x09, /* action - delete */
+ ATTR_CREATED = 0x0a, /* created */
+ ATTR_HREF = 0x0b, /* href */
+ ATTR_HREF_HTTP = 0x0c, /* http:// */
+ ATTR_HREF_HTTP_WWW = 0x0d, /* http://www. */
+ ATTR_HREF_HTTPS = 0x0e, /* https:// */
+ ATTR_HREF_HTTPS_WWW = 0x0f, /* https://www. */
+ ATTR_SI_EXPRES = 0x10,
+ ATTR_SI_ID = 0x11,
+ ATTR_CLASS = 0x12
+} gn_wap_push_tag_attr;
Modified: trunk/src/host/qemu-neo1973/hw/modem.c
===================================================================
--- trunk/src/host/qemu-neo1973/hw/modem.c 2007-05-16 22:38:21 UTC (rev 1986)
+++ trunk/src/host/qemu-neo1973/hw/modem.c 2007-05-17 00:24:48 UTC (rev 1987)
@@ -1,5 +1,5 @@
/*
- * AT commands interpreter. (Fake GSM modem)
+ * Fake GSM modem. Tries to be Texas Instruments "Calypso" compatible.
*
* Copyright (c) 2007 OpenMoko, Inc.
* Author: Andrzej Zaborowski <andrew at openedhand.com>
@@ -8,22 +8,117 @@
*/
#include "vl.h"
+#include "misc.h"
+#include "gnokii.h"
+#include "compat.h"
+#include "at-emulator.h"
+#include "datapump.h"
+
+#define TICALYPSO_MANF "<manufacturer>"
+#define TICALYPSO_MODEL "<model>"
+#define TICALYPSO_REV "<revision>"
+#define TICALYPSO_IMEI "<serial number>"
+
+bool GTerminateThread = false;
+
+GNOKII_API gn_error gn_cfg_phone_load(const char *iname,
+ struct gn_statemachine *state)
+{
+ return GN_ERR_NOTSUPPORTED;
+}
+
+GNOKII_API gn_error gn_sm_functions(gn_operation op, gn_data *data,
+ struct gn_statemachine *sm)
+{
+ switch (op) {
+ case GN_OP_MakeCall:
+ fprintf(stderr, "%s: calling %s: busy.\n", __FUNCTION__,
+ data->call_info->number);
+ return GN_ERR_LINEBUSY;
+
+ case GN_OP_CancelCall:
+ fprintf(stderr, "%s: hangup.\n", __FUNCTION__);
+ break;
+
+ case GN_OP_DeleteSMS:
+ fprintf(stderr, "%s: deleting SMS number %i\n", __FUNCTION__,
+ data->sms->number);
+ return GN_ERR_EMPTYLOCATION;
+
+ case GN_OP_GetRFLevel:
+ *data->rf_level = 32.0f; /* Some -50 dBm */
+ break;
+
+ case GN_OP_GetImei:
+ strcpy(data->imei, TICALYPSO_IMEI);
+ break;
+
+ case GN_OP_GetRevision:
+ strcpy(data->revision, TICALYPSO_REV);
+ break;
+
+ case GN_OP_GetModel:
+ strcpy(data->revision, TICALYPSO_MODEL);
+ break;
+
+ case GN_OP_Identify:
+ strcpy(data->model, TICALYPSO_MODEL);
+ strcpy(data->revision, TICALYPSO_REV);
+ strcpy(data->imei, TICALYPSO_IMEI);
+ strcpy(data->manufacturer, TICALYPSO_MANF);
+ break;
+
+ default:
+ return GN_ERR_NOTSUPPORTED;
+ }
+ return GN_ERR_NONE;
+}
+
+GNOKII_API gn_error gn_gsm_initialise(struct gn_statemachine *sm)
+{
+ return GN_ERR_NOTSUPPORTED;
+}
+
+GNOKII_API void gn_data_clear(gn_data *data)
+{
+ memset(data, 0, sizeof(gn_data));
+}
+
+GNOKII_API gn_state gn_sm_loop(int timeout, struct gn_statemachine *state)
+{
+ return GN_ERR_NOTSUPPORTED;
+}
+
+GNOKII_API gn_error gn_sms_get(gn_data *data, struct gn_statemachine *state)
+{
+ fprintf(stderr, "%s: SMS number %i requested\n",
+ __FUNCTION__, data->sms->number);
+ return GN_ERR_EMPTYLOCATION;
+}
+
+GNOKII_API gn_error gn_sms_send(gn_data *data, struct gn_statemachine *state)
+{
+ fprintf(stderr, "%s: SMS type 0x%02x sent\n",
+ __FUNCTION__, data->sms->type);
+ return GN_ERR_NOTSUPPORTED;
+}
+
struct modem_s {
int enable;
CharDriverState chr;
- int cmd_len;
- char cmd[1024];
#define FIFO_LEN 4096
int out_start;
int out_len;
char outfifo[FIFO_LEN];
QEMUTimer *out_tm;
int64_t baud_delay;
+
+ struct gn_statemachine state;
+ struct gsmmodem_info_s info;
};
static void modem_reset(struct modem_s *s)
{
- s->cmd_len = 0;
s->out_len = 0;
s->baud_delay = ticks_per_sec;
}
@@ -45,10 +140,11 @@
qemu_mod_timer(s->out_tm, qemu_get_clock(vm_clock) + s->baud_delay);
}
-static void modem_resp(struct modem_s *s, const char *fmt, ...)
+static void modem_resp(void *opaque, const char *fmt, ...)
__attribute__ ((__format__ (__printf__, 2, 3)));
-static void modem_resp(struct modem_s *s, const char *fmt, ...)
+static void modem_resp(void *opaque, const char *fmt, ...)
{
+ struct modem_s *s = (struct modem_s *) opaque;
static char buf[FIFO_LEN];
int len, off;
va_list ap;
@@ -69,319 +165,14 @@
modem_fifo_wake(s);
}
-static struct modem_cmd_s {
- const char *cmd;
- enum { modem_ok, modem_error, modem_call, modem_str } action;
- int (*call)(struct modem_s *s, const char *param);
- const char *resp;
-} modem_cmds[] = {
- { "AT+CACM", modem_error },
- { "AT+CAMM", modem_error },
- { "AT+CAOC", modem_error },
- { "AT+CBC", modem_error },
- { "AT+CBST", modem_error },
- { "AT+CCFC", modem_error },
- { "AT+CCUG", modem_error },
- { "AT+CCWA", modem_error },
- { "AT+CCWE", modem_error },
- { "AT+CEER", modem_error },
- { "AT+CFUN", modem_error },
- { "AT+CGACT", modem_error },
- { "AT+CGANS", modem_error },
- { "AT+CGATT", modem_error },
- { "AT+CGAUTO", modem_error },
- { "AT+CGCLASS", modem_error },
- { "AT+CGDATA", modem_error },
- { "AT+CGDCONT", modem_error },
- { "AT+CGEREP", modem_error },
- { "AT+CGMI", modem_str, 0, "<manufacturer>\n\n" },
- { "AT+CGMM", modem_str, 0, "<model>\n\n" },
- { "AT+CGMR", modem_str, 0, "<revision>\n\n" },
- { "AT+CGPADDR", modem_error },
- { "AT+CGQMIN", modem_error },
- { "AT+CGQREQ", modem_error },
- { "AT+CGREG", modem_error },
- { "AT+CGSMS", modem_error },
- { "AT+CGSN", modem_str, 0, "<serial number>\n\n" },
- { "AT+CHLD", modem_error },
- { "AT+CHUP", modem_error },
- { "AT+CIMI", modem_error },
- { "AT+CLAC", modem_error },
- { "AT+CLAE", modem_error },
- { "AT+CLAN", modem_error },
- { "AT+CLCC", modem_error },
- { "AT+CLCK", modem_error },
- { "AT+CLIP", modem_error },
- { "AT+CDIP", modem_error },
- { "AT+CLIR", modem_error },
- { "AT+CLVL", modem_error },
- { "AT+CMEE", modem_error },
- { "AT+CMGC", modem_error },
- { "AT+CMGD", modem_error },
- { "AT+CMGF", modem_error },
- { "AT+CMGL", modem_error },
- { "AT+CMGR", modem_error },
- { "AT+CMGS", modem_error },
- { "AT+CMGW", modem_error },
- { "AT+CMOD", modem_error },
- { "AT+CMSS", modem_error },
- { "AT+CMMS", modem_error },
- { "AT+CMUT", modem_error },
- { "AT+CMUX", modem_error },
- { "AT+CNMA", modem_error },
- { "AT+CNMI", modem_error },
- { "AT+CNUM", modem_error },
- { "AT+COLP", modem_error },
- { "AT+COPN", modem_error },
- { "AT+COPS", modem_ok },
- { "AT+CPAS", modem_error },
- { "AT+CPBF", modem_error },
- { "AT+CPBR", modem_error },
- { "AT+CPBS", modem_error },
- { "AT+CPBW", modem_error },
- { "AT+CPIN", modem_ok },
- { "AT+CPMS", modem_error },
- { "AT+CPOL", modem_error },
- { "AT+CPUC", modem_error },
- { "AT+CPWD", modem_error },
- { "AT+CR", modem_error },
- { "AT+CRC", modem_error },
- { "AT+CREG", modem_error },
- { "AT+CRES", modem_error },
- { "AT+CRLP", modem_error },
- { "AT+CRSL", modem_error },
- { "AT+CRSM", modem_error },
- { "AT+CSAS", modem_error },
- { "AT+CSCA", modem_error },
- { "AT+CSCB", modem_error },
- { "AT+CSCS", modem_error },
- { "AT+CSDH", modem_error },
- { "AT+CSIM", modem_error },
- { "AT+CSMP", modem_error },
- { "AT+CSMS", modem_error },
- { "AT+CSNS", modem_error },
- { "AT+CSQ", modem_error },
- { "AT%CSQ", modem_error },
- { "AT+CSSN", modem_error },
- { "AT+CSTA", modem_error },
- { "AT+CSVM", modem_error },
- { "AT+CTFR", modem_error },
- { "AT+CUSD", modem_error },
- { "AT+DR", modem_error },
- { "AT+FAP", modem_error },
- { "AT+FBO", modem_error },
- { "AT+FBS", modem_error },
- { "AT+FBU", modem_error },
- { "AT+FCC", modem_error },
- { "AT+FCLASS", modem_error },
- { "AT+FCQ", modem_error },
- { "AT+FCR", modem_error },
- { "AT+FCS", modem_error },
- { "AT+FCT", modem_error },
- { "AT+FDR", modem_error },
- { "AT+FDT", modem_error },
- { "AT+FEA", modem_error },
- { "AT+FFC", modem_error },
- { "AT+FHS", modem_error },
- { "AT+FIE", modem_error },
- { "AT+FIP", modem_error },
- { "AT+FIS", modem_error },
- { "AT+FIT", modem_error },
- { "AT+FKS", modem_error },
- { "AT+FLI", modem_error },
- { "AT+FLO", modem_error },
- { "AT+FLP", modem_error },
- { "AT+FMI", modem_error },
- { "AT+FMM", modem_error },
- { "AT+FMR", modem_error },
- { "AT+FMS", modem_error },
- { "AT+FND", modem_error },
- { "AT+FNR", modem_error },
- { "AT+FNS", modem_error },
- { "AT+FPA", modem_error },
- { "AT+FPI", modem_error },
- { "AT+FPS", modem_error },
- { "AT+FPW", modem_error },
- { "AT+FRQ", modem_error },
- { "AT+FSA", modem_error },
- { "AT+FSP", modem_error },
- { "AT+GCAP", modem_error },
- { "AT+GCI", modem_error },
- { "AT+GMI", modem_error },
- { "AT+GMM", modem_error },
- { "AT+GMR", modem_error },
- { "AT+GSN", modem_error },
- { "AT+ICF", modem_error },
- { "AT+IFC", modem_error },
- { "AT+ILRR", modem_error },
- { "AT+IPR", modem_error },
- { "AT+VTS", modem_error },
- { "AT+WS46", modem_error },
- { "AT%ALS", modem_error },
- { "AT%ATR", modem_error },
- { "AT%BAND", modem_error },
- { "AT%CACM", modem_error },
- { "AT%CAOC", modem_error },
- { "AT%CCBS", modem_error },
- { "AT%STDR", modem_error },
- { "AT%CGAATT", modem_error },
- { "AT%CGMM", modem_error },
- { "AT%CGREG", modem_error },
- { "AT%CNAP", modem_error },
- { "AT%CPI", modem_error },
- { "AT%COLR", modem_error },
- { "AT%CPRIM", modem_error },
- { "AT%CTV", modem_error },
- { "AT%CUNS", modem_error },
- { "AT%NRG", modem_error },
- { "AT%SATC", modem_error },
- { "AT%SATE", modem_error },
- { "AT%SATR", modem_error },
- { "AT%SATT", modem_error },
- { "AT%SNCNT", modem_error },
- { "AT%VER", modem_error },
- { "AT%CGCLASS", modem_error },
- { "AT%CGPCO", modem_error },
- { "AT%CGPPP", modem_error },
- { "AT%EM", modem_error },
- { "AT%EMET", modem_error },
- { "AT%EMETS", modem_error },
- { "AT%CBHZ", modem_error },
- { "AT%CPHS", modem_error },
- { "AT%CPNUMS", modem_error },
- { "AT%CPALS", modem_error },
- { "AT%CPVWI", modem_error },
- { "AT%CPOPN", modem_error },
- { "AT%CPCFU", modem_error },
- { "AT%CPINF", modem_error },
- { "AT%CPMB", modem_error },
- { "AT%CPRI", modem_error },
- { "AT%DATA", modem_error },
- { "AT%DINF", modem_error },
- { "AT%CLCC", modem_error },
- { "AT%DBGINFO", modem_error },
- { "AT%VTS", modem_error },
- { "AT%CHPL", modem_error },
- { "AT%CREG", modem_error },
- { "AT+CTZR", modem_error },
- { "AT+CTZU", modem_error },
- { "AT%CTZV", modem_error },
- { "AT%CNIV", modem_error },
- { "AT%PVRF", modem_error },
- { "AT%CWUP", modem_error },
- { "AT%DAR", modem_error },
- { "AT+CIND", modem_error },
- { "AT+CMER", modem_error },
- { "AT%CSCN", modem_error },
- { "AT%RDL", modem_error },
- { "AT%RDLB", modem_error },
- { "AT%CSTAT", modem_error },
- { "AT%CPRSM", modem_error },
- { "AT%CHLD", modem_error },
- { "AT%SIMIND", modem_error },
- { "AT%SECP", modem_error },
- { "AT%SECS", modem_error },
- { "AT%CSSN", modem_error },
- { "AT+CCLK", modem_error },
- { "AT%CSSD", modem_error },
- { "AT%COPS", modem_error },
- { "AT%CPMBW", modem_error },
- { "AT%CUST", modem_error },
- { "AT%SATCC", modem_error },
- { "AT%COPN", modem_error },
- { "AT%CGEREP", modem_error },
- { "AT%CUSCFG", modem_error },
- { "AT%CUSDR", modem_error },
- { "AT%CPBS", modem_error },
- { "AT%PBCF", modem_error },
- { "AT%SIMEF", modem_error },
- { "AT%EFRSLT", modem_error },
- { "AT%CMGMDU", modem_error },
- { "AT%CMGL", modem_error },
- { "AT%CMGR", modem_error },
- { "ATA", modem_ok },
- { "ATB", modem_error },
- { "AT&C", modem_error },
- { "ATD", modem_ok },
- { "AT&D", modem_error },
- { "ATE", modem_ok },
- { "ATF", modem_error },
- { "AT&F", modem_error },
- { "ATH", modem_ok },
- { "ATI", modem_error },
- { "AT&K", modem_error },
- { "ATL", modem_error },
- { "ATM", modem_error },
- { "ATO", modem_error },
- { "ATP", modem_error },
- { "ATQ", modem_error },
- { "ATS", modem_error },
- { "ATT", modem_error },
- { "ATV", modem_error },
- { "ATW", modem_error },
- { "AT&W", modem_error },
- { "ATX", modem_error },
- { "ATZ", modem_error },
- { 0 }
-};
-
-static void modem_cmd(struct modem_s *s, const char *cmd)
-{
- struct modem_cmd_s *entry;
- const char *eq, *param;
- int ok;
- eq = strchr(cmd, '=');
- if (eq)
- param = eq + 1;
- else
- param = 0;
- ok = 0;
- for (entry = modem_cmds; entry->cmd; entry ++)
- if (!strncmp(cmd, entry->cmd, strlen(entry->cmd))) {
- switch (entry->action) {
- case modem_ok:
- ok = 1;
- break;
- case modem_error:
- ok = 0;
- break;
- case modem_call:
- ok = entry->call(s, param);
- break;
- case modem_str:
- modem_resp(s, entry->resp);
- ok = 1;
- break;
- }
- return;
- }
- if (ok)
- modem_resp(s, "OK\n");
- else
- modem_resp(s, "ERROR\n");
-}
-
static int modem_write(struct CharDriverState *chr,
const uint8_t *buf, int len)
{
struct modem_s *s = (struct modem_s *) chr->opaque;
- char *eol;
if (!s->enable)
return 0;
- len = MIN(len, 1023 - s->cmd_len);
- memcpy(s->cmd + s->cmd_len, buf, len);
- s->cmd_len += len;
- s->cmd[s->cmd_len] = 0;
-
- eol = strchr(s->cmd, '\n');
- if (eol) {
- s->cmd_len -= eol - s->cmd;
- *eol = 0;
- modem_cmd(s, s->cmd);
- memcpy(s->cmd, eol + 1, s->cmd_len --);
- } else if (s->cmd_len >= 1023)
- s->cmd_len = 0;
+ gn_atem_incoming_data_handle(buf, len);
return len;
}
@@ -399,7 +190,7 @@
if (!s->enable)
return -ENOTSUP;
if (*(int *) arg)
- modem_resp(s, "AT-Command Interpreter Ready\nOK\n");
+ modem_resp(s, "AT-Command Interpreter Ready\r\nOK\r\n");
break;
default:
@@ -430,5 +221,18 @@
s->chr.chr_ioctl = modem_ioctl;
s->out_tm = qemu_new_timer(vm_clock, modem_out_tick, s);
+ s->state.info = &s->info;
+ s->info.write = modem_resp;
+ s->info.opaque = s;
+
+ if (!gn_atem_initialise(0, 1, &s->state))
+ goto fail;
+
+ if (!dp_Initialise(0, 1))
+ goto fail;
+
return &s->chr;
+fail:
+ fprintf(stderr, "%s: GSM modem initialisation failed\n", __FUNCTION__);
+ exit(-1);
}
Modified: trunk/src/host/qemu-neo1973/hw/s3c2410.c
===================================================================
--- trunk/src/host/qemu-neo1973/hw/s3c2410.c 2007-05-16 22:38:21 UTC (rev 1986)
+++ trunk/src/host/qemu-neo1973/hw/s3c2410.c 2007-05-17 00:24:48 UTC (rev 1987)
@@ -133,6 +133,19 @@
[S3C_PICS_ADC & 31] = S3C_PIC_ADC,
};
+static void s3c_pic_subupdate(struct s3c_pic_state_s *s)
+{
+ int next;
+ const int *sub = &s3c_sub_src_map[-1];
+ uint32_t pnd = s->subsrcpnd & ~s->intsubmsk;
+ while ((next = ffs(pnd))) {
+ sub += next;
+ pnd >>= next;
+ s->srcpnd |= 1 << *sub;
+ }
+ s3c_pic_arbitrate(s);
+}
+
static void s3c_pic_set_irq(void *opaque, int irq, int req)
{
struct s3c_pic_state_s *s = (struct s3c_pic_state_s *) opaque;
@@ -145,10 +158,10 @@
if (irq & 32) {
irq &= 31;
s->subsrcpnd |= 1 << irq;
- if (~s->intsubmsk & (1 << irq))
+ if (s->intsubmsk & (1 << irq))
+ return;
+ else
irq = s3c_sub_src_map[irq];
- else
- return;
}
s->srcpnd |= (mask = 1 << irq);
@@ -255,6 +268,7 @@
break;
case S3C_INTSUBMSK:
s->intsubmsk = value;
+ s3c_pic_subupdate(s);
break;
default:
printf("%s: Bad register 0x%lx\n", __FUNCTION__, addr);
@@ -1106,37 +1120,6 @@
s->rxlen = 0;
}
-static void s3c_uart_params_update(struct s3c_uart_state_s *s)
-{
- QEMUSerialSetParams ssp;
- int i;
- if (!s->chr)
- return;
-
- /* XXX Calculate PCLK frequency from clock manager registers */
- ssp.speed = (S3C_PCLK_FREQ >> 4) / (s->brdiv + 1);
-
- switch ((s->lcontrol >> 3) & 7) {
- case 4:
- case 6:
- ssp.parity = 'O';
- break;
- case 5:
- case 7:
- ssp.parity = 'E';
- break;
- default:
- ssp.parity = 'N';
- }
-
- ssp.data_bits = 5 + (s->lcontrol & 3);
-
- ssp.stop_bits = (s->lcontrol & (1 << 2)) ? 2 : 1;
-
- for (i = 0; i < s->chr_num; i ++)
- qemu_chr_ioctl(s->chr[i], CHR_IOCTL_SERIAL_SET_PARAMS, &ssp);
-}
-
static void s3c_uart_err(struct s3c_uart_state_s *s, int err)
{
s->errstat |= err;
@@ -1144,7 +1127,7 @@
qemu_irq_raise(s->irq[2]);
}
-static void s3c_uart_full(struct s3c_uart_state_s *s)
+inline static void s3c_uart_full(struct s3c_uart_state_s *s, int pulse)
{
if (s->fcontrol & 1) /* FIFOEnable */
if (s->rxlen < (((s->fcontrol >> 4) & 3) + 1) * 4)
@@ -1152,7 +1135,8 @@
switch ((s->control >> 0) & 3) { /* ReceiveMode */
case 1:
- qemu_irq_raise(s->irq[0]);
+ if ((s->control & (1 << 8)) || pulse) /* RxInterruptType */
+ qemu_irq_raise(s->irq[0]);
break;
case 2:
case 3:
@@ -1161,11 +1145,12 @@
}
}
-static void s3c_uart_empty(struct s3c_uart_state_s *s)
+inline static void s3c_uart_empty(struct s3c_uart_state_s *s, int pulse)
{
switch ((s->control >> 2) & 3) { /* TransmitMode */
case 1:
- qemu_irq_raise(s->irq[1]);
+ if ((s->control & (1 << 9)) || pulse) /* TxInterruptType */
+ qemu_irq_raise(s->irq[1]);
break;
case 2:
case 3:
@@ -1174,6 +1159,43 @@
}
}
+inline static void s3c_uart_update(struct s3c_uart_state_s *s)
+{
+ s3c_uart_empty(s, 0);
+ s3c_uart_full(s, 0);
+}
+
+static void s3c_uart_params_update(struct s3c_uart_state_s *s)
+{
+ QEMUSerialSetParams ssp;
+ int i;
+ if (!s->chr)
+ return;
+
+ /* XXX Calculate PCLK frequency from clock manager registers */
+ ssp.speed = (S3C_PCLK_FREQ >> 4) / (s->brdiv + 1);
+
+ switch ((s->lcontrol >> 3) & 7) {
+ case 4:
+ case 6:
+ ssp.parity = 'O';
+ break;
+ case 5:
+ case 7:
+ ssp.parity = 'E';
+ break;
+ default:
+ ssp.parity = 'N';
+ }
+
+ ssp.data_bits = 5 + (s->lcontrol & 3);
+
+ ssp.stop_bits = (s->lcontrol & (1 << 2)) ? 2 : 1;
+
+ for (i = 0; i < s->chr_num; i ++)
+ qemu_chr_ioctl(s->chr[i], CHR_IOCTL_SERIAL_SET_PARAMS, &ssp);
+}
+
static int s3c_uart_is_empty(void *opaque)
{
struct s3c_uart_state_s *s = (struct s3c_uart_state_s *) opaque;
@@ -1206,7 +1228,7 @@
s->rxlen = 1;
s->data = buf[0];
}
- s3c_uart_full(s);
+ s3c_uart_full(s, 1);
}
/* S3C2410 UART doesn't seem to understand break conditions. */
@@ -1244,14 +1266,19 @@
case S3C_UTRSTAT:
return 6 | !!s->rxlen;
case S3C_UERSTAT:
+ /* XXX: UERSTAT[3] is Reserved but Linux thinks it is BREAK */
ret = s->errstat;
s->errstat = 0;
+ s3c_uart_update(s);
return ret;
case S3C_UFSTAT:
- return ((!!s->rxlen) << 8) | s->rxlen;
+ s3c_uart_update(s);
+ return s->rxlen ? s->rxlen | (1 << 8) : 0;
case S3C_UMSTAT:
- return 1;
+ s3c_uart_update(s);
+ return 0x11;
case S3C_URXH:
+ s3c_uart_update(s);
if (s->rxlen) {
s->rxlen --;
if (s->fcontrol & 1) { /* FIFOEnable */
@@ -1286,17 +1313,21 @@
(value & (1 << 6)) ? "on" : "off");
s->lcontrol = value;
s3c_uart_params_update(s);
+ s3c_uart_update(s);
break;
case S3C_UCON:
+ /* XXX: UCON[4] is Reserved but Linux thinks it is BREAK */
if ((s->control ^ value) & (1 << 5))
printf("%s: UART loopback test mode %s\n", __FUNCTION__,
(value & (1 << 5)) ? "on" : "off");
s->control = value & 0x7ef;
+ s3c_uart_update(s);
break;
case S3C_UFCON:
if (value & (1 << 1)) /* RxReset */
s->rxlen = 0;
s->fcontrol = value & 0xf1;
+ s3c_uart_update(s);
break;
case S3C_UMCON:
if ((s->mcontrol ^ value) & (1 << 4)) {
@@ -1305,16 +1336,19 @@
qemu_chr_ioctl(s->chr[i], CHR_IOCTL_MODEM_HANDSHAKE, &afc);
}
s->mcontrol = value & 0x11;
+ s3c_uart_update(s);
break;
case S3C_UTXH:
ch = value & 0xff;
for (i = 0; i < s->chr_num; i ++)
qemu_chr_write(s->chr[i], &ch, 1);
- s3c_uart_empty(s);
+ s3c_uart_empty(s, 1);
+ s3c_uart_update(s);
break;
case S3C_UBRDIV:
s->brdiv = value & 0xffff;
s3c_uart_params_update(s);
+ s3c_uart_update(s);
break;
default:
printf("%s: Bad register 0x%lx\n", __FUNCTION__, addr);
More information about the commitlog
mailing list