copy mod_gsmopen from branch

git-svn-id: http://svn.freeswitch.org/svn/freeswitch/trunk@17138 d0543943-73ff-0310-b7d9-9358b9ac24b2
This commit is contained in:
Michael Jerris 2010-03-30 05:59:43 +00:00
parent e39be69652
commit a33b576e70
267 changed files with 116342 additions and 0 deletions

View File

@ -0,0 +1,9 @@
MODNAME=mod_gsmopen
SVNDEF := -D'GSMOPEN_SVN_VERSION="$(shell svnversion -n .)"'
#LOCAL_CFLAGS += $(SVNDEF) -I/usr/src/gsmlib-1.10
LOCAL_CFLAGS += $(SVNDEF) -I../../../../libs/spandsp/src -I../../../..//libs/tiff-3.8.2/libtiff
#LOCAL_LDFLAGS=-lasound -L/usr/src/gsmlib-1.10/gsmlib/.libs -lgsmme
LOCAL_LDFLAGS=-L../../../../libs/spandsp/src -lasound -lgsmme -lspandsp
LOCAL_OBJS=gsmopen_protocol.o
#OUR_OBJS += /usr/src/gsmlib-1.10/gsmlib/libgsmme.la
include ../../../../build/modmake.rules

View File

@ -0,0 +1,7 @@
include $(top_srcdir)/build/modmake.rulesam
MODNAME=mod_gsmopen
mod_LTLIBRARIES = mod_gsmopen.la
mod_gsmopen_la_SOURCES = mod_gsmopen.cpp gsmopen_protocol.cpp
mod_gsmopen_la_CFLAGS = $(AM_CFLAGS) -DGSMOPEN_SVN_VERSION=\"`cat $(switch_builddir)/.version`\"
mod_gsmopen_la_LIBADD = $(switch_builddir)/libfreeswitch.la
mod_gsmopen_la_LDFLAGS = -avoid-version -module -no-undefined -lasound -lgsmme -lspandsp

View File

@ -0,0 +1,35 @@
GSMopen, GSM Endpoint and Trunk
This is just a prototype.
put this directory in freeswitch.trunk/src/mod/endpoints/
make clean; make; make install
Is not getting its configuration from the configuration file, it's all hardcoded but it needs the configuration file.
Copy gsmopen.conf.xml in /usr/local/freeswitch/conf/autoload_configs/
You must have the device on serial port /dev/ttyACM0 and the audio as second soundcard plughw:1 (if you do not have a first soundcard, just modprobe snd-dummy before to connect the usb thingy).
Put the volumes (with alsamixer -c1 -Vall) as: speaker 80, autogain on, mic off, mic capt 0.
Then, with alsamixer -c1 -Vcapture, be sure capture is active (eg, press the spacebar until the red CAPTURE appear). When it all working, adjust to your taste.
It answer calls, make calls, receive sms, and send sms (with the CLI command "sendsms").
Copy ciapalo in /usr/local/bin/ (is the program automatically spawned when an SMS is received).
Copy asound.conf in /etc/asound.conf, it will spare you cpu cycles when rate conversion is required (always).
All documentation on compiling, using, configuring,
tricks and tweaks, possible problems at:
http://wiki.freeswitch.org/wiki/GSMopen_GSM_Endpoint_and_Trunk
Enjoy
-giovanni
< gmaruzz at gmail dot com >

View File

@ -0,0 +1,6 @@
MODNAME=mod_gsmopen
SVNDEF := -D'GSMOPEN_SVN_VERSION="$(shell svnversion -n .)"'
LOCAL_CFLAGS += $(SVNDEF) -Wno-error=address -DNO_GSMLIB -I../../../../../../libs/spandsp/src -I../../../../../..//libs/tiff-3.8.2/libtiff
LOCAL_LDFLAGS=-lasound -L../../../../../../libs/spandsp/src -lspandsp
LOCAL_OBJS=gsmopen_protocol.o
include ../../../../../../build/modmake.rules

View File

@ -0,0 +1 @@
../../gsmopen.h

View File

@ -0,0 +1 @@
../../gsmopen_protocol.cpp

View File

@ -0,0 +1 @@
../../mod_gsmopen.cpp

View File

@ -0,0 +1,81 @@
#
# Asterisk -- A telephony toolkit for Linux.
#
# Makefile for channel drivers
#
# Copyright (C) 1999-2005, Mark Spencer
#
# Mark Spencer <markster@digium.com>
#
# Edited By Belgarath <> Aug 28 2004
# Added bare bones ultrasparc-linux support.
#
# This program is free software, distributed under the terms of
# the GNU General Public License
#
#ASTERISK INCLUDE FILES
#The directory that contains the Asterisk include files (eg: /usr/include or /usr/include/asterisk or /usr/src/asterisk/include or ...)
#AST_INCLUDE_DIR=/usr/src/off_dev/asterisk-1.2.rev137401/include
AST_INCLUDE_DIR=/usr/src/asterisk-1.4.27.1/include
#AST_INCLUDE_DIR=/usr/src/asterisk-1.6.0.10/include
#ASTERISK VERSION
#Uncomment one of the following lines to match your Asterisk series
#CFLAGS+=-DASTERISK_VERSION_1_2
CFLAGS+=-DASTERISK_VERSION_1_4
#CFLAGS+=-DASTERISK_VERSION_1_6_0
CFLAGS+=-pipe -Wall -Wstrict-prototypes -Wmissing-prototypes -Wmissing-declarations
CFLAGS+=-g3
CFLAGS+=-I$(AST_INCLUDE_DIR) -I.
CFLAGS+=-D_REENTRANT -D_GNU_SOURCE
#CFLAGS+=-O6
#CFLAGS+=-march=i586
CFLAGS+=-fomit-frame-pointer
ifeq ($(shell uname -m),x86_64)
CFLAGS+=-fPIC
endif
SVNDEF := -D'CELLIAX_SVN_VERSION="$(shell svnversion -n .)"'
CFLAGS += $(SVNDEF)
SOLINK=-shared -Xlinker -x
CHANNEL_LIBS=chan_celliax.so
CC=gcc
OSARCH=$(shell uname -s)
ifeq ($(findstring CYGWIN,$(OSARCH)),CYGWIN)
# definition of pthread_kill as a printf (or as a noop) is required for Asterisk (and celliax) to run on Cygwin
# without it, each time (often) pthread_kill is called (by any thread, with any signal, URG included), bad things happen
CC=gcc -D pthread_kill=cyg_no_pthreadkill
AST_DLL_DIR=/home/maruzz/devel/svn_asterisk_branches_12
CYGSOLINK=-Wl,--out-implib=lib$@.a -Wl,--export-all-symbols cyg_no_pthread_kill.o
CYGSOLIB=-L/usr/lib/w32api -lrpcrt4 -L/lib/mingw -lwinmm -L$(AST_DLL_DIR) -lasterisk.dll -L$(AST_DLL_DIR)/res -lres_features.so
CHANNEL_LIBS=cyg_no_pthread_kill.o chan_celliax.so
endif
all: $(CHANNEL_LIBS)
clean:
rm -f *.so *.o *.so.a
#chan_celliax section begins
#to debug threads and lock on 1.4 uncomment the following
#CFLAGS+=-include /usr/src/asterisk/include/asterisk/autoconfig.h
cyg_no_pthread_kill.o: cyg_no_pthread_kill.c
$(CC) $(CFLAGS) -c -o cyg_no_pthread_kill.o cyg_no_pthread_kill.c
chan_celliax.o: chan_celliax.c
$(CC) $(CFLAGS) -c -o chan_celliax.o chan_celliax.c
chan_celliax.so: chan_celliax.o celliax_spandsp.o celliax_libcsv.o celliax_additional.o
$(CC) $(SOLINK) -o $@ ${CYGSOLINK} chan_celliax.o celliax_spandsp.o celliax_libcsv.o celliax_additional.o -lm -ldl -lasound ${CYGSOLIB}
#chan_celliax section ends

View File

@ -0,0 +1,96 @@
**************************************************************
* CHAN_CELLIAX DRIVER FOR AN EXISTING ASTERISK INSTALLATION
* (works for Asterisk 1.2.xx 1.4.xx 1.6.0.xx series)
* (do NOT works for Asterisk 1.6.1.xx series)
**************************************************************
==============================================================
1) To build celliax you need the ALSA development libraries
==============================================================
To build celliax on Linux you need to install ALSA-dev libs
You can do it on Debian/Ubuntu with:
# apt-get install libasound2-dev
You can do it on Fedora/CentOS with:
# yum --nogpgcheck -y install alsa-lib-devel
===============================================================
2) build chan_celliax
===============================================================
go into the celliax source directory, edit the Makefile,
insert the asterisk version (1.2.x or 1.4.x or 1.6.0.x,
NOT 1.6.1.x), the location of your asterisk sources, then
# make clean
# make
copy chan_celliax.so in the asterisk modules directory
===============================================================
2) configure chan_celliax and asterisk
===============================================================
edit and copy celliax.conf in the asterisk configuration
directory
copy ciapalo (or your program that accepts text in stdini) in
the location defined in celliax.conf (sms_receiving_program)
edit modules.conf and put noload in front of *BOTH* chan_oss.so
AND chan_alsa.so AND chan_console.so
copy asound.conf in /etc/asound.conf
if you enable debug in logger.conf and "set debug 100" on
Asterisk, you'll get *a lot* of info on celliax inner workings
===============================================================
3) Troubleshooting
===============================================================
Check that you set the correct serial device in celliax.conf
You can check how the device is called on your platform with:
dmesg | grep ttyU
dmesg | grep ttyA
Check that you set the correct audio device in celliax.conf
You can check how the device is called on your platform with:
aplay -l
it will give you the number to put on "plughw:N" in celliax.conf
Check the volume for both play and capture, and that capture
is activated (press spacebar when alsamixer in capture mode)
alsamixer -c[soundcard_number] -Vplay
alsamixer -c[soundcard_number] -Vcapture
we found good results with capt(31) autogain(on) speaker(75)
If you get double digits (bounces) on DTMFs, check if the capture
volume is too high
The SMSs are managed in Unicode (UTF8) for international characters
compatibility. Check that your console and/or text editor displays
UTF8 characters
If you have bad sound, it's a timing problem. Use a 1000HZ kernel,
or add a timing device (ztdummy or zaptel interfaces)
***************************************************************
* END CHAN_CELLIAX DRIVER FOR AN EXISTING ASTERISK INSTALLATION
***************************************************************
chan_celliax adds to Asterisk the DIALPLAN application:
CelliaxSendsms
You can type at the Asterisk CLI 'show application [application]'
to obtain more specific info on usage.
Enjoy!
-giovanni
< gmaruzz at gmail dot com >

View File

@ -0,0 +1,2 @@
#defaults.pcm.rate_converter "speexrate"
defaults.pcm.rate_converter "linear"

View File

@ -0,0 +1,205 @@
;;
;;
; Celliax Asterisk Driver
;
; Configuration file
; lines beginning with semicolon (" are ignored (commented out)
;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;
; The first interface (named line0)
[line0]
;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;
; general settings, valid on all platforms
;
;
; Default language
;
language=en
;
; Default context (is overridden with @context syntax)
;
context=default
;
; Default extension (in extensions.conf) where incoming calls land
;
extension=s
;
;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;
; Debugging settings, valid globally for all interfaces on all platforms
;
; the debug values are global for all the interfaces.
;
; default is no celliax debugging output, you **have** to activate debugging here to obtain debugging from celliax
;
; To see the debugging output you have to "set debug 100" from the Asterisk CLI or launch
; Asterisk with -ddddddddddd option, and have the logger.conf file activating debug info for console and messages
;
; You can activate each of the following separately, but you can't disactivate. Eg: debug_at=no does not subtract debug_at from debug_all
; debug_all activate all possible debugging info
;
;debug_all=yes
debug_at=yes
;debug_fbus2=yes
debug_serial=yes
debug_pbx=yes
debug_sound=yes
;debug_locks=yes
debug_call=yes
;debug_monitorlocks=yes
;debug_cvm=yes
;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;
; This is the program that will receive in stdin the incoming SMSs
sms_receiving_program=/usr/local/asterisk/usr/sbin/ciapalo
;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;
; serial settings, valid for all platforms
;
;control_device_protocol can be AT or FBUS2 or NO_SERIAL (with NO_SERIAL the speed and name of the port are ignored)
control_device_protocol=at
;speed of the serial port
control_device_speed=115200
;name of the serial port device
control_device_name=/dev/ttyACM0 ; this is a Celliax Official Device, recognized as a modem by Linux
;control_device_name=/dev/ttyUSB0 ; this is an alternative form of a Celliax Official Device, recognized as a modem by Linux
;watch the soundcard for noise (ring), because the serial port do not tell us about incoming calls (eg 3310nokia), NO_SERIAL protocol watch for acoustic ring in any case
need_acoustic_ring=0
;audio noise threshold beyond which we declare there is a ring (512 is default, put it to 1024 or 2048 if you have false positive), ignored if not watching for ring
dsp_silence_threshold=1024
;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;
; audio boost settings, valid for all platforms, to compensate for different soundcard/phone input/output signal levels
; tweak it if you get horrible (or not hearable) sound
;
;boost can be positive or negative (-40 to +40) in db
;experiment to find which values are best for your soundcard
playback_boost=0 ;
capture_boost=0 ;
;;;;;;;;;;;;;;;;;;;;;;;;;;;
; which audio device to use
;;;;;;;;;;;;;;;;;;;;;;;;;;;
;names of the sound devices in linux
;if you don't use skype on this interface (eg don't need to share the audio device with other applications while celliax is running), use the plughw:n devices (plughw:0 is the first, plughw:1 is the second soundcard, etc). They have the best latency
;if you use skype on this interface use the default:n devices (default:0 is the first, default:1 is the second soundcard, etc). They have worst latency, but you can share them
alsa_capture_device_name=plughw:1
alsa_playback_device_name=plughw:1
alsa_period_size=160
alsa_periods_in_buffer=4
;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;
; at "modem" commands settings for this interface (if controldevice_protocol is not AT they are ignored)
;
;what the modem is expecting in the part of the dial command before the number to be dialed (eg: ATD)
;at_dial_pre_number=AT+CKPD="EEE
at_dial_pre_number=ATD
;what the modem is expecting in the part of the dial command after the number to be dialed. If you want it to wait for a semicolon (;), just comment out the followin line. Wait for semicolon is the default
;at_dial_post_number=S"
;what the modem will answer after succesful execution of the dial command
at_dial_expect=OK
;command to hangup the current call
;at_hangup=AT+CKPD="EEE"
at_hangup=ATH
;what the modem will answer after succesful execution of the hangup command
at_hangup_expect=OK
;command to answer an incoming call
at_answer=ATA
;what the modem will answer after succesful execution of the answer command
at_answer_expect=OK
;pause right after serial port opening, before any command is sent, in usecs (1million usec= 1sec)
at_initial_pause=500000
;custom commands to be sent after the initial pause and before the "built in" initialization commands, and what the modem is expected to send as reply
;the first empty string stop the preinit sending
at_preinit_1=atciapa ; nonsense entry, just to show the preinit
at_preinit_1_expect=OK
at_preinit_2=
at_preinit_2_expect=
at_preinit_3=
at_preinit_3_expect=
at_preinit_4=
at_preinit_4_expect=
at_preinit_5=
at_preinit_5_expect=
;pause right after the custom preinit commands, before any "built in" command is sent, in usecs (1million usec= 1sec)
at_after_preinit_pause=500000
;custom commands to be sent after the "built in" initialization commands, and what the modem is expected to send as reply
;the first empty string stop the postinit sending
;at_postinit_1=atcucu ; nonsense entry, just to show the postinit
at_postinit_1=at+cmic=0,9 ; modem's microphone sensitivity (our spk)
at_postinit_1_expect=OK
at_postinit_2=AT+CKPD="EEE" ;send three "end" buttonpress, to have the phone in a sane state, ready to dialing with furter CKPDs ***THIS IS IMPORTANT, needed on c650***
at_postinit_2_expect=OK
at_postinit_3=AT+CSSN=1,0
at_postinit_3_expect=OK
at_postinit_4=at+sidet=0 ; no sidetone in modem, please
at_postinit_4_expect=OK
at_postinit_5=at+clvl=99 ; modem's speaker level, out mic
at_postinit_5_expect=OK
;what command to query the battery status, and what the modem is expected to send as reply
at_query_battchg=AT+CBC
at_query_battchg_expect=OK
;what command to query the signal status, and what the modem is expected to send as reply
at_query_signal=AT+CSQ
at_query_signal_expect=OK
;what command to send a DTMF
at_send_dtmf=AT+VTS
;the modem will send us the following messages to signal that the visual indicators on the phone has changed because of events (without us to ask for them), loosely based on ETSI standard (see CIND/CIEV/CMER in ETSI). Variable by manufacturer and phone model
; no service
at_indicator_noservice_string=+CIEV: 2,0
; no signal
at_indicator_nosignal_string=+CIEV: 5,0
; low signal
at_indicator_lowsignal_string=+CIEV: 5,1
; low battery
at_indicator_lowbattchg_string=+CIEV: 0,1
; no battery battery
at_indicator_nobattchg_string=+CIEV: 0,0
; call is up
at_indicator_callactive_string=+CIEV: 3,1
; call is down
at_indicator_nocallactive_string=+CIEV: 3,0
; call is no more in process
at_indicator_nocallsetup_string=+CIEV: 6,0
; call incoming is in process
at_indicator_callsetupincoming_string=+CIEV: 6,1
; call outgoing is in process
at_indicator_callsetupoutgoing_string=+CIEV: 6,2
; remote party is ringing because of our call outgoing
at_indicator_callsetupremoteringing_string=+CIEV: 6,3
;call processing unsolicited messages, proprietary for each phone manufacturer
;the modem will send us the following mesage to signal that the line is idle (eg. after an outgoing call has failed, or after hangup)
at_call_idle=+MCST: 1
;the modem will send us the following mesage to signal that there is an incoming voice call
at_call_incoming=+MCST: 2
;the modem will send us the following mesage to signal that there is an active call (eg. the remote party has answered us, or we answered them)
;at_call_active=+MCST: 3
at_call_active=+CSSI: 7
;the modem will send us the following mesage to signal that our outgoing call has failed
at_call_failed=+MCST: 65
;the modem will send us the following mesage to signal that our outgoing call is in the calling phase
;at_call_calling=+MCST: 64
at_call_calling=+CSSI: 1

View File

@ -0,0 +1,909 @@
//indent -gnu -ts4 -br -brs -cdw -lp -ce -nbfda -npcs -nprs -npsl -nbbo -saf -sai -saw -cs -bbo -nhnl -nut -sob -l90
#undef GIOVA48
#define CELLIAX_ALSA
#ifndef _CELLIAX_H_
#define _CELLIAX_H_
#ifndef CELLIAX_SVN_VERSION
#define CELLIAX_SVN_VERSION "????NO_REVISION???"
#endif
#include <asterisk/version.h> /* needed here for conditional compilation on version.h */
/* the following #defs are for LINUX */
#ifndef __CYGWIN__
#ifndef ASTERISK_VERSION_1_6_0
#ifndef ASTERISK_VERSION_1_4
#ifndef ASTERISK_VERSION_1_2
#define ASTERISK_VERSION_1_4
#if(ASTERISK_VERSION_NUM == 999999)
#undef ASTERISK_VERSION_1_4
#elif(ASTERISK_VERSION_NUM < 10400)
#undef ASTERISK_VERSION_1_4
#endif /* ASTERISK_VERSION_NUM == 999999 || ASTERISK_VERSION_NUM < 10400 */
#endif /* ASTERISK_VERSION_1_2 */
#endif /* ASTERISK_VERSION_1_4 */
#endif /* ASTERISK_VERSION_1_6_0 */
#ifdef ASTERISK_VERSION_1_2
#undef ASTERISK_VERSION_1_4
#endif /* ASTERISK_VERSION_1_2 */
#ifdef ASTERISK_VERSION_1_6_0
#define ASTERISK_VERSION_1_4
#endif /* ASTERISK_VERSION_1_6_0 */
#define CELLIAX_DIR
#undef CELLIAX_LIBCSV
#endif /* NOT __CYGWIN__ */
/* the following #defs are for WINDOWS */
#ifdef __CYGWIN__
#undef ASTERISK_VERSION_1_4
#undef ASTERISK_VERSION_1_6_0
#define CELLIAX_DIR
#undef CELLIAX_LIBCSV
#endif /* __CYGWIN__ */
/* CELLIAX_CVM */
#undef CELLIAX_CVM
/* CELLIAX_CVM */
#undef CELLIAX_FBUS2
#define CELLIAX_DIR
#define CELLIAX_LIBCSV
/* INCLUDES */
#ifdef ASTERISK_VERSION_1_6_0
#include <asterisk.h> /* some asterisk-devel package do not contains asterisk.h, but seems that is needed for the 1.6 series, at least from trunk */
#endif /* ASTERISK_VERSION_1_6_0 */
#include <unistd.h>
#include <termios.h>
#include <fcntl.h>
#include <errno.h>
#include <math.h>
#include <sys/ioctl.h>
#include <sys/time.h>
#include <string.h>
#include <sys/types.h>
#include <signal.h>
#include <ctype.h>
#ifndef ASTERISK_VERSION_1_4
#include <stdlib.h>
#include <stdio.h>
#endif /* ASTERISK_VERSION_1_4 */
#ifndef CELLIAX_ALSA
#include "pablio.h"
#endif /* CELLIAX_ALSA */
//#include <asterisk/frame.h>
#include <asterisk/channel.h>
#include <asterisk/module.h>
#include <asterisk/pbx.h>
#include <asterisk/causes.h>
#include <asterisk/cli.h>
#include <asterisk/options.h>
#include <asterisk/config.h>
#include <asterisk/endian.h>
#include <asterisk/dsp.h>
#include <asterisk/lock.h>
#include <asterisk/devicestate.h>
#include <asterisk/file.h>
#include <asterisk/say.h>
#include <asterisk/manager.h>
#ifdef ASTERISK_VERSION_1_6_0
#include <asterisk/astobj2.h>
#include <asterisk/paths.h>
#endif /* ASTERISK_VERSION_1_6_0 */
#ifdef ASTERISK_VERSION_1_4
#include <asterisk/stringfields.h>
#include <asterisk/abstract_jb.h>
#include <asterisk/logger.h>
#include <asterisk/utils.h>
#endif /* ASTERISK_VERSION_1_4 */
#ifdef ASTERISK_VERSION_1_2
#include <asterisk/utils.h>
#include <asterisk/logger.h>
#endif /* ASTERISK_VERSION_1_2 */
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
#include "celliax_spandsp.h"
#ifdef CELLIAX_LIBCSV
#include "celliax_libcsv.h"
#endif /* CELLIAX_LIBCSV */
#ifdef __CYGWIN__
#include <windows.h>
#endif /* __CYGWIN__ */
#ifndef AST_DIGIT_ANYDIG
#define AST_DIGIT_ANYDIG "0123456789*#"
#else
#warning Please review Celliax AST_DIGIT_ANYDIG
#endif
#ifndef _ASTERISK_H
#define AST_CONFIG_MAX_PATH 255 /* defined in asterisk.h, but some asterisk-devel package do not contains asterisk.h */
extern char ast_config_AST_CONFIG_DIR[AST_CONFIG_MAX_PATH];
int ast_register_atexit(void (*func) (void)); /* in asterisk.h, but some asterisk-devel package do not contains asterisk.h */
void ast_unregister_atexit(void (*func) (void)); /* in asterisk.h, but some asterisk-devel package do not contains asterisk.h */
#endif
#ifdef CELLIAX_ALSA
#define ALSA_PCM_NEW_HW_PARAMS_API
#define ALSA_PCM_NEW_SW_PARAMS_API
#include <alsa/asoundlib.h>
#endif /* CELLIAX_ALSA */
/* DEFINITIONS */
/* LUIGI RIZZO's magic */
/* boost support. BOOST_SCALE * 10 ^(BOOST_MAX/20) must
* be representable in 16 bits to avoid overflows.
*/
#define BOOST_SCALE (1<<9)
#define BOOST_MAX 40 /* slightly less than 7 bits */
/* call flow from the device */
#define FBUS2_OUTGOING_ACK 999
#define FBUS2_SECURITY_COMMAND_ON 444
#define CALLFLOW_CALL_IDLE AST_STATE_DOWN
#define CALLFLOW_INCOMING_RING AST_STATE_RING
#define CALLFLOW_CALL_DIALING AST_STATE_DIALING
#define CALLFLOW_CALL_LINEBUSY AST_STATE_BUSY
#define CALLFLOW_CALL_ACTIVE 300
#define CALLFLOW_INCOMING_HANGUP 100
#define CALLFLOW_CALL_RELEASED 101
#define CALLFLOW_CALL_NOCARRIER 102
#define CALLFLOW_CALL_INFLUX 103
#define CALLFLOW_CALL_INCOMING 104
#define CALLFLOW_CALL_FAILED 105
#define CALLFLOW_CALL_NOSERVICE 106
#define CALLFLOW_CALL_OUTGOINGRESTRICTED 107
#define CALLFLOW_CALL_SECURITYFAIL 108
#define CALLFLOW_CALL_NOANSWER 109
#define CALLFLOW_CALL_HANGUP_REQUESTED 110
//fixme CALLFLOW_GOT_IMEI to be removed
#define CALLFLOW_GOT_IMEI 1009
//fixme CALLFLOW_INCOMING_CALLID to be removed
#define CALLFLOW_INCOMING_CALLID 1019
#define AT_OK 0
#define AT_ERROR 1
/* FBUS2 (old Nokia phones) undocumented proprietary protocol */
#define FBUS2_ACK_BYTE 0x7f
#define FBUS2_CALL_CALLID 0x05
#define FBUS2_CALL_HANGUP 0x04
#define FBUS2_CALL_STATUS_OFF 0x01
#define FBUS2_CALL_STATUS_ON 0x02
#define FBUS2_COMMAND_BYTE_1 0x00
#define FBUS2_COMMAND_BYTE_2 0x01
#define FBUS2_DEVICE_PC 0x0c
#define FBUS2_DEVICE_PHONE 0x00
#define FBUS2_IRDA_FRAME_ID 0x1c
#define FBUS2_IS_LAST_FRAME 0x01
#define FBUS2_MAX_TRANSMIT_LENGTH 120
#define FBUS2_NETWORK_STATUS_REGISTERED 0x71
#define FBUS2_SECURIY_CALL_COMMAND_ANSWER 0x02
#define FBUS2_SECURIY_CALL_COMMAND_CALL 0x01
#define FBUS2_SECURIY_CALL_COMMAND_RELEASE 0x03
#define FBUS2_SECURIY_CALL_COMMANDS 0x7c
#define FBUS2_SECURIY_EXTENDED_COMMAND_ON 0x01
#define FBUS2_SECURIY_EXTENDED_COMMANDS 0x64
#define FBUS2_SECURIY_IMEI_COMMAND_GET 0x00
#define FBUS2_SECURIY_IMEI_COMMANDS 0x66
#define FBUS2_SEQNUM_MAX 0x47
#define FBUS2_SEQNUM_MIN 0x40
#define FBUS2_SERIAL_FRAME_ID 0x1e
#define FBUS2_SMS_INCOMING 0x10
#define FBUS2_TYPE_CALL 0x01
#define FBUS2_TYPE_CALL_DIVERT 0x06
#define FBUS2_TYPE_CALL_STATUS 0x0d
#define FBUS2_TYPE_NETWORK_STATUS 0x0a
#define FBUS2_TYPE_SECURITY 0x40
#define FBUS2_TYPE_SMS 0x02
#define FBUS2_TYPE_MODEL_ASK 0xd1
#define FBUS2_TYPE_MODEL_ANSWER 0xd2
//#define FBUS2_TYPE_MODEL_ANSWER 0xffffffd2
#ifdef CELLIAX_CVM
#define CVM_BUSMAIL_SEQNUM_MAX 0x7
#endif /* CELLIAX_CVM */
/* debugging bitmask */
#define DEBUG_SOUND 1
#define DEBUG_SERIAL 2
#define DEBUG_SKYPE 4
#define DEBUG_AT 8
#define DEBUG_FBUS2 16
#define DEBUG_CALL 32
#define DEBUG_LOCKS 64
#define DEBUG_PBX 128
#define DEBUG_MONITORLOCKS 256
#ifndef CELLIAX_CVM
#define DEBUG_ALL DEBUG_SOUND|DEBUG_SERIAL|DEBUG_SKYPE|DEBUG_AT|DEBUG_FBUS2|DEBUG_CALL|DEBUG_PBX|DEBUG_LOCKS|DEBUG_MONITORLOCKS
#else
#define DEBUG_CVM 512
#define DEBUG_ALL DEBUG_SOUND|DEBUG_SERIAL|DEBUG_SKYPE|DEBUG_AT|DEBUG_FBUS2|DEBUG_CALL|DEBUG_PBX|DEBUG_LOCKS|DEBUG_MONITORLOCKS|DEBUG_CVM
#endif /* CELLIAX_CVM */
/* wrappers for ast_log */
#define DEBUGA_SOUND(...) if (celliax_debug & DEBUG_SOUND) ast_log(LOG_DEBUG, "rev "CELLIAX_SVN_VERSION "[%p|%-7lx][DEBUG_SOUND %-5d][%-10s][%2d,%2d,%2d] " __VA_ARGS__ );
#define DEBUGA_SERIAL(...) if (celliax_debug & DEBUG_SERIAL) ast_log(LOG_DEBUG, "rev "CELLIAX_SVN_VERSION "[%p|%-7lx][DEBUG_SERIAL %-5d][%-10s][%2d,%2d,%2d] " __VA_ARGS__ );
#define DEBUGA_SKYPE(...) if (celliax_debug & DEBUG_SKYPE) ast_log(LOG_DEBUG, "rev "CELLIAX_SVN_VERSION "[%p|%-7lx][DEBUG_SKYPE %-5d][%-10s][%2d,%2d,%2d] " __VA_ARGS__ );
#define DEBUGA_AT(...) if (celliax_debug & DEBUG_AT) ast_log(LOG_DEBUG, "rev "CELLIAX_SVN_VERSION "[%p|%-7lx][DEBUG_AT %-5d][%-10s][%2d,%2d,%2d] " __VA_ARGS__ );
#define DEBUGA_FBUS2(...) if (celliax_debug & DEBUG_FBUS2) ast_log(LOG_DEBUG, "rev "CELLIAX_SVN_VERSION "[%p|%-7lx][DEBUG_FBUS2 %-5d][%-10s][%2d,%2d,%2d] " __VA_ARGS__ );
#define DEBUGA_CALL(...) if (celliax_debug & DEBUG_CALL) ast_log(LOG_DEBUG, "rev "CELLIAX_SVN_VERSION "[%p|%-7lx][DEBUG_CALL %-5d][%-10s][%2d,%2d,%2d] " __VA_ARGS__ );
#define DEBUGA_PBX(...) if (celliax_debug & DEBUG_PBX) ast_log(LOG_DEBUG, "rev "CELLIAX_SVN_VERSION "[%p|%-7lx][DEBUG_PBX %-5d][%-10s][%2d,%2d,%2d] " __VA_ARGS__ );
#ifdef CELLIAX_CVM
#define DEBUGA_CVM(...) if (celliax_debug & DEBUG_CVM) ast_log(LOG_DEBUG, "rev "CELLIAX_SVN_VERSION "[%p|%-7lx][DEBUG_CVM %-5d][%-10s][%2d,%2d,%2d] " __VA_ARGS__ );
#endif /* CELLIAX_CVM */
#define ERRORA(...) ast_log(LOG_ERROR, "rev "CELLIAX_SVN_VERSION "[%p|%-7lx][ERROR %-5d][%-10s][%2d,%2d,%2d] " __VA_ARGS__ );
#define NOTICA(...) ast_log(LOG_NOTICE, "rev "CELLIAX_SVN_VERSION "[%p|%-7lx][NOTICE %-5d][%-10s][%2d,%2d,%2d] " __VA_ARGS__ );
#define WARNINGA(...) ast_log(LOG_WARNING, "rev "CELLIAX_SVN_VERSION "[%p|%-7lx][WARNING %-5d][%-10s][%2d,%2d,%2d] " __VA_ARGS__ );
/* macros for logging */
#define CELLIAX_P_LOG p ? p->owner : NULL, (unsigned long)pthread_self(), __LINE__, p ? p->name ? p->name : "none" : "none", p ? p->owner ? p->owner->_state : -1 : -1, p ? p->interface_state : -1, p ? p->phone_callflow : -1
#define CELLIAX_TMP_LOG tmp ? tmp->owner : NULL, (unsigned long)pthread_self(), __LINE__, tmp ? tmp->name ? tmp->name : "none" : "none", tmp ? tmp->owner ? tmp->owner->_state : -1 : -1, tmp ? tmp->interface_state : -1, tmp ? tmp->phone_callflow : -1
/* logging wrappers for ast_mutex_lock and ast_mutex_unlock */
#define LOKKA(x) if (celliax_debug & DEBUG_LOCKS) ast_log(LOG_DEBUG, "rev "CELLIAX_SVN_VERSION "[%p|%-7lx][DEBUG_LOCKS %-5d][%-10s][%2d,%2d,%2d] going to lock %p (%s)\n", CELLIAX_P_LOG, x, x == &celliax_monlock ? "MONLOCK" : x == &celliax_iflock ? "IFLOCK" : x == &celliax_usecnt_lock ? "USECNT_LOCK" : x == &p->controldev_lock ? "CONTROLDEV_LOCK" : x == &p->fbus2_outgoing_list_lock ? "FBUS2_OUTGOING_LIST_LOCK" : "?????"); if (ast_mutex_lock(x)) ast_log(LOG_ERROR, "ast_mutex_lock failed, BAD\n"); if (celliax_debug & DEBUG_LOCKS) ast_log(LOG_DEBUG, "rev "CELLIAX_SVN_VERSION "[%p|%-7lx][DEBUG_LOCKS %-5d][%-10s][%2d,%2d,%2d] locked %p (%s)\n", CELLIAX_P_LOG, x, x == &celliax_monlock ? "MONLOCK" : x == &celliax_iflock ? "IFLOCK" : x == &celliax_usecnt_lock ? "USECNT_LOCK" : x == &p->controldev_lock ? "CONTROLDEV_LOCK" : x == &p->fbus2_outgoing_list_lock ? "FBUS2_OUTGOING_LIST_LOCK" : "?????");
#define UNLOCKA(x) if (celliax_debug & DEBUG_LOCKS) ast_log(LOG_DEBUG, "rev "CELLIAX_SVN_VERSION "[%p|%-7lx][DEBUG_LOCKS %-5d][%-10s][%2d,%2d,%2d] going to unlock %p (%s)\n", CELLIAX_P_LOG, x, x == &celliax_monlock ? "MONLOCK" : x == &celliax_iflock ? "IFLOCK" : x == &celliax_usecnt_lock ? "USECNT_LOCK" : x == &p->controldev_lock ? "CONTROLDEV_LOCK" : x == &p->fbus2_outgoing_list_lock ? "FBUS2_OUTGOING_LIST_LOCK" : "?????"); if (ast_mutex_unlock(x)) ast_log(LOG_ERROR, "ast_mutex_lock failed, BAD\n"); if (celliax_debug & DEBUG_LOCKS) ast_log(LOG_DEBUG, "rev "CELLIAX_SVN_VERSION "[%p|%-7lx][DEBUG_LOCKS %-5d][%-10s][%2d,%2d,%2d] unlocked %p (%s)\n", CELLIAX_P_LOG, x, x == &celliax_monlock ? "MONLOCK" : x == &celliax_iflock ? "IFLOCK" : x == &celliax_usecnt_lock ? "USECNT_LOCK" : x == &p->controldev_lock ? "CONTROLDEV_LOCK" : x == &p->fbus2_outgoing_list_lock ? "FBUS2_OUTGOING_LIST_LOCK" : "?????");
#define CVM_LOKKA(x) if (celliax_debug & DEBUG_LOCKS) ast_log(LOG_DEBUG, "rev "CELLIAX_SVN_VERSION "[%p|%-7lx][DEBUG_LOCKS %-5d][%-10s][%2d,%2d,%2d] going to lock %p (%s)\n", CELLIAX_P_LOG, x, x == &celliax_monlock ? "MONLOCK" : x == &celliax_iflock ? "IFLOCK" : x == &celliax_usecnt_lock ? "USECNT_LOCK" : x == &p->controldev_lock ? "CONTROLDEV_LOCK" : x == &p->cvm_busmail_outgoing_list_lock ? "FBUS2_OUTGOING_LIST_LOCK" : "?????"); if (ast_mutex_lock(x)) ast_log(LOG_ERROR, "ast_mutex_lock failed, BAD\n"); if (celliax_debug & DEBUG_LOCKS) ast_log(LOG_DEBUG, "rev "CELLIAX_SVN_VERSION "[%p|%-7lx][DEBUG_LOCKS %-5d][%-10s][%2d,%2d,%2d] locked %p (%s)\n", CELLIAX_P_LOG, x, x == &celliax_monlock ? "MONLOCK" : x == &celliax_iflock ? "IFLOCK" : x == &celliax_usecnt_lock ? "USECNT_LOCK" : x == &p->controldev_lock ? "CONTROLDEV_LOCK" : x == &p->cvm_busmail_outgoing_list_lock ? "CVM_BUSMAIL_OUTGOING_LIST_LOCK" : "?????");
#define CVM_UNLOCKA(x) if (celliax_debug & DEBUG_LOCKS) ast_log(LOG_DEBUG, "rev "CELLIAX_SVN_VERSION "[%p|%-7lx][DEBUG_LOCKS %-5d][%-10s][%2d,%2d,%2d] going to unlock %p (%s)\n", CELLIAX_P_LOG, x, x == &celliax_monlock ? "MONLOCK" : x == &celliax_iflock ? "IFLOCK" : x == &celliax_usecnt_lock ? "USECNT_LOCK" : x == &p->controldev_lock ? "CONTROLDEV_LOCK" : x == &p->cvm_busmail_outgoing_list_lock ? "FBUS2_OUTGOING_LIST_LOCK" : "?????"); if (ast_mutex_unlock(x)) ast_log(LOG_ERROR, "ast_mutex_lock failed, BAD\n"); if (celliax_debug & DEBUG_LOCKS) ast_log(LOG_DEBUG, "rev "CELLIAX_SVN_VERSION "[%p|%-7lx][DEBUG_LOCKS %-5d][%-10s][%2d,%2d,%2d] unlocked %p (%s)\n", CELLIAX_P_LOG, x, x == &celliax_monlock ? "MONLOCK" : x == &celliax_iflock ? "IFLOCK" : x == &celliax_usecnt_lock ? "USECNT_LOCK" : x == &p->controldev_lock ? "CONTROLDEV_LOCK" : x == &p->cvm_busmail_outgoing_list_lock ? "CVM_BUSMAIL_OUTGOING_LIST_LOCK" : "?????");
#define PUSHA_UNLOCKA(x) pthread_cleanup_push(celliax_unlocka_log, (void *) x);
#define POPPA_UNLOCKA(x) pthread_cleanup_pop(0);
#define MONITORLOKKA(x) if (celliax_debug & DEBUG_MONITORLOCKS) ast_log(LOG_DEBUG, "rev "CELLIAX_SVN_VERSION "[%p|%-7lx][DEBUG_MONITORLOCKS %-5d][%-10s][%2d,%2d,%2d] going to lock %p (%s)\n", CELLIAX_P_LOG, x, x == &celliax_monlock ? "MONLOCK" : x == &celliax_iflock ? "IFLOCK" : x == &celliax_usecnt_lock ? "USECNT_LOCK" : x == &p->controldev_lock ? "CONTROLDEV_LOCK" : x == &p->fbus2_outgoing_list_lock ? "FBUS2_OUTGOING_LIST_LOCK" : "?????"); if (ast_mutex_lock(x)) ast_log(LOG_ERROR, "ast_mutex_lock failed, BAD\n"); if (celliax_debug & DEBUG_MONITORLOCKS) ast_log(LOG_DEBUG, "rev "CELLIAX_SVN_VERSION "[%p|%-7lx][DEBUG_MONITORLOCKS %-5d][%-10s][%2d,%2d,%2d] locked %p (%s)\n", CELLIAX_P_LOG, x, x == &celliax_monlock ? "MONLOCK" : x == &celliax_iflock ? "IFLOCK" : x == &celliax_usecnt_lock ? "USECNT_LOCK" : x == &p->controldev_lock ? "CONTROLDEV_LOCK" : x == &p->fbus2_outgoing_list_lock ? "FBUS2_OUTGOING_LIST_LOCK" : "?????");
#define MONITORUNLOCKA(x) if (celliax_debug & DEBUG_MONITORLOCKS) ast_log(LOG_DEBUG, "rev "CELLIAX_SVN_VERSION "[%p|%-7lx][DEBUG_MONITORLOCKS %-5d][%-10s][%2d,%2d,%2d] going to unlock %p (%s)\n", CELLIAX_P_LOG, x, x == &celliax_monlock ? "MONLOCK" : x == &celliax_iflock ? "IFLOCK" : x == &celliax_usecnt_lock ? "USECNT_LOCK" : x == &p->controldev_lock ? "CONTROLDEV_LOCK" : x == &p->fbus2_outgoing_list_lock ? "FBUS2_OUTGOING_LIST_LOCK" : "?????"); if (ast_mutex_unlock(x)) ast_log(LOG_ERROR, "ast_mutex_lock failed, BAD\n"); if (celliax_debug & DEBUG_MONITORLOCKS) ast_log(LOG_DEBUG, "rev "CELLIAX_SVN_VERSION "[%p|%-7lx][DEBUG_MONITORLOCKS %-5d][%-10s][%2d,%2d,%2d] unlocked %p (%s)\n", CELLIAX_P_LOG, x, x == &celliax_monlock ? "MONLOCK" : x == &celliax_iflock ? "IFLOCK" : x == &celliax_usecnt_lock ? "USECNT_LOCK" : x == &p->controldev_lock ? "CONTROLDEV_LOCK" : x == &p->fbus2_outgoing_list_lock ? "FBUS2_OUTGOING_LIST_LOCK" : "?????");
/* macros used for config file parsing */
#define M_BOOL(tag, dst) M_F(tag, (dst) = ast_true(__val) )
#define M_END(x) x;
#define M_F(tag, f) if (!strcasecmp((__s), tag)) { f; } else
#ifdef ASTERISK_VERSION_1_6_0
#define M_START(var, val) const char *__s = var; const char *__val = val;
#else
#define M_START(var, val) char *__s = var; char *__val = val;
#endif /* ASTERISK_VERSION_1_6_0 */
#define M_STR(tag, dst) M_F(tag, ast_copy_string(dst, __val, sizeof(dst)))
#define M_UINT(tag, dst) M_F(tag, (dst) = strtoul(__val, NULL, 0) )
/* which protocol we use to control the phone through serial device */
#ifdef CELLIAX_CVM
#define PROTOCOL_CVM_BUSMAIL 5
#endif /* CELLIAX_CVM */
#define PROTOCOL_ALSA_VOICEMODEM 4
#define PROTOCOL_AT 2
#define PROTOCOL_FBUS2 1
#define PROTOCOL_NO_SERIAL 3
#ifndef GIOVA48
#define CELLIAX_FRAME_SIZE 160
#else //GIOVA48
#define CELLIAX_FRAME_SIZE 960
#endif //GIOVA48
#define AT_BUFSIZ 8192
#define AT_MESG_MAX_LENGTH 2048 /* much more than 10 SMSs */
#define AT_MESG_MAX_LINES 256 /* 256 lines, so it can contains the results of AT+CLAC, that gives all the AT commands the phone supports */
#ifdef CELLIAX_CVM
/* MAIL PRIMITIVES */
/* CVM -> CELLIAX */
#define API_PP_LOCKED_IND 0x8558 //PP locked with FP
#define API_PP_UNLOCKED_IND 0x8559 //PP out of service, unlocked from FP
#define API_PP_SETUP_IND 0x8574 //Incoming call to PP
#define API_PP_SETUP_IND_CALL_TYPE_OFFSET 0x0
#define API_PP_SETUP_IND_RING_TYPE_OFFSET 0x1
#define API_PP_SETUP_IND_CALL_EXT 0x0
#define API_PP_SETUP_IND_CALL_INT 0x1
#define API_PP_SETUP_IND_RING_INT_CALL 0x40
#define API_PP_SETUP_IND_RING_PAGE_ALL 0x46
#define API_PP_SETUP_ACK_IND 0x857F //internal connection established with FPs, waiting for handsetnumber
#define API_PP_CONNECT_IND 0x8576 //air-link established with FPs
#define API_PP_CONNECT_CFM 0x8578 //PP answered incoming call
#define API_PP_ALERT_IND 0x8581
#define API_PP_ALERT_ON_IND 0x857D
#define API_PP_ALERT_OFF_IND 0x857E
#define API_PP_SIGNAL_ON_IND 0x2F9C
#define API_PP_SIGNAL_OFF_IND 0x2F9D
#define API_PP_RELEASE_IND 0x857B
#define API_PP_RELEASE_CFM 0x857A
#define API_PP_REJECT_IND 0x8564
#define API_PP_ACCESS_RIGHTS_CFM 0x8568
#define API_PP_ACCESS_RIGHTS_REJ 0x8569
#define API_PP_DELETE_SUBS_CFM 0x8561
#define API_PP_REMOTE_DELETE_SUBS_CFM 0x2F9F
#define API_PP_CLIP_IND 0x2F93
#define API_PP_SW_STATUS_IND 0x2FC2
#define API_PP_MESSAGE_WAITING_IND 0x2FA1
#define CVM_PP_PLUG_STATUS_IND 0x2F4F
#define CVM_PP_LINE_STATUS_IND 0x2F53
#define CVM_PP_ON_KEY_IND 0x2F64
#define API_PP_READ_RSSI_CFM 0x2FC7
#define API_PP_ALERT_BROADCAST_IND 0x2FA3
/* CELLIAX -> CVM */
#define API_PP_LOCK_REQ 0x8554 //select FP to lock once
#define API_PP_SETUP_REQ 0x8571 //setup air-link PP<->FP
#define API_PP_KEYPAD_REQ 0x858A //send string for dialing
#define API_PP_CONNECT_REQ 0x8577 //answer incoming call
#define API_PP_ALERT_REQ 0x2F8D //inform FP that alering is started
#define API_PP_RELEASE_REQ 0x8579 //release connection
#define API_PP_RELEASE_RES 0x857C //confirm FP initiated release of connection
#define API_PP_REJECT_REQ 0x8565 //PP reject incoming call
#define API_PP_ACCESS_RIGHTS_REQ 0x8566 //init registration to FP
#define API_PP_DELETE_SUBS_REQ 0x8560 //deregister from FP (locally only in PP)
#define API_PP_REMOTE_DELETE_SUBS_REQ 0x2F9E //remotly deregister from FP
#define API_PP_STOP_PROTOCOL_REQ 0x2FC4 //stop protocol from running (even registration)
#define API_PP_READ_RSSI_REQ 0x2FC6 //RSSI readout request
#define API_PP_READ_RSSI_CFM 0x2FC7 //RSSI readout result
#define CVM_PP_AUDIO_OPEN_REQ 0x2F0E //Enable audio
#define CVM_PP_AUDIO_CLOSE_REQ 0x2F0F //Disable audio
#define CVM_PP_AUDIO_SET_VOLUME_REQ 0x2F1D //set volume
#define CVM_PP_AUDIO_UNMUTE_MIC_REQ 0x2F1A //unmute mic
#define CVM_PP_AUDIO_MUTE_MIC_REQ 0x2F19 //mute mic
#define CVM_PP_AUDIO_HS_PLUG_IND 0x2F1C //mute mic
#define CVM_PP_AUDIO_OPEN_ADPCM_OFF_REQ 0x2F68 //open audio even before making connection
/* END OF MAIL PRIMITIVES */
enum CvmLockState {
CVM_UNKNOWN_LOCK_STATE = 0,
CVM_UNLOCKED_TO_FP,
CVM_LOCKED_TO_FP
};
enum CvmRegisterState {
CVM_UNKNOWN_REGISTER_STATE = 0,
CVM_UNREGISTERED_TO_FP,
CVM_REGISTERED_TO_FP
};
#define BUSMAIL_MAIL_MAX_PARAMS_LENGTH 128
#define BUSMAIL_MAX_FRAME_LENGTH (BUSMAIL_MAIL_MAX_PARAMS_LENGTH + 9)
#define BUSMAIL_OFFSET_SOF 0
#define BUSMAIL_OFFSET_LEN_MSB 1
#define BUSMAIL_OFFSET_LEN_LSB 2
#define BUSMAIL_OFFSET_HEADER 3
#define BUSMAIL_OFFSET_MAIL BUSMAIL_OFFSET_MAIL_PROGRAM_ID
#define BUSMAIL_OFFSET_MAIL_PROGRAM_ID 4
#define BUSMAIL_OFFSET_MAIL_TASK_ID 5
#define BUSMAIL_OFFSET_MAIL_PRIMITIVE_MSB 7
#define BUSMAIL_OFFSET_MAIL_PRIMITIVE_LSB 6
#define BUSMAIL_OFFSET_MAIL_PARAMS 8
#define BUSMAIL_MAIL_PRIMITIVE_MSB 1
#define BUSMAIL_MAIL_PRIMITIVE_LSB 0
#define BUSMAIL_LEN_MSB 0
#define BUSMAIL_LEN_LSB 1
#define BUSMAIL_SOF 0x10
#define BUSMAIL_MAIL_PROGRAM_ID 0x0
#define BUSMAIL_MAIL_USERTASK_TASK_ID 0x0f
#define BUSMAIL_MAIL_TBHANDLE_TASK_ID 0x0
#define BUSMAIL_MAIL_TASK_ID BUSMAIL_MAIL_USERTASK_TASK_ID
#define BUSMAIL_HEADER_IC_BIT_MASK 0x80
#define BUSMAIL_HEADER_SU_BIT_MASK 0x40
#define BUSMAIL_HEADER_PF_BIT_MASK 0x08
#define BUSMAIL_HEADER_TXSEQ_MASK 0x70
#define BUSMAIL_HEADER_RXSEQ_MASK 0x07
#define BUSMAIL_HEADER_SUID_MASK 0x30
#define BUSMAIL_HEADER_UNID_MASK BUSMAIL_HEADER_SUID_MASK
#define BUSMAIL_HEADER_INFO_FRAME 0x0
#define BUSMAIL_HEADER_CTRL_FRAME 0x80
#define BUSMAIL_HEADER_CTRL_SU_FRAME 0x0
#define BUSMAIL_HEADER_CTRL_UN_FRAME 0x40
#define BUSMAIL_HEADER_UNID_SABM 0x0
#define BUSMAIL_HEADER_SUID_RR 0x0
#define BUSMAIL_HEADER_SUID_REJ 0x10
#define BUSMAIL_HEADER_SUID_RNR 0x20
#define BUSMAIL_HEADER_SABM_MASK (BUSMAIL_HEADER_IC_BIT_MASK | BUSMAIL_HEADER_SU_BIT_MASK | BUSMAIL_HEADER_UNID_MASK)
#define BUSMAIL_HEADER_SABM (BUSMAIL_HEADER_CTRL_FRAME | BUSMAIL_HEADER_CTRL_UN_FRAME | BUSMAIL_HEADER_UNID_SABM)
#define BUSMAIL_HEADER_REJ_MASK (BUSMAIL_HEADER_IC_BIT_MASK | BUSMAIL_HEADER_SU_BIT_MASK | BUSMAIL_HEADER_SUID_MASK)
#define BUSMAIL_HEADER_REJ (BUSMAIL_HEADER_CTRL_FRAME | BUSMAIL_HEADER_CTRL_SU_FRAME | BUSMAIL_HEADER_SUID_REJ)
#define BUSMAIL_HEADER_SU_FRAME_MASK (BUSMAIL_HEADER_IC_BIT_MASK | BUSMAIL_HEADER_SU_BIT_MASK)
#define BUSMAIL_HEADER_SU_FRAME (BUSMAIL_HEADER_CTRL_FRAME | BUSMAIL_HEADER_CTRL_SU_FRAME)
/*!
* \brief structure holding raw data to be send throught serial
*/
struct cvm_busmail_msg {
int valid;
unsigned char busmail_msg_buffer[BUSMAIL_MAX_FRAME_LENGTH];
unsigned int busmail_msg_len;
unsigned int tv_sec;
unsigned int tv_usec;
unsigned char txseqno;
int acknowledged;
int how_many_sent;
int sent;
struct cvm_busmail_msg *next;
struct cvm_busmail_msg *previous;
};
/*!
* \brief structure holding busmail frame, for internal use
*/
struct cvm_busmail_frame {
unsigned char busmail_sof;
unsigned char busmail_len[2];
unsigned char busmail_header;
unsigned char busmail_mail_program_id;
unsigned char busmail_mail_task_id;
unsigned char busmail_mail_primitive[2];
unsigned char busmail_mail_params_buffer[BUSMAIL_MAIL_MAX_PARAMS_LENGTH];
unsigned int busmail_mail_params_buffer_len;
unsigned char busmail_crc;
};
#endif /* CELLIAX_CVM */
/* CELLIAX INTERNAL STRUCTS */
/*!
* \brief structure for the linked list of FBUS2 Nokia proprietary protocol messages
*/
struct fbus2_msg {
int msg;
int seqnum;
int len;
int acknowledged;
int how_many_sent;
int sent;
unsigned int tv_sec;
unsigned int tv_usec;
unsigned char buffer[FBUS2_MAX_TRANSMIT_LENGTH + 10];
struct fbus2_msg *next;
struct fbus2_msg *previous;
};
/*!
* \brief structure for storing the results of AT commands, in an array of AT_MESG_MAX_LINES * AT_MESG_MAX_LENGTH chars
*/
struct s_result {
int elemcount;
char result[AT_MESG_MAX_LINES][AT_MESG_MAX_LENGTH];
};
/*!
* \brief PVT structure for a celliax interface (channel), created by celliax_mkif
*/
struct celliax_pvt {
char *name; /*!< \brief 'name' of the interface (channel) */
int interface_state; /*!< \brief 'state' of the interface (channel) */
int phone_callflow; /*!< \brief 'callflow' of the phone interface (as opposed to skype interface) */
struct ast_channel *owner; /*!< \brief channel we belong to, possibly NULL */
struct celliax_pvt *next; /*!< \brief Next interface (channel) in list */
int readpos; /*!< \brief read position above */
struct ast_frame read_f; /*!< \brief returned by oss_read */
char context[AST_MAX_EXTENSION]; /*!< \brief default Asterisk dialplan context for this interface */
char language[MAX_LANGUAGE]; /*!< \brief default Asterisk dialplan language for this interface */
char exten[AST_MAX_EXTENSION]; /*!< \brief default Asterisk dialplan extension for this interface */
struct ast_dsp *dsp; /*!< \brief Used for in-band DTMF detection */
int celliax_sound_rate; /*!< \brief rate of the sound device, in Hz, eg: 8000 */
int celliax_sound_capt_fd; /*!< \brief file descriptor for sound capture dev */
char controldevice_name[50]; /*!< \brief name of the serial device controlling the interface, possibly none */
int controldevprotocol; /*!< \brief which protocol is used for serial control of this interface */
char controldevprotocolname[50]; /*!< \brief name of the serial device controlling protocol, one of "at" "fbus2" "no_serial" "alsa_voicemodem" */
int controldevfd; /*!< \brief serial controlling file descriptor for this interface */
char callid_name[50];
char callid_number[50];
unsigned char rxm[255]; /*!< \brief read buffer for FBUS2 serial protocol controlling Nokia phones */
unsigned char array[255]; /*!< \brief read buffer for FBUS2 serial protocol controlling Nokia phones */
int arraycounter; /*!< \brief position in the 'array' read buffer for FBUS2 serial protocol controlling Nokia phones */
int seqnumfbus; /*!< \brief sequential number of FBUS2 messages, hex, revolving */
pthread_t controldev_thread; /*!< \brief serial control thread for this interface, running during the call */
struct fbus2_msg *fbus2_outgoing_list; /*!< \brief list used to track FBUS2 traffic acknowledgement and resending */
ast_mutex_t fbus2_outgoing_list_lock;
int dsp_silence_threshold;
int need_acoustic_ring; /*!< \brief bool, this interface get the incoming ring from soundcard, not serial */
char oss_write_buf[CELLIAX_FRAME_SIZE * 2];
int oss_write_dst;
char oss_read_buf[CELLIAX_FRAME_SIZE * 2 + AST_FRIENDLY_OFFSET]; /*!< in bytes */
time_t celliax_serial_synced_timestamp;
time_t celliax_serial_sync_period;
time_t audio_play_reset_timestamp;
time_t audio_capture_reset_timestamp;
speed_t controldevice_speed;
struct s_result line_array;
struct timeval ringtime;
struct timeval call_incoming_time;
int at_result;
char at_dial_pre_number[64];
char at_dial_post_number[64];
char at_dial_expect[64];
unsigned int at_early_audio;
char at_hangup[64];
char at_hangup_expect[64];
char at_answer[64];
char at_answer_expect[64];
unsigned int at_initial_pause;
char at_preinit_1[64];
char at_preinit_1_expect[64];
char at_preinit_2[64];
char at_preinit_2_expect[64];
char at_preinit_3[64];
char at_preinit_3_expect[64];
char at_preinit_4[64];
char at_preinit_4_expect[64];
char at_preinit_5[64];
char at_preinit_5_expect[64];
unsigned int at_after_preinit_pause;
char at_postinit_1[64];
char at_postinit_1_expect[64];
char at_postinit_2[64];
char at_postinit_2_expect[64];
char at_postinit_3[64];
char at_postinit_3_expect[64];
char at_postinit_4[64];
char at_postinit_4_expect[64];
char at_postinit_5[64];
char at_postinit_5_expect[64];
char at_send_dtmf[64];
char at_query_battchg[64];
char at_query_battchg_expect[64];
char at_query_signal[64];
char at_query_signal_expect[64];
char at_call_idle[64];
char at_call_incoming[64];
char at_call_active[64];
char at_call_failed[64];
char at_call_calling[64];
#define CIEV_STRING_SIZE 64
char at_indicator_noservice_string[64];
char at_indicator_nosignal_string[64];
char at_indicator_lowsignal_string[64];
char at_indicator_lowbattchg_string[64];
char at_indicator_nobattchg_string[64];
char at_indicator_callactive_string[64];
char at_indicator_nocallactive_string[64];
char at_indicator_nocallsetup_string[64];
char at_indicator_callsetupincoming_string[64];
char at_indicator_callsetupoutgoing_string[64];
char at_indicator_callsetupremoteringing_string[64];
int at_indicator_callp;
int at_indicator_callsetupp;
int at_indicator_roamp;
int at_indicator_battchgp;
int at_indicator_servicep;
int at_indicator_signalp;
int at_has_clcc;
int at_has_ecam;
double playback_boost;
double capture_boost;
int stripmsd;
int controldev_dead;
ast_mutex_t controldev_lock;
struct timeval fbus2_list_tv;
struct timezone fbus2_list_tz;
dtmf_rx_state_t dtmf_state;
int dtmf_inited;
pthread_t sync_thread;
pthread_t celliax_sound_monitor_thread;
pthread_t celliax_serial_monitor_thread;
int celliax_serial_monitoring;
int skype; /*!< \brief config flag, bool, Skype support on this interface (0 if false, -1 if true) */
int phonebook_listing;
int phonebook_querying;
int phonebook_listing_received_calls;
int phonebook_first_entry;
int phonebook_last_entry;
int phonebook_number_lenght;
int phonebook_text_lenght;
FILE *phonebook_writing_fp;
int celliax_dir_entry_extension_prefix;
#ifdef CELLIAX_CVM
char cvm_subsc_1_pin[20];
char cvm_subsc_2_pin[20];
int cvm_subsc_no;
int cvm_lock_state;
int cvm_register_state;
int cvm_volume_level;
int cvm_celliax_serial_delay;
unsigned char cvm_handset_no;
unsigned char cvm_fp_is_cvm;
unsigned char cvm_rssi;
unsigned char busmail_rxseq_cvm_last; /*!< \brief sequential number of BUSMAIL messages, (0-7) */
unsigned char busmail_txseq_celliax_last; /*!< \brief sequential number of BUSMAIL messages, (0-7) */
struct cvm_busmail_msg *cvm_busmail_outgoing_list; /*!< \brief list used to track CVM BUSMAIL traffic acknowledgement and resending */
ast_mutex_t cvm_busmail_outgoing_list_lock;
struct timeval cvm_busmail_list_tv;
struct timezone cvm_busmail_list_tz;
#endif /* CELLIAX_CVM */
#ifdef CELLIAX_LIBCSV
int csv_separator_is_semicolon;
int csv_complete_name_pos;
int csv_email_pos;
int csv_home_phone_pos;
int csv_mobile_phone_pos;
int csv_business_phone_pos;
int csv_first_row_is_title;
int csv_fields;
int csv_rows;
char csv_complete_name[256];
char csv_email[256];
char csv_home_phone[256];
char csv_mobile_phone[256];
char csv_business_phone[256];
#endif /* CELLIAX_LIBCSV */
int audio_play_reset_period;
char at_cmgw[16];
int isInputInterleaved;
int isOutputInterleaved;
int numInputChannels;
int numOutputChannels;
int framesPerCallback;
#ifndef CELLIAX_ALSA
PABLIO_Stream *stream;
#endif /* CELLIAX_ALSA */
int audiopipe[2];
int speexecho;
int speexpreprocess;
int portaudiocindex; /*!< \brief Index of the Portaudio capture audio device */
int portaudiopindex; /*!< \brief Index of the Portaudio playback audio device */
int control_to_send;
int unread_sms_msg_id;
int reading_sms_msg;
char sms_message[4800];
int sms_cnmi_not_supported;
char sms_receiving_program[256];
int celliax_dir_prefix;
int no_ucs2;
#ifdef CELLIAX_ALSA
snd_pcm_t *alsac; /*!< \brief handle of the ALSA capture audio device */
snd_pcm_t *alsap; /*!< \brief handle of the ALSA playback audio device */
char alsacname[50]; /*!< \brief name of the ALSA capture audio device */
char alsapname[50]; /*!< \brief name of the ALSA playback audio device */
int alsa_period_size; /*!< \brief ALSA period_size, in byte */
int alsa_periods_in_buffer; /*!< \brief how many periods in ALSA buffer, to calculate buffer_size */
unsigned long int alsa_buffer_size; /*!< \brief ALSA buffer_size, in byte */
int alsawrite_filled;
int alsa_capture_is_mono;
int alsa_play_is_mono;
struct pollfd pfd;
#endif /* CELLIAX_ALSA */
struct timeval dtmf_timestamp;
};
/* LOCKS */
/*! \brief Protect the celliax_usecnt */
AST_MUTEX_DEFINE_STATIC(celliax_usecnt_lock);
/*! \brief Protect the monitoring thread, so only one process can kill or start it, and not
* when it's doing something critical. */
AST_MUTEX_DEFINE_STATIC(celliax_monlock);
/*! \brief Protect the interfaces list */
AST_MUTEX_DEFINE_STATIC(celliax_iflock);
/* FUNCTIONS */
/* module helpers functions */
int load_module(void);
int unload_module(void);
int usecount(void);
char *description(void);
char *key(void);
/* chan_celliax internal functions */
void celliax_unlocka_log(void *x);
#ifdef CELLIAX_FBUS2
int celliax_serial_sync_FBUS2(struct celliax_pvt *p);
int celliax_serial_answer_FBUS2(struct celliax_pvt *p);
int celliax_serial_call_FBUS2(struct celliax_pvt *p, char *dstr);
int celliax_serial_hangup_FBUS2(struct celliax_pvt *p);
int celliax_serial_config_FBUS2(struct celliax_pvt *p);
int celliax_serial_read_FBUS2(struct celliax_pvt *p);
int celliax_serial_getstatus_FBUS2(struct celliax_pvt *p);
int celliax_serial_get_seqnum_FBUS2(struct celliax_pvt *p);
int celliax_serial_security_command_FBUS2(struct celliax_pvt *p);
int celliax_serial_send_FBUS2(struct celliax_pvt *p, int len, unsigned char *buffer2);
int celliax_serial_list_acknowledge_FBUS2(struct celliax_pvt *p, int seqnum);
int celliax_serial_send_if_time_FBUS2(struct celliax_pvt *p);
int celliax_serial_write_FBUS2(struct celliax_pvt *p, unsigned char *MsgBuffer,
int MsgLength, unsigned char MsgType);
int celliax_serial_send_ack_FBUS2(struct celliax_pvt *p, unsigned char MsgType,
unsigned char MsgSequence);
struct fbus2_msg *celliax_serial_list_init_FBUS2(struct celliax_pvt *p);
int celliax_serial_list_print_FBUS2(struct celliax_pvt *p, struct fbus2_msg *list);
#endif /* CELLIAX_FBUS2 */
#ifdef CELLIAX_CVM
int celliax_serial_sync_CVM_BUSMAIL(struct celliax_pvt *p);
int celliax_serial_answer_CVM_BUSMAIL(struct celliax_pvt *p);
int celliax_serial_call_CVM_BUSMAIL(struct celliax_pvt *p, char *dstr);
int celliax_serial_hangup_CVM_BUSMAIL(struct celliax_pvt *p);
int celliax_serial_config_CVM_BUSMAIL(struct celliax_pvt *p);
int celliax_serial_read_CVM_BUSMAIL(struct celliax_pvt *p);
int celliax_serial_getstatus_CVM_BUSMAIL(struct celliax_pvt *p);
int celliax_serial_send_CVM_BUSMAIL(struct celliax_pvt *p, int len,
unsigned char *mesg_ptr);
int celliax_serial_list_acknowledge_CVM_BUSMAIL(struct celliax_pvt *p,
unsigned char TxSeqNo);
int celliax_serial_send_if_time_CVM_BUSMAIL(struct celliax_pvt *p);
int celliax_serial_write_CVM_BUSMAIL(struct celliax_pvt *p,
struct cvm_busmail_frame *busmail_frame);
int celliax_serial_send_ctrl_frame_CVM_BUSMAIL(struct celliax_pvt *p,
unsigned char FrameType);
int celliax_serial_send_info_frame_CVM_BUSMAIL(struct celliax_pvt *p, int FrameType,
unsigned char ParamsLen,
unsigned char *Params);
struct cvm_busmail_msg *celliax_serial_list_init_CVM_BUSMAIL(struct celliax_pvt *p);
int celliax_serial_list_print_CVM_BUSMAIL(struct celliax_pvt *p,
struct cvm_busmail_msg *list);
int celliax_serial_lists_free_CVM_BUSMAIL(struct celliax_pvt *p);
#endif /* CELLIAX_CVM */
/* CHAN_CELLIAX.C */
int celliax_queue_control(struct ast_channel *chan, int control);
struct celliax_pvt *celliax_console_find_desc(char *dev);
int celliax_serial_call(struct celliax_pvt *p, char *dstr);
/* FUNCTIONS */
/* PBX interface functions */
struct ast_channel *celliax_request(const char *type, int format, void *data, int *cause);
int celliax_answer(struct ast_channel *c);
int celliax_hangup(struct ast_channel *c);
int celliax_call(struct ast_channel *c, char *idest, int timeout);
struct ast_frame *celliax_read(struct ast_channel *chan);
int celliax_write(struct ast_channel *c, struct ast_frame *f);
int celliax_fixup(struct ast_channel *oldchan, struct ast_channel *newchan);
#ifndef ASTERISK_VERSION_1_4
int celliax_indicate(struct ast_channel *c, int cond);
#else
int celliax_indicate(struct ast_channel *c, int cond, const void *data, size_t datalen);
#endif
int celliax_devicestate(void *data);
#ifdef ASTERISK_VERSION_1_4
int celliax_senddigit_begin(struct ast_channel *ast, char digit);
int celliax_senddigit_end(struct ast_channel *ast, char digit, unsigned int duration);
#else /* ASTERISK_VERSION_1_4 */
int celliax_senddigit(struct ast_channel *ast, char digit);
#endif /* ASTERISK_VERSION_1_4 */
/* chan_celliax internal functions */
struct celliax_pvt *celliax_mkif(struct ast_config *cfg, char *ctg,
int is_first_category);
struct ast_channel *celliax_new(struct celliax_pvt *p, int state, char *context);
int celliax_restart_monitor(void);
void *celliax_do_monitor(void *data);
void *celliax_do_audio_monitor(void *data);
int celliax_sound_boost(struct ast_frame *f, double boost);
int celliax_sound_init(struct celliax_pvt *p);
int celliax_sound_shutdown(struct celliax_pvt *p);
struct ast_frame *celliax_sound_dsp_analize(struct celliax_pvt *p, struct ast_frame *f,
int dsp_silence_threshold);
int celliax_sound_dsp_set(struct celliax_pvt *p, int dsp_silence_threshold,
int silence_suppression);
struct ast_frame *celliax_sound_read(struct celliax_pvt *p);
int celliax_sound_write(struct celliax_pvt *p, struct ast_frame *f);
int celliax_sound_monitor(struct celliax_pvt *p);
void *celliax_do_controldev_thread(void *data);
int celliax_serial_init(struct celliax_pvt *p, speed_t controldevice_speed);
int celliax_serial_monitor(struct celliax_pvt *p);
int celliax_serial_read(struct celliax_pvt *p);
int celliax_serial_sync(struct celliax_pvt *p);
int celliax_serial_getstatus(struct celliax_pvt *p);
int celliax_serial_config(struct celliax_pvt *p);
int celliax_serial_hangup(struct celliax_pvt *p);
int celliax_serial_answer(struct celliax_pvt *p);
#define celliax_serial_write_AT_expect(P, D, S) celliax_serial_write_AT_expect1(P, D, S, 1, 2)
#define celliax_serial_write_AT_expect_noexpcr(P, D, S) celliax_serial_write_AT_expect1(P, D, S, 0, 2)
#define celliax_serial_write_AT_expect_noexpcr_tout(P, D, S, T) celliax_serial_write_AT_expect1(P, D, S, 0, T)
// 20.5 sec timeout, used for querying the SIM and sending SMSs
#define celliax_serial_write_AT_expect_longtime(P, D, S) celliax_serial_write_AT_expect1(P, D, S, 1, 20)
#define celliax_serial_write_AT_expect_longtime_noexpcr(P, D, S) celliax_serial_write_AT_expect1(P, D, S, 0, 20)
int celliax_serial_write_AT(struct celliax_pvt *p, const char *data);
int celliax_serial_write_AT_nocr(struct celliax_pvt *p, const char *data);
int celliax_serial_write_AT_ack(struct celliax_pvt *p, const char *data);
int celliax_serial_write_AT_ack_nocr_longtime(struct celliax_pvt *p, const char *data);
int celliax_serial_write_AT_noack(struct celliax_pvt *p, const char *data);
int celliax_serial_write_AT_expect1(struct celliax_pvt *p, const char *data,
const char *expected_string, int expect_crlf,
int seconds);
int celliax_serial_AT_expect(struct celliax_pvt *p, const char *expected_string,
int expect_crlf, int seconds);
int celliax_serial_read_AT(struct celliax_pvt *p, int look_for_ack, int timeout_usec,
int timeout_sec, const char *expected_string, int expect_crlf);
int celliax_serial_answer_AT(struct celliax_pvt *p);
int celliax_serial_hangup_AT(struct celliax_pvt *p);
int celliax_serial_config_AT(struct celliax_pvt *p);
int celliax_serial_call_AT(struct celliax_pvt *p, char *dstr);
int celliax_serial_sync_AT(struct celliax_pvt *p);
int celliax_serial_getstatus_AT(struct celliax_pvt *p);
#ifdef ASTERISK_VERSION_1_6_0
void celliax_store_boost(const char *s, double *boost);
#else
void celliax_store_boost(char *s, double *boost);
#endif /* ASTERISK_VERSION_1_6_0 */
int celliax_console_set_active(int fd, int argc, char *argv[]);
#ifndef ASTERISK_VERSION_1_6_0
int celliax_console_hangup(int fd, int argc, char *argv[]);
#else /* ASTERISK_VERSION_1_6_0 */
char *celliax_console_hangup(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a);
#endif /* ASTERISK_VERSION_1_6_0 */
int celliax_console_playback_boost(int fd, int argc, char *argv[]);
int celliax_console_capture_boost(int fd, int argc, char *argv[]);
int celliax_console_celliax(int fd, int argc, char *argv[]);
#ifdef CELLIAX_DIR
int celliax_console_celliax_dir_import(int fd, int argc, char *argv[]);
int celliax_console_celliax_dir_export(int fd, int argc, char *argv[]);
#endif /* CELLIAX_DIR */
int celliax_console_dial(int fd, int argc, char *argv[]);
int celliax_console_sendsms(int fd, int argc, char *argv[]);
int celliax_portaudio_init(struct celliax_pvt *p);
int celliax_portaudio_shutdown(struct celliax_pvt *p);
struct ast_frame *celliax_portaudio_read(struct celliax_pvt *p);
int celliax_portaudio_write(struct celliax_pvt *p, struct ast_frame *f);
int celliax_portaudio_devlist(struct celliax_pvt *p);
#ifdef CELLIAX_DIR
int celliax_dir_exec(struct ast_channel *chan, void *data);
int celliax_dir_create_extensions(void);
int celliax_dir_play_mailbox_owner(struct ast_channel *chan, char *context,
char *dialcontext, char *ext, char *name);
struct ast_config *celliax_dir_realtime(char *context);
int celliax_dir_do(struct ast_channel *chan, struct ast_config *cfg, char *context,
char *dialcontext, char digit, int last);
#endif /* CELLIAX_DIR */
#ifdef CELLIAX_LIBCSV
void celliax_cb1(char *s, size_t len, void *data);
void celliax_cb2(char c, void *data);
#endif /* CELLIAX_LIBCSV */
int celliax_sendsms(struct ast_channel *c, void *data);
int celliax_console_echo(int fd, int argc, char *argv[]);
int celliax_console_at(int fd, int argc, char *argv[]);
#ifdef ASTERISK_VERSION_1_2
int celliax_manager_sendsms(struct mansession *s, struct message *m);
#endif //ASTERISK_VERSION_1_2
#ifdef ASTERISK_VERSION_1_4
int celliax_manager_sendsms(struct mansession *s, const struct message *m);
#endif //ASTERISK_VERSION_1_4
int utf_to_ucs2(struct celliax_pvt *p, char *utf_in, size_t inbytesleft, char *ucs2_out,
size_t outbytesleft);
int ucs2_to_utf8(struct celliax_pvt *p, char *ucs2_in, char *utf8_out,
size_t outbytesleft);
#endif /* _CELLIAX_H_ */
#ifdef CELLIAX_ALSA
int console_alsa_period(int fd, int argc, char *argv[]);
#endif /* CELLIAX_ALSA */
#ifdef CELLIAX_ALSA
int alsa_init(struct celliax_pvt *p);
int alsa_shutdown(struct celliax_pvt *p);
snd_pcm_t *alsa_open_dev(struct celliax_pvt *p, snd_pcm_stream_t stream);
struct ast_frame *alsa_read(struct celliax_pvt *p);
int alsa_write(struct celliax_pvt *p, struct ast_frame *f);
#endif /* CELLIAX_ALSA */

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,356 @@
/*
libcsv - parse and write csv data
Copyright (C) 2007 Robert Gamble
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#if ___STDC_VERSION__ >= 199901L
# include <stdint.h>
#else
# define SIZE_MAX ((size_t)-1) /* C89 doesn't have stdint.h or SIZE_MAX */
#endif
#include "celliax_libcsv.h"
#define VERSION "1.0.0"
#define ROW_NOT_BEGUN 0
#define FIELD_NOT_BEGUN 1
#define FIELD_BEGUN 2
#define FIELD_MIGHT_HAVE_ENDED 3
/*
Explanation of states
ROW_NOT_BEGUN There have not been any fields encountered for this row
FIELD_NOT_BEGUN There have been fields but we are currently not in one
FIELD_BEGUN We are in a field
FIELD_MIGHT_HAVE_ENDED
We encountered a double quote inside a quoted field, the
field is either ended or the quote is literal
*/
#define MEM_BLK_SIZE 128
#define SUBMIT_FIELD(p) \
do { \
if (!(p)->quoted) \
(p)->entry_pos -= (p)->spaces; \
if (cb1) \
cb1(p->entry_buf, (p)->entry_pos, data); \
(p)->pstate = FIELD_NOT_BEGUN; \
(p)->entry_pos = (p)->quoted = (p)->spaces = 0; \
} while (0)
#define SUBMIT_ROW(p, c) \
do { \
if (cb2) \
cb2(c, data); \
(p)->pstate = ROW_NOT_BEGUN; \
(p)->entry_pos = (p)->quoted = (p)->spaces = 0; \
} while (0)
#define SUBMIT_CHAR(p, c) ((p)->entry_buf[(p)->entry_pos++] = (c))
static char *csv_errors[] = {"success",
"error parsing data while strict checking enabled",
"memory exhausted while increasing buffer size",
"data size too large",
"invalid status code"};
int
csv_error(struct csv_parser *p)
{
return p->status;
}
char *
csv_strerror(int status)
{
if (status >= CSV_EINVALID || status < 0)
return csv_errors[CSV_EINVALID];
else
return csv_errors[status];
}
int
csv_opts(struct csv_parser *p, unsigned char options)
{
if (p == NULL)
return -1;
p->options = options;
return 0;
}
int
csv_init(struct csv_parser **p, unsigned char options)
{
/* Initialize a csv_parser object returns 0 on success, -1 on error */
if (p == NULL)
return -1;
if ((*p = malloc(sizeof(struct csv_parser))) == NULL)
return -1;
if ( ((*p)->entry_buf = malloc(MEM_BLK_SIZE)) == NULL ) {
free(*p);
return -1;
}
(*p)->pstate = ROW_NOT_BEGUN;
(*p)->quoted = 0;
(*p)->spaces = 0;
(*p)->entry_pos = 0;
(*p)->entry_size = MEM_BLK_SIZE;
(*p)->status = 0;
(*p)->options = options;
return 0;
}
void
csv_free(struct csv_parser *p)
{
/* Free the entry_buffer and the csv_parser object */
if (p == NULL)
return;
if (p->entry_buf)
free(p->entry_buf);
free(p);
return;
}
int
csv_fini(struct csv_parser *p, void (*cb1)(char *, size_t, void *), void (*cb2)(char c, void *), void *data)
{
/* Finalize parsing. Needed, for example, when file does not end in a newline */
if (p == NULL)
return -1;
switch (p->pstate) {
case FIELD_MIGHT_HAVE_ENDED:
p->entry_pos -= p->spaces + 1; /* get rid of spaces and original quote */
case FIELD_NOT_BEGUN:
case FIELD_BEGUN:
SUBMIT_FIELD(p);
SUBMIT_ROW(p, 0);
case ROW_NOT_BEGUN: /* Already ended properly */
;
}
p->spaces = p->quoted = p->entry_pos = p->status = 0;
p->pstate = ROW_NOT_BEGUN;
return 0;
}
size_t
csv_parse(struct csv_parser *p, const char *s, size_t len, void (*cb1)(char *, size_t, void *), void (*cb2)(char c, void *), void *data)
{
char c; /* The character we are currently processing */
size_t pos = 0; /* The number of characters we have processed in this call */
while (pos < len) {
/* Check memory usage */
if (p->entry_pos == p->entry_size) {
size_t to_add = MEM_BLK_SIZE;
void *vp;
while ( p->entry_size >= SIZE_MAX - to_add )
to_add /= 2;
if (!to_add) {
p->status = CSV_ETOOBIG;
return pos;
}
while ((vp = realloc(p->entry_buf, p->entry_size + to_add)) == NULL) {
to_add /= 2;
if (!to_add) {
p->status = CSV_ENOMEM;
return pos;
}
}
p->entry_buf = vp;
p->entry_size += to_add;
}
c = s[pos++];
switch (p->pstate) {
case ROW_NOT_BEGUN:
case FIELD_NOT_BEGUN:
if (c == CSV_SPACE || c == CSV_TAB) { /* Space or Tab */
continue;
} else if (c == CSV_CR || c == CSV_LF) { /* Carriage Return or Line Feed */
if (p->pstate == FIELD_NOT_BEGUN) {
SUBMIT_FIELD(p);
SUBMIT_ROW(p, c);
} else { /* ROW_NOT_BEGUN */
/* Don't submit empty rows by default */
if (p->options & CSV_REPALL_NL) {
SUBMIT_ROW(p, c);
}
}
continue;
} else if ( (!(p->options & CSV_USE_SEMICOLON_SEPARATOR) && (c == CSV_COMMA)) || ((p->options & CSV_USE_SEMICOLON_SEPARATOR) && (c == CSV_SEMICOLON)) ) { /* Comma or SemiColon */
SUBMIT_FIELD(p);
break;
} else if (c == CSV_QUOTE) { /* Quote */
p->pstate = FIELD_BEGUN;
p->quoted = 1;
} else { /* Anything else */
p->pstate = FIELD_BEGUN;
p->quoted = 0;
SUBMIT_CHAR(p, c);
}
break;
case FIELD_BEGUN:
if (c == CSV_QUOTE) { /* Quote */
if (p->quoted) {
SUBMIT_CHAR(p, c);
p->pstate = FIELD_MIGHT_HAVE_ENDED;
} else {
/* STRICT ERROR - double quote inside non-quoted field */
if (p->options & CSV_STRICT) {
p->status = CSV_EPARSE;
return pos-1;
}
SUBMIT_CHAR(p, c);
p->spaces = 0;
}
} else if ((!(p->options & CSV_USE_SEMICOLON_SEPARATOR) && (c == CSV_COMMA)) || ((p->options & CSV_USE_SEMICOLON_SEPARATOR) && (c == CSV_SEMICOLON))) { /* Comma or SemiColon */
if (p->quoted) {
SUBMIT_CHAR(p, c);
} else {
SUBMIT_FIELD(p);
}
} else if (c == CSV_CR || c == CSV_LF) { /* Carriage Return or Line Feed */
if (!p->quoted) {
SUBMIT_FIELD(p);
SUBMIT_ROW(p, c);
} else {
SUBMIT_CHAR(p, c);
}
} else if (!p->quoted && (c == CSV_SPACE || c == CSV_TAB)) { /* Tab or space for non-quoted field */
SUBMIT_CHAR(p, c);
p->spaces++;
} else { /* Anything else */
SUBMIT_CHAR(p, c);
p->spaces = 0;
}
break;
case FIELD_MIGHT_HAVE_ENDED:
/* This only happens when a quote character is encountered in a quoted field */
if ((!(p->options & CSV_USE_SEMICOLON_SEPARATOR) && (c == CSV_COMMA)) || ((p->options & CSV_USE_SEMICOLON_SEPARATOR) && (c == CSV_SEMICOLON))) { /* Comma or SemiColon */
p->entry_pos -= p->spaces + 1; /* get rid of spaces and original quote */
SUBMIT_FIELD(p);
} else if (c == CSV_CR || c == CSV_LF) { /* Carriage Return or Line Feed */
p->entry_pos -= p->spaces + 1; /* get rid of spaces and original quote */
SUBMIT_FIELD(p);
SUBMIT_ROW(p, c);
} else if (c == CSV_SPACE || c == CSV_TAB) { /* Space or Tab */
SUBMIT_CHAR(p, c);
p->spaces++;
} else if (c == CSV_QUOTE) { /* Quote */
if (p->spaces) {
/* STRICT ERROR - unescaped double quote */
if (p->options & CSV_STRICT) {
p->status = CSV_EPARSE;
return pos-1;
}
p->spaces = 0;
SUBMIT_CHAR(p, c);
} else {
/* Two quotes in a row */
p->pstate = FIELD_BEGUN;
}
} else { /* Anything else */
/* STRICT ERROR - unescaped double quote */
if (p->options & CSV_STRICT) {
p->status = CSV_EPARSE;
return pos-1;
}
p->pstate = FIELD_BEGUN;
p->spaces = 0;
SUBMIT_CHAR(p, c);
}
break;
default:
break;
}
}
return pos;
}
size_t
csv_write (char *dest, size_t dest_size, const char *src, size_t src_size)
{
size_t chars = 0;
if (src == NULL)
return 0;
if (dest == NULL)
dest_size = 0;
if (dest_size > 0)
*dest++ = '"';
chars++;
while (src_size) {
if (*src == '"') {
if (dest_size > chars)
*dest++ = '"';
if (chars < SIZE_MAX) chars++;
}
if (dest_size > chars)
*dest++ = *src;
if (chars < SIZE_MAX) chars++;
src_size--;
src++;
}
if (dest_size > chars)
*dest = '"';
if (chars < SIZE_MAX) chars++;
return chars;
}
int
csv_fwrite (FILE *fp, const char *src, size_t src_size)
{
if (fp == NULL || src == NULL)
return 0;
if (fputc('"', fp) == EOF)
return EOF;
while (src_size) {
if (*src == '"') {
if (fputc('"', fp) == EOF)
return EOF;
}
if (fputc(*src, fp) == EOF)
return EOF;
src_size--;
src++;
}
if (fputc('"', fp) == EOF) {
return EOF;
}
return 0;
}

View File

@ -0,0 +1,48 @@
#ifndef LIBCSV_H__
#define LIBCSV_H__
#include <stdlib.h>
#include <stdio.h>
/* Error Codes */
#define CSV_SUCCESS 0
#define CSV_EPARSE 1 /* Parse error in strict mode */
#define CSV_ENOMEM 2 /* Out of memory while increasing buffer size */
#define CSV_ETOOBIG 3 /* Buffer larger than SIZE_MAX needed */
#define CSV_EINVALID 4 /* Invalid code, should never receive this from csv_error */
/* parser options */
#define CSV_STRICT 1 /* enable strict mode */
#define CSV_REPALL_NL 2 /* report all unquoted carriage returns and linefeeds */
#define CSV_USE_SEMICOLON_SEPARATOR 4 /* use CSV_SEMICOLON as separator instead of CSV_COMMA */
/* Character values */
#define CSV_TAB 0x09
#define CSV_SPACE 0x20
#define CSV_CR 0x0d
#define CSV_LF 0x0a
#define CSV_COMMA 0x2c
#define CSV_SEMICOLON 0x3b /* ; */
#define CSV_QUOTE 0x22
struct csv_parser {
int pstate; /* Parser state */
int quoted; /* Is the current field a quoted field? */
size_t spaces; /* Number of continious spaces after quote or in a non-quoted field */
char * entry_buf; /* Entry buffer */
size_t entry_pos; /* Current position in entry_buf (and current size of entry) */
size_t entry_size; /* Size of buffer */
int status; /* Operation status */
unsigned char options;
};
int csv_init(struct csv_parser **p, unsigned char options);
int csv_fini(struct csv_parser *p, void (*cb1)(char *, size_t, void *), void (*cb2)(char, void *), void *data);
void csv_free(struct csv_parser *p);
int csv_error(struct csv_parser *p);
char * csv_strerror(int error);
size_t csv_parse(struct csv_parser *p, const char *s, size_t len, void (*cb1)(char *, size_t, void *), void (*cb2)(char, void *), void *data);
size_t csv_write(char *dest, size_t dest_size, const char *src, size_t src_size);
int csv_fwrite(FILE *fp, const char *src, size_t src_size);
int csv_opts(struct csv_parser *p, unsigned char options);
#endif

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,8 @@
#!/usr/bin/perl
open(FILEOUT, ">> /tmp/smses_received");
while(<>){
print FILEOUT $_ ;
printf FILEOUT "\n" ;
}
close(FILEOUT);

View File

@ -0,0 +1,6 @@
defaults.pcm.rate_converter "linear"
#defaults.pcm.rate_converter "speexrate"
#defaults.pcm.dmix.rate 16000
#defaults.pcm.dsnoop.rate 16000

View File

@ -0,0 +1,23 @@
<configuration name="gsmopen.conf" description="GSMopen Configuration">
<global_settings>
<param name="debug" value="8"/>
<param name="dialplan" value="XML"/>
<param name="context" value="default"/>
<param name="hold-music" value="$${moh_uri}"/>
<param name="destination" value="9999"/>
</global_settings>
<!-- one entry here per gsmopen interface -->
<per_interface_settings>
<interface id="1" name="interface1">
<param name="hold-music" value="$${moh_uri}"/>
<param name="dialplan" value="XML"/>
<param name="context" value="default"/>
<param name="destination" value="5000"/>
<param name="alsacname" value="plughw:1"/>
<param name="alsapname" value="plughw:1"/>
<param name="controldevice_name" value="/dev/ttyACM0"/>
</interface>
<!-- following interfaces are commented out!
-->
</per_interface_settings>
</configuration>

View File

@ -0,0 +1,110 @@
<configuration name="gsmopen.conf" description="GSMopen Configuration">
<global_settings>
<param name="debug" value="8"/>
<param name="dialplan" value="XML"/>
<param name="context" value="default"/>
<param name="hold-music" value="$${moh_uri}"/>
<param name="destination" value="9999"/>
</global_settings>
<!-- one entry here per gsmopen interface -->
<per_interface_settings>
<!-- following interfaces are commented out!
-->
<interface id="1" name="interface2001">
<param name="hold-music" value="$${moh_uri}"/>
<param name="dialplan" value="XML"/>
<param name="context" value="default"/>
<param name="destination" value="2000"/>
<param name="alsacname" value="plughw:2"/>
<param name="alsapname" value="plughw:2"/>
<param name="controldevice_name" value="/dev/ttyACM2"/>
<param name="no_sound" value="0"/>
</interface>
<interface id="2" name="interface4001">
<param name="hold-music" value="$${moh_uri}"/>
<param name="dialplan" value="XML"/>
<param name="context" value="default"/>
<param name="destination" value="2000"/>
<param name="alsacname" value="plughw:1"/>
<param name="alsapname" value="plughw:1"/>
<param name="controldevice_name" value="/dev/ttyACM1"/>
<param name="no_sound" value="0"/>
</interface>
<interface id="3" name="interface3">
<param name="hold-music" value="$${moh_uri}"/>
<param name="dialplan" value="XML"/>
<param name="context" value="default"/>
<param name="destination" value="2000"/>
<param name="alsacname" value="plughw:3"/>
<param name="alsapname" value="plughw:3"/>
<param name="controldevice_name" value="/dev/ttyACM0"/>
<param name="no_sound" value="0"/>
<param name="playback_boost" value="0" />
<param name="capture_boost" value="0" />
<param name="at_dial_pre_number" value="AT+CKPD=&quot;EEE" />
<param name="at_dial_post_number" value="S&quot;" />
<param name="at_dial_expect" value="OK" />
<param name="at_hangup" value="AT+CKPD=&quot;EEE&quot;" />
<param name="at_hangup_expect" value="OK" />
<param name="at_answer" value="ATA" />
<param name="at_answer_expect" value="OK" />
<param name="at_initial_pause" value="1000000" />
<param name="at_preinit_1" value="atciapa" />
<param name="at_preinit_1_expect" value="OK" />
<param name="at_preinit_2" value="" />
<param name="at_preinit_2_expect" value="" />
<param name="at_preinit_3" value="" />
<param name="at_preinit_3_expect" value="" />
<param name="at_preinit_4" value="" />
<param name="at_preinit_4_expect" value="" />
<param name="at_preinit_5" value="" />
<param name="at_preinit_5_expect" value="" />
<param name="at_after_preinit_pause" value="1000000" />
<param name="at_postinit_1" value="atcucu" />
<param name="at_postinit_1_expect" value="OK" />
<param name="at_postinit_2" value="AT+CKPD=&quot;EEE&quot;" />
<param name="at_postinit_2_expect" value="OK" />
<param name="at_postinit_3" value="" />
<param name="at_postinit_3_expect" value="" />
<param name="at_postinit_4" value="" />
<param name="at_postinit_4_expect" value="" />
<param name="at_postinit_5" value="" />
<param name="at_postinit_5_expect" value="" />
<param name="at_query_battchg" value="AT+CBC" />
<param name="at_query_battchg_expect" value="OK" />
<param name="at_query_signal" value="AT+CSQ" />
<param name="at_query_signal_expect" value="OK" />
<param name="at_indicator_noservice_string" value="+CIEV: 2,0" />
<param name="at_indicator_nosignal_string" value="+CIEV: 5,0" />
<param name="at_indicator_lowsignal_string" value="+CIEV: 5,1" />
<param name="at_indicator_lowbattchg_string" value="+CIEV: 0,1" />
<param name="at_indicator_nobattchg_string" value="+CIEV: 0,0" />
<param name="at_indicator_callactive_string" value="+CIEV: 3,1" />
<param name="at_indicator_nocallactive_string" value="+CIEV: 3,0" />
<param name="at_indicator_nocallsetup_string" value="+CIEV: 6,0" />
<param name="at_indicator_callsetupincoming_string" value="+CIEV: 6,1" />
<param name="at_indicator_callsetupoutgoing_string" value="+CIEV: 6,2" />
<param name="at_indicator_callsetupremoteringing_string" value="+CIEV: 6,3" />
<param name="at_call_idle" value="+MCST: 1" />
<param name="at_call_incoming" value="+MCST: 2" />
<param name="at_call_active" value="+MCST: 3" />
<param name="at_call_failed" value="+MCST: 65" />
<param name="at_call_calling" value="+MCST: 64" />
</interface>
</per_interface_settings>
</configuration>

View File

@ -0,0 +1,71 @@
/* Copyright (C) 2007 Jean-Marc Valin
File: testresample.c
Testing the resampling code
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are
met:
1. Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
3. The name of the author may not be used to endorse or promote products
derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.
*/
#include <stdio.h>
#include <math.h>
#include <stdlib.h>
#define NN 256
int main()
{
short *in;
short *out;
int i;
int a;
in = malloc(NN*sizeof(short));
out = malloc(NN*sizeof(short)/6);
while (1)
{
fread(in, sizeof(short), NN, stdin);
if (feof(stdin))
break;
a=0;
for (i=0;i<NN;i++){
out[a]=in[i];
i++;
i++;
i++;
i++;
i++;
a++;
}
fwrite(out, sizeof(short), NN/6, stdout);
}
free(in);
free(out);
return 0;
}

View File

@ -0,0 +1,81 @@
/* Copyright (C) 2007 Jean-Marc Valin
File: testresample.c
Testing the resampling code
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are
met:
1. Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
3. The name of the author may not be used to endorse or promote products
derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.
*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include <stdio.h>
//#include "speex/speex_resampler.h"
#include <math.h>
#include <stdlib.h>
#define NN 256
int main()
{
short *in;
short *out;
int i;
int a;
in = malloc(NN*sizeof(short));
out = malloc(NN*sizeof(short)*6);
while (1)
{
fread(in, sizeof(short), NN, stdin);
if (feof(stdin))
break;
a=0;
for (i=0;i<NN;i++){
out[a]=in[i];
a++;
out[a]=in[i];
a++;
out[a]=in[i];
a++;
out[a]=in[i];
a++;
out[a]=in[i];
a++;
out[a]=in[i];
a++;
}
fwrite(out, sizeof(short), NN*6, stdout);
}
free(in);
free(out);
return 0;
}

View File

@ -0,0 +1,8 @@
For Linux distros without gsmlib (eg: CentOS):
Here are the original (ancient) sources for gsmlib, and the patch made by Ubuntu for modern compilers.
In the directory gsmlib-1.10-patched-12ubuntu1 are the patched sources, ready for (no need to patch them again):
./configure
make
make install

View File

@ -0,0 +1,226 @@
Notes on the Free Translation Project
*************************************
Free software is going international! The Free Translation Project
is a way to get maintainers of free software, translators, and users all
together, so that will gradually become able to speak many languages.
A few packages already provide translations for their messages.
If you found this `ABOUT-NLS' file inside a distribution, you may
assume that the distributed package does use GNU `gettext' internally,
itself available at your nearest GNU archive site. But you do *not*
need to install GNU `gettext' prior to configuring, installing or using
this package with messages translated.
Installers will find here some useful hints. These notes also
explain how users should proceed for getting the programs to use the
available translations. They tell how people wanting to contribute and
work at translations should contact the appropriate team.
When reporting bugs in the `intl/' directory or bugs which may be
related to internationalization, you should tell about the version of
`gettext' which is used. The information can be found in the
`intl/VERSION' file, in internationalized packages.
One advise in advance
=====================
If you want to exploit the full power of internationalization, you
should configure it using
./configure --with-included-gettext
to force usage of internationalizing routines provided within this
package, despite the existence of internationalizing capabilities in the
operating system where this package is being installed. So far, only
the `gettext' implementation in the GNU C library version 2 provides as
many features (such as locale alias or message inheritance) as the
implementation here. It is also not possible to offer this additional
functionality on top of a `catgets' implementation. Future versions of
GNU `gettext' will very likely convey even more functionality. So it
might be a good idea to change to GNU `gettext' as soon as possible.
So you need not provide this option if you are using GNU libc 2 or
you have installed a recent copy of the GNU gettext package with the
included `libintl'.
INSTALL Matters
===============
Some packages are "localizable" when properly installed; the
programs they contain can be made to speak your own native language.
Most such packages use GNU `gettext'. Other packages have their own
ways to internationalization, predating GNU `gettext'.
By default, this package will be installed to allow translation of
messages. It will automatically detect whether the system provides
usable `catgets' (if using this is selected by the installer) or
`gettext' functions. If neither is available, the GNU `gettext' own
library will be used. This library is wholly contained within this
package, usually in the `intl/' subdirectory, so prior installation of
the GNU `gettext' package is *not* required. Installers may use
special options at configuration time for changing the default
behaviour. The commands:
./configure --with-included-gettext
./configure --with-catgets
./configure --disable-nls
will respectively bypass any pre-existing `catgets' or `gettext' to use
the internationalizing routines provided within this package, enable
the use of the `catgets' functions (if found on the locale system), or
else, *totally* disable translation of messages.
When you already have GNU `gettext' installed on your system and run
configure without an option for your new package, `configure' will
probably detect the previously built and installed `libintl.a' file and
will decide to use this. This might be not what is desirable. You
should use the more recent version of the GNU `gettext' library. I.e.
if the file `intl/VERSION' shows that the library which comes with this
package is more recent, you should use
./configure --with-included-gettext
to prevent auto-detection.
By default the configuration process will not test for the `catgets'
function and therefore they will not be used. The reasons are already
given above: the emulation on top of `catgets' cannot provide all the
extensions provided by the GNU `gettext' library. If you nevertheless
want to use the `catgets' functions use
./configure --with-catgets
to enable the test for `catgets' (this causes no harm if `catgets' is
not available on your system). If you really select this option we
would like to hear about the reasons because we cannot think of any
good one ourself.
Internationalized packages have usually many `po/LL.po' files, where
LL gives an ISO 639 two-letter code identifying the language. Unless
translations have been forbidden at `configure' time by using the
`--disable-nls' switch, all available translations are installed
together with the package. However, the environment variable `LINGUAS'
may be set, prior to configuration, to limit the installed set.
`LINGUAS' should then contain a space separated list of two-letter
codes, stating which languages are allowed.
Using This Package
==================
As a user, if your language has been installed for this package, you
only have to set the `LANG' environment variable to the appropriate
ISO 639 `LL' two-letter code prior to using the programs in the
package. For example, let's suppose that you speak German. At the
shell prompt, merely execute `setenv LANG de' (in `csh'),
`export LANG; LANG=de' (in `sh') or `export LANG=de' (in `bash'). This
can be done from your `.login' or `.profile' file, once and for all.
An operating system might already offer message localization for
many of its programs, while other programs have been installed locally
with the full capabilities of GNU `gettext'. Just using `gettext'
extended syntax for `LANG' would break proper localization of already
available operating system programs. In this case, users should set
both `LANGUAGE' and `LANG' variables in their environment, as programs
using GNU `gettext' give preference to `LANGUAGE'. For example, some
Swedish users would rather read translations in German than English for
when Swedish is not available. This is easily accomplished by setting
`LANGUAGE' to `sv:de' while leaving `LANG' to `sv'.
Translating Teams
=================
For the Free Translation Project to be a success, we need interested
people who like their own language and write it well, and who are also
able to synergize with other translators speaking the same language.
Each translation team has its own mailing list, courtesy of Linux
International. You may reach your translation team at the address
`LL@li.org', replacing LL by the two-letter ISO 639 code for your
language. Language codes are *not* the same as the country codes given
in ISO 3166. The following translation teams exist, as of December
1997:
Chinese `zh', Czech `cs', Danish `da', Dutch `nl', English `en',
Esperanto `eo', Finnish `fi', French `fr', German `de', Hungarian
`hu', Irish `ga', Italian `it', Indonesian `id', Japanese `ja',
Korean `ko', Latin `la', Norwegian `no', Persian `fa', Polish
`pl', Portuguese `pt', Russian `ru', Slovenian `sl', Spanish `es',
Swedish `sv', and Turkish `tr'.
For example, you may reach the Chinese translation team by writing to
`zh@li.org'.
If you'd like to volunteer to *work* at translating messages, you
should become a member of the translating team for your own language.
The subscribing address is *not* the same as the list itself, it has
`-request' appended. For example, speakers of Swedish can send a
message to `sv-request@li.org', having this message body:
subscribe
Keep in mind that team members are expected to participate
*actively* in translations, or at solving translational difficulties,
rather than merely lurking around. If your team does not exist yet and
you want to start one, or if you are unsure about what to do or how to
get started, please write to `translation@iro.umontreal.ca' to reach the
coordinator for all translator teams.
The English team is special. It works at improving and uniformizing
the terminology in use. Proven linguistic skill are praised more than
programming skill, here.
Available Packages
==================
Languages are not equally supported in all packages. The following
matrix shows the current state of internationalization, as of December
1997. The matrix shows, in regard of each package, for which languages
PO files have been submitted to translation coordination.
Ready PO files cs da de en es fi fr it ja ko nl no pl pt ru sl sv
.----------------------------------------------------.
bash | [] [] [] | 3
bison | [] [] [] | 3
clisp | [] [] [] [] | 4
cpio | [] [] [] [] [] [] | 6
diffutils | [] [] [] [] [] | 5
enscript | [] [] [] [] [] [] | 6
fileutils | [] [] [] [] [] [] [] [] [] [] | 10
findutils | [] [] [] [] [] [] [] [] [] | 9
flex | [] [] [] [] | 4
gcal | [] [] [] [] [] | 5
gettext | [] [] [] [] [] [] [] [] [] [] [] | 12
grep | [] [] [] [] [] [] [] [] [] [] | 10
hello | [] [] [] [] [] [] [] [] [] [] [] | 11
id-utils | [] [] [] | 3
indent | [] [] [] [] [] | 5
libc | [] [] [] [] [] [] [] | 7
m4 | [] [] [] [] [] [] | 6
make | [] [] [] [] [] [] | 6
music | [] [] | 2
ptx | [] [] [] [] [] [] [] [] | 8
recode | [] [] [] [] [] [] [] [] [] | 9
sh-utils | [] [] [] [] [] [] [] [] | 8
sharutils | [] [] [] [] [] [] | 6
tar | [] [] [] [] [] [] [] [] [] [] [] | 11
texinfo | [] [] [] | 3
textutils | [] [] [] [] [] [] [] [] [] | 9
wdiff | [] [] [] [] [] [] [] [] | 8
`----------------------------------------------------'
17 languages cs da de en es fi fr it ja ko nl no pl pt ru sl sv
27 packages 6 4 25 1 18 1 26 2 1 12 20 9 19 7 4 7 17 179
Some counters in the preceding matrix are higher than the number of
visible blocks let us expect. This is because a few extra PO files are
used for implementing regional variants of languages, or language
dialects.
For a PO file in the matrix above to be effective, the package to
which it applies should also have been internationalized and
distributed as such by its maintainer. There might be an observable
lag between the mere existence a PO file and its wide availability in a
distribution.
If December 1997 seems to be old, you may fetch a more recent copy
of this `ABOUT-NLS' file on most GNU archive sites.

View File

@ -0,0 +1,482 @@
GNU LIBRARY GENERAL PUBLIC LICENSE
Version 2, June 1991
Copyright (C) 1991 Free Software Foundation, Inc.
59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
[This is the first released version of the library GPL. It is
numbered 2 because it goes with version 2 of the ordinary GPL.]
Preamble
The licenses for most software are designed to take away your
freedom to share and change it. By contrast, the GNU General Public
Licenses are intended to guarantee your freedom to share and change
free software--to make sure the software is free for all its users.
This license, the Library General Public License, applies to some
specially designated Free Software Foundation software, and to any
other libraries whose authors decide to use it. You can use it for
your libraries, too.
When we speak of free software, we are referring to freedom, not
price. Our General Public Licenses are designed to make sure that you
have the freedom to distribute copies of free software (and charge for
this service if you wish), that you receive source code or can get it
if you want it, that you can change the software or use pieces of it
in new free programs; and that you know you can do these things.
To protect your rights, we need to make restrictions that forbid
anyone to deny you these rights or to ask you to surrender the rights.
These restrictions translate to certain responsibilities for you if
you distribute copies of the library, or if you modify it.
For example, if you distribute copies of the library, whether gratis
or for a fee, you must give the recipients all the rights that we gave
you. You must make sure that they, too, receive or can get the source
code. If you link a program with the library, you must provide
complete object files to the recipients so that they can relink them
with the library, after making changes to the library and recompiling
it. And you must show them these terms so they know their rights.
Our method of protecting your rights has two steps: (1) copyright
the library, and (2) offer you this license which gives you legal
permission to copy, distribute and/or modify the library.
Also, for each distributor's protection, we want to make certain
that everyone understands that there is no warranty for this free
library. If the library is modified by someone else and passed on, we
want its recipients to know that what they have is not the original
version, so that any problems introduced by others will not reflect on
the original authors' reputations.
Finally, any free program is threatened constantly by software
patents. We wish to avoid the danger that companies distributing free
software will individually obtain patent licenses, thus in effect
transforming the program into proprietary software. To prevent this,
we have made it clear that any patent must be licensed for everyone's
free use or not licensed at all.
Most GNU software, including some libraries, is covered by the ordinary
GNU General Public License, which was designed for utility programs. This
license, the GNU Library General Public License, applies to certain
designated libraries. This license is quite different from the ordinary
one; be sure to read it in full, and don't assume that anything in it is
the same as in the ordinary license.
The reason we have a separate public license for some libraries is that
they blur the distinction we usually make between modifying or adding to a
program and simply using it. Linking a program with a library, without
changing the library, is in some sense simply using the library, and is
analogous to running a utility program or application program. However, in
a textual and legal sense, the linked executable is a combined work, a
derivative of the original library, and the ordinary General Public License
treats it as such.
Because of this blurred distinction, using the ordinary General
Public License for libraries did not effectively promote software
sharing, because most developers did not use the libraries. We
concluded that weaker conditions might promote sharing better.
However, unrestricted linking of non-free programs would deprive the
users of those programs of all benefit from the free status of the
libraries themselves. This Library General Public License is intended to
permit developers of non-free programs to use free libraries, while
preserving your freedom as a user of such programs to change the free
libraries that are incorporated in them. (We have not seen how to achieve
this as regards changes in header files, but we have achieved it as regards
changes in the actual functions of the Library.) The hope is that this
will lead to faster development of free libraries.
The precise terms and conditions for copying, distribution and
modification follow. Pay close attention to the difference between a
"work based on the library" and a "work that uses the library". The
former contains code derived from the library, while the latter only
works together with the library.
Note that it is possible for a library to be covered by the ordinary
General Public License rather than by this special one.
GNU LIBRARY GENERAL PUBLIC LICENSE
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
0. This License Agreement applies to any software library which
contains a notice placed by the copyright holder or other authorized
party saying it may be distributed under the terms of this Library
General Public License (also called "this License"). Each licensee is
addressed as "you".
A "library" means a collection of software functions and/or data
prepared so as to be conveniently linked with application programs
(which use some of those functions and data) to form executables.
The "Library", below, refers to any such software library or work
which has been distributed under these terms. A "work based on the
Library" means either the Library or any derivative work under
copyright law: that is to say, a work containing the Library or a
portion of it, either verbatim or with modifications and/or translated
straightforwardly into another language. (Hereinafter, translation is
included without limitation in the term "modification".)
"Source code" for a work means the preferred form of the work for
making modifications to it. For a library, complete source code means
all the source code for all modules it contains, plus any associated
interface definition files, plus the scripts used to control compilation
and installation of the library.
Activities other than copying, distribution and modification are not
covered by this License; they are outside its scope. The act of
running a program using the Library is not restricted, and output from
such a program is covered only if its contents constitute a work based
on the Library (independent of the use of the Library in a tool for
writing it). Whether that is true depends on what the Library does
and what the program that uses the Library does.
1. You may copy and distribute verbatim copies of the Library's
complete source code as you receive it, in any medium, provided that
you conspicuously and appropriately publish on each copy an
appropriate copyright notice and disclaimer of warranty; keep intact
all the notices that refer to this License and to the absence of any
warranty; and distribute a copy of this License along with the
Library.
You may charge a fee for the physical act of transferring a copy,
and you may at your option offer warranty protection in exchange for a
fee.
2. You may modify your copy or copies of the Library or any portion
of it, thus forming a work based on the Library, and copy and
distribute such modifications or work under the terms of Section 1
above, provided that you also meet all of these conditions:
a) The modified work must itself be a software library.
b) You must cause the files modified to carry prominent notices
stating that you changed the files and the date of any change.
c) You must cause the whole of the work to be licensed at no
charge to all third parties under the terms of this License.
d) If a facility in the modified Library refers to a function or a
table of data to be supplied by an application program that uses
the facility, other than as an argument passed when the facility
is invoked, then you must make a good faith effort to ensure that,
in the event an application does not supply such function or
table, the facility still operates, and performs whatever part of
its purpose remains meaningful.
(For example, a function in a library to compute square roots has
a purpose that is entirely well-defined independent of the
application. Therefore, Subsection 2d requires that any
application-supplied function or table used by this function must
be optional: if the application does not supply it, the square
root function must still compute square roots.)
These requirements apply to the modified work as a whole. If
identifiable sections of that work are not derived from the Library,
and can be reasonably considered independent and separate works in
themselves, then this License, and its terms, do not apply to those
sections when you distribute them as separate works. But when you
distribute the same sections as part of a whole which is a work based
on the Library, the distribution of the whole must be on the terms of
this License, whose permissions for other licensees extend to the
entire whole, and thus to each and every part regardless of who wrote
it.
Thus, it is not the intent of this section to claim rights or contest
your rights to work written entirely by you; rather, the intent is to
exercise the right to control the distribution of derivative or
collective works based on the Library.
In addition, mere aggregation of another work not based on the Library
with the Library (or with a work based on the Library) on a volume of
a storage or distribution medium does not bring the other work under
the scope of this License.
3. You may opt to apply the terms of the ordinary GNU General Public
License instead of this License to a given copy of the Library. To do
this, you must alter all the notices that refer to this License, so
that they refer to the ordinary GNU General Public License, version 2,
instead of to this License. (If a newer version than version 2 of the
ordinary GNU General Public License has appeared, then you can specify
that version instead if you wish.) Do not make any other change in
these notices.
Once this change is made in a given copy, it is irreversible for
that copy, so the ordinary GNU General Public License applies to all
subsequent copies and derivative works made from that copy.
This option is useful when you wish to copy part of the code of
the Library into a program that is not a library.
4. You may copy and distribute the Library (or a portion or
derivative of it, under Section 2) in object code or executable form
under the terms of Sections 1 and 2 above provided that you accompany
it with the complete corresponding machine-readable source code, which
must be distributed under the terms of Sections 1 and 2 above on a
medium customarily used for software interchange.
If distribution of object code is made by offering access to copy
from a designated place, then offering equivalent access to copy the
source code from the same place satisfies the requirement to
distribute the source code, even though third parties are not
compelled to copy the source along with the object code.
5. A program that contains no derivative of any portion of the
Library, but is designed to work with the Library by being compiled or
linked with it, is called a "work that uses the Library". Such a
work, in isolation, is not a derivative work of the Library, and
therefore falls outside the scope of this License.
However, linking a "work that uses the Library" with the Library
creates an executable that is a derivative of the Library (because it
contains portions of the Library), rather than a "work that uses the
library". The executable is therefore covered by this License.
Section 6 states terms for distribution of such executables.
When a "work that uses the Library" uses material from a header file
that is part of the Library, the object code for the work may be a
derivative work of the Library even though the source code is not.
Whether this is true is especially significant if the work can be
linked without the Library, or if the work is itself a library. The
threshold for this to be true is not precisely defined by law.
If such an object file uses only numerical parameters, data
structure layouts and accessors, and small macros and small inline
functions (ten lines or less in length), then the use of the object
file is unrestricted, regardless of whether it is legally a derivative
work. (Executables containing this object code plus portions of the
Library will still fall under Section 6.)
Otherwise, if the work is a derivative of the Library, you may
distribute the object code for the work under the terms of Section 6.
Any executables containing that work also fall under Section 6,
whether or not they are linked directly with the Library itself.
6. As an exception to the Sections above, you may also compile or
link a "work that uses the Library" with the Library to produce a
work containing portions of the Library, and distribute that work
under terms of your choice, provided that the terms permit
modification of the work for the customer's own use and reverse
engineering for debugging such modifications.
You must give prominent notice with each copy of the work that the
Library is used in it and that the Library and its use are covered by
this License. You must supply a copy of this License. If the work
during execution displays copyright notices, you must include the
copyright notice for the Library among them, as well as a reference
directing the user to the copy of this License. Also, you must do one
of these things:
a) Accompany the work with the complete corresponding
machine-readable source code for the Library including whatever
changes were used in the work (which must be distributed under
Sections 1 and 2 above); and, if the work is an executable linked
with the Library, with the complete machine-readable "work that
uses the Library", as object code and/or source code, so that the
user can modify the Library and then relink to produce a modified
executable containing the modified Library. (It is understood
that the user who changes the contents of definitions files in the
Library will not necessarily be able to recompile the application
to use the modified definitions.)
b) Accompany the work with a written offer, valid for at
least three years, to give the same user the materials
specified in Subsection 6a, above, for a charge no more
than the cost of performing this distribution.
c) If distribution of the work is made by offering access to copy
from a designated place, offer equivalent access to copy the above
specified materials from the same place.
d) Verify that the user has already received a copy of these
materials or that you have already sent this user a copy.
For an executable, the required form of the "work that uses the
Library" must include any data and utility programs needed for
reproducing the executable from it. However, as a special exception,
the source code distributed need not include anything that is normally
distributed (in either source or binary form) with the major
components (compiler, kernel, and so on) of the operating system on
which the executable runs, unless that component itself accompanies
the executable.
It may happen that this requirement contradicts the license
restrictions of other proprietary libraries that do not normally
accompany the operating system. Such a contradiction means you cannot
use both them and the Library together in an executable that you
distribute.
7. You may place library facilities that are a work based on the
Library side-by-side in a single library together with other library
facilities not covered by this License, and distribute such a combined
library, provided that the separate distribution of the work based on
the Library and of the other library facilities is otherwise
permitted, and provided that you do these two things:
a) Accompany the combined library with a copy of the same work
based on the Library, uncombined with any other library
facilities. This must be distributed under the terms of the
Sections above.
b) Give prominent notice with the combined library of the fact
that part of it is a work based on the Library, and explaining
where to find the accompanying uncombined form of the same work.
8. You may not copy, modify, sublicense, link with, or distribute
the Library except as expressly provided under this License. Any
attempt otherwise to copy, modify, sublicense, link with, or
distribute the Library is void, and will automatically terminate your
rights under this License. However, parties who have received copies,
or rights, from you under this License will not have their licenses
terminated so long as such parties remain in full compliance.
9. You are not required to accept this License, since you have not
signed it. However, nothing else grants you permission to modify or
distribute the Library or its derivative works. These actions are
prohibited by law if you do not accept this License. Therefore, by
modifying or distributing the Library (or any work based on the
Library), you indicate your acceptance of this License to do so, and
all its terms and conditions for copying, distributing or modifying
the Library or works based on it.
10. Each time you redistribute the Library (or any work based on the
Library), the recipient automatically receives a license from the
original licensor to copy, distribute, link with or modify the Library
subject to these terms and conditions. You may not impose any further
restrictions on the recipients' exercise of the rights granted herein.
You are not responsible for enforcing compliance by third parties to
this License.
11. If, as a consequence of a court judgment or allegation of patent
infringement or for any other reason (not limited to patent issues),
conditions are imposed on you (whether by court order, agreement or
otherwise) that contradict the conditions of this License, they do not
excuse you from the conditions of this License. If you cannot
distribute so as to satisfy simultaneously your obligations under this
License and any other pertinent obligations, then as a consequence you
may not distribute the Library at all. For example, if a patent
license would not permit royalty-free redistribution of the Library by
all those who receive copies directly or indirectly through you, then
the only way you could satisfy both it and this License would be to
refrain entirely from distribution of the Library.
If any portion of this section is held invalid or unenforceable under any
particular circumstance, the balance of the section is intended to apply,
and the section as a whole is intended to apply in other circumstances.
It is not the purpose of this section to induce you to infringe any
patents or other property right claims or to contest validity of any
such claims; this section has the sole purpose of protecting the
integrity of the free software distribution system which is
implemented by public license practices. Many people have made
generous contributions to the wide range of software distributed
through that system in reliance on consistent application of that
system; it is up to the author/donor to decide if he or she is willing
to distribute software through any other system and a licensee cannot
impose that choice.
This section is intended to make thoroughly clear what is believed to
be a consequence of the rest of this License.
12. If the distribution and/or use of the Library is restricted in
certain countries either by patents or by copyrighted interfaces, the
original copyright holder who places the Library under this License may add
an explicit geographical distribution limitation excluding those countries,
so that distribution is permitted only in or among countries not thus
excluded. In such case, this License incorporates the limitation as if
written in the body of this License.
13. The Free Software Foundation may publish revised and/or new
versions of the Library General Public License from time to time.
Such new versions will be similar in spirit to the present version,
but may differ in detail to address new problems or concerns.
Each version is given a distinguishing version number. If the Library
specifies a version number of this License which applies to it and
"any later version", you have the option of following the terms and
conditions either of that version or of any later version published by
the Free Software Foundation. If the Library does not specify a
license version number, you may choose any version ever published by
the Free Software Foundation.
14. If you wish to incorporate parts of the Library into other free
programs whose distribution conditions are incompatible with these,
write to the author to ask for permission. For software which is
copyrighted by the Free Software Foundation, write to the Free
Software Foundation; we sometimes make exceptions for this. Our
decision will be guided by the two goals of preserving the free status
of all derivatives of our free software and of promoting the sharing
and reuse of software generally.
NO WARRANTY
15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO
WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW.
EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR
OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY
KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE
LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME
THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN
WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY
AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU
FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR
CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE
LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING
RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A
FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF
SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
DAMAGES.
END OF TERMS AND CONDITIONS
How to Apply These Terms to Your New Libraries
If you develop a new library, and you want it to be of the greatest
possible use to the public, we recommend making it free software that
everyone can redistribute and change. You can do so by permitting
redistribution under these terms (or, alternatively, under the terms of the
ordinary General Public License).
To apply these terms, attach the following notices to the library. It is
safest to attach them to the start of each source file to most effectively
convey the exclusion of warranty; and each file should have at least the
"copyright" line and a pointer to where the full notice is found.
<one line to give the library's name and a brief idea of what it does.>
Copyright (C) <year> <name of author>
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public
License as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Library General Public License for more details.
You should have received a copy of the GNU Library General Public
License along with this library; if not, write to the
Free Software Foundation, Inc., 59 Temple Place - Suite 330,
Boston, MA 02111-1307 USA.
Also add information on how to contact you by electronic and paper mail.
You should also get your employer (if you work as a programmer) or your
school, if any, to sign a "copyright disclaimer" for the library, if
necessary. Here is a sample; alter the names:
Yoyodyne, Inc., hereby disclaims all copyright interest in the
library `Frob' (a library for tweaking knobs) written by James Random Hacker.
<signature of Ty Coon>, 1 April 1990
Ty Coon, President of Vice
That's all there is to it!

View File

@ -0,0 +1,386 @@
gsmlib-1.10
- reactivated code in gsm_at to retry sending PDU after
unsolicited result code
- added description of unicode handling to FAQ
- compilation fixes for gcc-3.0.4
- added quick exit for ATZ in UnixSerialPort constructor
if phone gives ERROR
- added fix for phones that return +CLIP: "Number not available."
instead of giving caller ID
- added get/setCLIRPresentation() functions to MeTa (contribution by
ivan)
- added "NO CARRIER" event to the event mechanism (contribution by
clock)
- added Win32 port of gsmsmsd (thanks to Konstantin Forostyan)
- further extented Win32 port of gsmsmsd to handle outgoing messages
- fixed problem with Ericsson T39m SMS sending (zero bytes in handshake)
- added capability to send concatenated SMSs in gsmsmsd and gsmsendsms
- fixed unsigned/signed char problems in Unix/Win32 serial port
implementations
- added capability to send multiple SMSs to gsmsendsms/gsmsmsd
gsmlib-1.9
- fixed decoding of alphanumeric addresses in gsm_sms_codec.
- fixed bug in gsm_event when checking whether to send an
acknowledgment for a received SMS
- More Siemens-specific patches, some extensions to the AT
command parser
- New code to print PIN status and set the PIN in gsmctl, setPIN
function in MeTa class (Andreas Roedl <flood@flood-net.de>)
- Missing virtual destructor in Port class caused destructors of
UnixSerialPort and Win32SerialPort not to be called - fixed
- Added new code to set functionality level on or off (thanks to
David Woodhouse)
- found bug in SMS store implementation that caused the now
obsolete _capacity member to be set to a too low value
- Added changes contributed by Frediano Ziglio to enable compilation
on Windows
- Added call waiting functions contributed by Ivan
gsmlib-1.8
- added workaround for Nokia Cellular Card Phone RPE-1 GSM900
that reports a CDS event that actually is an CDSI and sends a spurious
CR when waiting for a PDU
- SMS are stored without index in files now
- tested compilation with gcc-3.0.2
- added workaround for gsmlib getting confused when receiving SMS
and echo cannot be switched off - echos of the AT command are
filtered out in chat() now
- extended gsm_phonebook preload mechanism to batch-load phonebooks
where the index does not start with 1
- Added workaround for Motorola Timeport 260 to write back
deliver messages to the ME
- added workaround for compilation with libstdc++-v2
- private members of MeTa made protected
- new ext directory for phone-specific extensions
gsmlib-1.7
- fixed bug with calculation of userData length if userDataHeader
is present (octet count was subtracted, not septet count)
- fixed problem with string erase() at end of PDU for Falcom A2-1
- -t/--charset option of gsmpb did not work due to missing parameter
of getopt_long, fixed
- The SMS decoder/encoder can now handle alphanumeric addresses
in the GSM default alphabet
- set only those SMS stores that are actually needed to perform
SMS store operation
- Fixed signalling error 321 (Invalid memory index) when trying to
read from empty SMS store entry
- Fixed parsing error when reading current network operator if no
network connection
- Added capability to parse cell broadcast messages to gsmlib and
the gsmsmsd program
- Added workaround for Motorola Timeport 260 bug that doesn't correctly
report the message status when retrieving SMS messages from the
store
- Added workaround for Motorola Timeport 260 that allocates index
numbers to SMS messages linearly so that index number can be
be larger than capacity reported by AT command
gsmlib-1.6
- more fixes for the COPS=? return format
- fixed putBack() behaviour in gsm_parser (don't put back if end-of-
stream is reached)
- added toString() function to gsm_sms_codec's Address class
- SMS dates and times are now output in a locale-specific manner
- fixed bug in Parser::getEol() (_eos was accidentally set to true)
- added gsm_win32_serial module, Win32 project (VC++), and
Option FirstFone changes contributed by Frediano Ziglio
<freddy77@angelfire.com>
- fix in COM port recognition for Win32 (gsm_util)
- renamed library files libgsm.* to libgsmme.* (now starting with
version 1.0) because of conflict with another Debian package
- in gsm_phonebook and gsm_store the caching of entries can now
be disabled
- added facilities to use other character sets for phonebooks
- fixed workaround for Ericcson SH888 (missing service centre address)
- fixed bug in gsm_phonebook that prevented texts with the
character '@' to be written to to the phonebook
- fixed nasty memory allocation bug in gsmpb/gsmsmsstore
(automatic MeTa variable went out of scope even though used
later)
- fixed Y2K problem in timestamp printing
- fixed "make dist" to include win32 files
- added workarounds for Falcom A2-1 (autodetection and enabling by
"export GSMLIB_FALCOM_A2_1_FIX=1", zero after PDU)
- fixed bug that caused gsmlib to abort with an assert if a malformed
PDU was read
gsmlib-1.5
- adapted MeTa::getCurrentOPInfo() and MeTa::getAvailableOPInfo()
to handle Nokia 8290 quirks
- code to set line speed in gsm_unix_serial reinserted (it was
accidentally removed in previous version)
- minor changes to initialization sequence in gsm_unix_serial
- bugfix in gsm_unix_serial.cc: readByte() == 0 does not mean no
more bytes, but is legal value
- additionally allowed characters "*#pwPW" and '+' at any
position in telephone numbers
- added environment variable GSMLIB_SH888_FIX that (if set)
enables the gsmlib workaround for Ericsson SH888's broken SMS TPDUs
- fixed command line parameter handling bug in gsmsmsstore
- fixed %files section .spec file to correctly include manual pages
- fixed some bugs in terminal line setup (gsm_unix_serial) regarding
software/hardware handshake
- added new "--sca" option to SMS-related apps to set the SMS
service centre address on the command line (useful if default is not
set correctly in the phone)
- removed tcflush() call in UnixSerialPort::putLine that broke
the event system needed for gsmsmsd
gsmlib-1.4
- more attempts to fix UNIX serial port access
- allow custom backends for sorted phonebooks to be integrated
into gsmlib (eg. for RDBMS or LDAP storage). Introduced a new
module gsm_sorted_phonebook_base that contains the infrastructure for
this.
- Now gsmlib needs at least gcc-2.95.2 to compile correctly.
- Implemented option to open device with software handshaking (XON/XOFF).
The applications now have an -X option to turn this on.
- gsmlib now contains a facility to interrupt ongoing activity in a
controlled way. gsm_unix_serial now blocks for one second
maximum until it checks whether it was interrupted.
- various small bugfixes
- added workaround for phones that omit ':' in AT command responses
- all debugging output is now printed to stderr
- gsm_unix_serial: new attempt to initialize modem in a more
robust way (contributed)
- gsm_sms: fixed handling of user data header (contributed)
gsmlib-1.3
- fixed bug that caused gsmlib to hang if TAs don't respond
to AT inquiries for serial number etc.
- fixed bug with handling of CB mode AT command construction in
gsm_me_ta.cc, setSMSRoutingToTA()
- allow '+' as the first character of phonenumbers
- implemented reading and writing from/to stdin/stdout in
gsm_sorted_[sms_store|phonebook] and gsmpb/gsmsmsstore
- fixed (hopefully) the intermittent hangup problem in
gsm_unix_serial_port
- Some mobile phones cannot report the status of some facility
locks. The gsmctl program now prints out "unknown" in the
corresponding result line from the FLSTAT
operation if this problem occurs (instead of terminating).
- switched off non-blocking access to serial device
gsmlib-1.2
- gsmlib now also works with TAs that can not switch off echo
- fixed bug that prevented gsmlib from copying SMS_DELIVER and
SMS_STATUS_REPORT back to the ME
- introduced -I (--init) parameter to all command line apps to
allow for device-specific initialization
- made SMS decoding routines more robust against bad SMS (especially
premature end of PDU)
- New debugging feature: If compiled without NDEBUG, the
environment variable GSMLIB_DEBUG determines the verbosity of
debugging messages (0 = none, 1 = many, 2 = extreme)
gsmlib-1.1
- Parse multiple COPS (operator info) lines returned by some phones
- accept string as numeric value when interpreting COPS=? response
(Ericsson phone + GSM12 GSM module)
- accept string as numeric value when interpreting COPS? response
(Ericsson phone + GSM12 GSM module)
- retry when initializing TA (ATZ/ATE0 sequences)
- Set SMS routing:
allow mode 3 (special in-band technique) when setting routing
to TA (gsmlib should not be active when phone is switched to data mode
anyway)
- Set SMS routing:
handle buffer mode but only if it was reported by the +CNMI=? command
(the Ericsson GM12 GSM modem does not like it otherwise)
- Determine CPMS number of parameters for CPMS command (better
compability with some mobile phones / GSM modems)
- handle missing service centre address in incoming SMS for Ericsson
model 6050102
- add new RING event to gsm_event.h/.cc, gsmsmsd now handles RING
indications properly
- defined default event handler mostly to handle unexpected RING
indications that might otherwise confuse gsmlib
- gsmsmsd: can now be cleanly terminated using the SIGINT or SIGTERM
signals
- gsmsmsd: now handles multiple incoming SMS messages cleanly, before
there was a chance that some SMS messages coming in rapid succession
might have been lost
- gsmsmsd: flush option implemented that dispatches and erases
existing messages in SMS store
- gsmsmsd: added sending of SMS messages. gsmsmsd now accepts a
spool directory options where it expects to find SMS message file in a
simple format, these are dispatched every 5 seconds
gsmlib-1.0
- RPM support (spec file)
- the "+" is at least for the Siemens S10 and S25 a valid char in
telephone numbers (inserts a pause of 3 seconds), therefore it is now
allowed as part of telephone numbers
- fixed incorrect analysis of facility class parameters in gsmctl.cc
- restricted call forward time to 0..30 seconds in gsm_me_ta.cc
gsmlib-0.3
- implemented timeout for accessing the mobile phone in order
to avoid hangs
- upgraded to BETA status
- written glossary for abbreviations (gsminfo(7))
- implemented NLS support, added German translations
- implemented preserving the index position of phonebook entries in
gsmpb.cc and gsm_sorted_phonebook
- cleaned up manual pages (alphabetic ordering of options etc.)
- gsmsmstore program and gsm_sorted_sms_store./.cc completed and
tested
- gsmpb and gsmsmsstore now have --verbose (-V) options for detailed
progress reporting
- now check for getopt_long in configure (can be compiled on non-GNU
systems)
- removed asserts regarding lengths of numeric data types, put them
into configure script
- sorted options in apps/*.cc alphabetically (--help option)
- in gsm_sorted_sms_store compare telephone numbers more sensibly
- introduced -v option to gsmpb and gsmsmsstore to report execution
statistics
- tested new synchronization function in gsmpb program
- implemented operations in the gsmctl program
- rewrote test cases (compare output)
- completed gsmsmsstore program
- first changes for compilation with VC++ 6.0 on WIN32
gsmlib-0.2
- gsmsmstore program and gsm_sorted_sms_store./.cc mostly
completed but not yet much tested
- Fixed problem with some mobiles/TAs not giving prefixes after
certain AT sequences (reported for SIEMENS S25/IrDA, Nokia
8810/IrDA)
- Fixed problem with Xircom REM56G.100/Nokia 6150 that give
"CABLE: GSM" instead of "OK" after ATZ
- Mobiles that return nothing when empty phonebook entries are
requested are now handled correctly (reported for SIEMENS S25/IrDA)
- optimizations in gsm_*_phonebook modules (less AT commands necessary)
- new synchronization function in gsmpb program that is (hopefully)
more sensible (see man page for details)
gsmlib-0.1
- Initial release

View File

@ -0,0 +1,198 @@
GSMLIB Installation
===================
This distribution uses autoconf/automake/libtool. See below
for generic installation instructions. The default commands would be:
./configure
make
make install
See also the section INSTALLATION in the README file in this
directory. For questions regarding the internationalization of this
package refer to doc/README.NLS and ./ABOUT-NLS.
Developers: See also the file doc/README.developers.
Basic Installation
==================
These are generic installation instructions.
The `configure' shell script attempts to guess correct values for
various system-dependent variables used during compilation. It uses
those values to create a `Makefile' in each directory of the package.
It may also create one or more `.h' files containing system-dependent
definitions. Finally, it creates a shell script `config.status' that
you can run in the future to recreate the current configuration, a file
`config.cache' that saves the results of its tests to speed up
reconfiguring, and a file `config.log' containing compiler output
(useful mainly for debugging `configure').
If you need to do unusual things to compile the package, please try
to figure out how `configure' could check whether to do them, and mail
diffs or instructions to the address given in the `README' so they can
be considered for the next release. If at some point `config.cache'
contains results you don't want to keep, you may remove or edit it.
The file `configure.in' is used to create `configure' by a program
called `autoconf'. You only need `configure.in' if you want to change
it or regenerate `configure' using a newer version of `autoconf'.
The simplest way to compile this package is:
1. `cd' to the directory containing the package's source code and type
`./configure' to configure the package for your system. If you're
using `csh' on an old version of System V, you might need to type
`sh ./configure' instead to prevent `csh' from trying to execute
`configure' itself.
Running `configure' takes awhile. While running, it prints some
messages telling which features it is checking for.
2. Type `make' to compile the package.
3. Optionally, type `make check' to run any self-tests that come with
the package.
4. Type `make install' to install the programs and any data files and
documentation.
5. You can remove the program binaries and object files from the
source code directory by typing `make clean'. To also remove the
files that `configure' created (so you can compile the package for
a different kind of computer), type `make distclean'. There is
also a `make maintainer-clean' target, but that is intended mainly
for the package's developers. If you use it, you may have to get
all sorts of other programs in order to regenerate files that came
with the distribution.
Compilers and Options
=====================
Some systems require unusual options for compilation or linking that
the `configure' script does not know about. You can give `configure'
initial values for variables by setting them in the environment. Using
a Bourne-compatible shell, you can do that on the command line like
this:
CC=c89 CFLAGS=-O2 LIBS=-lposix ./configure
Or on systems that have the `env' program, you can do it like this:
env CPPFLAGS=-I/usr/local/include LDFLAGS=-s ./configure
Compiling For Multiple Architectures
====================================
You can compile the package for more than one kind of computer at the
same time, by placing the object files for each architecture in their
own directory. To do this, you must use a version of `make' that
supports the `VPATH' variable, such as GNU `make'. `cd' to the
directory where you want the object files and executables to go and run
the `configure' script. `configure' automatically checks for the
source code in the directory that `configure' is in and in `..'.
If you have to use a `make' that does not supports the `VPATH'
variable, you have to compile the package for one architecture at a time
in the source code directory. After you have installed the package for
one architecture, use `make distclean' before reconfiguring for another
architecture.
Installation Names
==================
By default, `make install' will install the package's files in
`/usr/local/bin', `/usr/local/man', etc. You can specify an
installation prefix other than `/usr/local' by giving `configure' the
option `--prefix=PATH'.
You can specify separate installation prefixes for
architecture-specific files and architecture-independent files. If you
give `configure' the option `--exec-prefix=PATH', the package will use
PATH as the prefix for installing programs and libraries.
Documentation and other data files will still use the regular prefix.
In addition, if you use an unusual directory layout you can give
options like `--bindir=PATH' to specify different values for particular
kinds of files. Run `configure --help' for a list of the directories
you can set and what kinds of files go in them.
If the package supports it, you can cause programs to be installed
with an extra prefix or suffix on their names by giving `configure' the
option `--program-prefix=PREFIX' or `--program-suffix=SUFFIX'.
Optional Features
=================
Some packages pay attention to `--enable-FEATURE' options to
`configure', where FEATURE indicates an optional part of the package.
They may also pay attention to `--with-PACKAGE' options, where PACKAGE
is something like `gnu-as' or `x' (for the X Window System). The
`README' should mention any `--enable-' and `--with-' options that the
package recognizes.
For packages that use the X Window System, `configure' can usually
find the X include and library files automatically, but if it doesn't,
you can use the `configure' options `--x-includes=DIR' and
`--x-libraries=DIR' to specify their locations.
Specifying the System Type
==========================
There may be some features `configure' can not figure out
automatically, but needs to determine by the type of host the package
will run on. Usually `configure' can figure that out, but if it prints
a message saying it can not guess the host type, give it the
`--host=TYPE' option. TYPE can either be a short name for the system
type, such as `sun4', or a canonical name with three fields:
CPU-COMPANY-SYSTEM
See the file `config.sub' for the possible values of each field. If
`config.sub' isn't included in this package, then this package doesn't
need to know the host type.
If you are building compiler tools for cross-compiling, you can also
use the `--target=TYPE' option to select the type of system they will
produce code for and the `--build=TYPE' option to select the type of
system on which you are compiling the package.
Sharing Defaults
================
If you want to set default values for `configure' scripts to share,
you can create a site shell script called `config.site' that gives
default values for variables like `CC', `cache_file', and `prefix'.
`configure' looks for `PREFIX/share/config.site' if it exists, then
`PREFIX/etc/config.site' if it exists. Or, you can set the
`CONFIG_SITE' environment variable to the location of the site script.
A warning: not all `configure' scripts look for a site script.
Operation Controls
==================
`configure' recognizes the following options to control how it
operates.
`--cache-file=FILE'
Use and save the results of the tests in FILE instead of
`./config.cache'. Set FILE to `/dev/null' to disable caching, for
debugging `configure'.
`--help'
Print a summary of the options to `configure', and exit.
`--quiet'
`--silent'
`-q'
Do not print messages saying which checks are being made. To
suppress all normal output, redirect it to `/dev/null' (any error
messages will still be shown).
`--srcdir=DIR'
Look for the package's source code in directory DIR. Usually
`configure' can determine that directory automatically.
`--version'
Print the version of Autoconf used to generate the `configure'
script, and exit.
`configure' also accepts some other, not widely useful, options.

View File

@ -0,0 +1,24 @@
## Process this file with automake to produce Makefile.in
# *************************************************************************
# * GSM TA/ME library
# *
# * File: Makefile.am
# *
# * Purpose: Toplevel Makefile
# *
# * Author: Peter Hofmann (software@pxh.de)
# *
# * Created: 21.5.1999
# *************************************************************************
SUBDIRS_ = po gsmlib apps tests doc scripts win32 ext
EXTRA_DIST = gsmlib.spec
if COMPILE_INTL
SUBDIRS = intl $(SUBDIRS_) # po - make automake happy
else
SUBDIRS = $(SUBDIRS_) # po intl - make automake happy
endif
all:

View File

@ -0,0 +1,423 @@
# Makefile.in generated automatically by automake 1.4-p6 from Makefile.am
# Copyright (C) 1994, 1995-8, 1999, 2001 Free Software Foundation, Inc.
# This Makefile.in is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
# with or without modifications, as long as this notice is preserved.
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
# PARTICULAR PURPOSE.
# *************************************************************************
# * GSM TA/ME library
# *
# * File: Makefile.am
# *
# * Purpose: Toplevel Makefile
# *
# * Author: Peter Hofmann (software@pxh.de)
# *
# * Created: 21.5.1999
# *************************************************************************
SHELL = @SHELL@
srcdir = @srcdir@
top_srcdir = @top_srcdir@
VPATH = @srcdir@
prefix = @prefix@
exec_prefix = @exec_prefix@
bindir = @bindir@
sbindir = @sbindir@
libexecdir = @libexecdir@
datadir = @datadir@
sysconfdir = @sysconfdir@
sharedstatedir = @sharedstatedir@
localstatedir = @localstatedir@
libdir = @libdir@
infodir = @infodir@
mandir = @mandir@
includedir = @includedir@
oldincludedir = /usr/include
DESTDIR =
pkgdatadir = $(datadir)/@PACKAGE@
pkglibdir = $(libdir)/@PACKAGE@
pkgincludedir = $(includedir)/@PACKAGE@
top_builddir = .
ACLOCAL = @ACLOCAL@
AUTOCONF = @AUTOCONF@
AUTOMAKE = @AUTOMAKE@
AUTOHEADER = @AUTOHEADER@
INSTALL = @INSTALL@
INSTALL_PROGRAM = @INSTALL_PROGRAM@ $(AM_INSTALL_PROGRAM_FLAGS)
INSTALL_DATA = @INSTALL_DATA@
INSTALL_SCRIPT = @INSTALL_SCRIPT@
transform = @program_transform_name@
NORMAL_INSTALL = :
PRE_INSTALL = :
POST_INSTALL = :
NORMAL_UNINSTALL = :
PRE_UNINSTALL = :
POST_UNINSTALL = :
host_alias = @host_alias@
host_triplet = @host@
AR = @AR@
AS = @AS@
BUILD_INCLUDED_LIBINTL = @BUILD_INCLUDED_LIBINTL@
CATOBJEXT = @CATOBJEXT@
CC = @CC@
CPP = @CPP@
CXX = @CXX@
CXXCPP = @CXXCPP@
DATADIRNAME = @DATADIRNAME@
DLLTOOL = @DLLTOOL@
ECHO = @ECHO@
EGREP = @EGREP@
EXEEXT = @EXEEXT@
F77 = @F77@
GCJ = @GCJ@
GCJFLAGS = @GCJFLAGS@
GENCAT = @GENCAT@
GLIBC2 = @GLIBC2@
GLIBC21 = @GLIBC21@
GMSGFMT = @GMSGFMT@
GSM_VERSION = @GSM_VERSION@
HAVE_ASPRINTF = @HAVE_ASPRINTF@
HAVE_LIB = @HAVE_LIB@
HAVE_POSIX_PRINTF = @HAVE_POSIX_PRINTF@
HAVE_SNPRINTF = @HAVE_SNPRINTF@
HAVE_WPRINTF = @HAVE_WPRINTF@
INSTOBJEXT = @INSTOBJEXT@
INTLBISON = @INTLBISON@
INTLLIBS = @INTLLIBS@
INTLOBJS = @INTLOBJS@
INTL_LIBTOOL_SUFFIX_PREFIX = @INTL_LIBTOOL_SUFFIX_PREFIX@
INTL_MACOSX_LIBS = @INTL_MACOSX_LIBS@
LIB = @LIB@
LIBICONV = @LIBICONV@
LIBINTL = @LIBINTL@
LIBTOOL = @LIBTOOL@
LN_S = @LN_S@
LTLIB = @LTLIB@
LTLIBICONV = @LTLIBICONV@
LTLIBINTL = @LTLIBINTL@
MAKEINFO = @MAKEINFO@
MKINSTALLDIRS = @MKINSTALLDIRS@
OBJDUMP = @OBJDUMP@
OBJEXT = @OBJEXT@
PACKAGE = @PACKAGE@
POSUB = @POSUB@
RANLIB = @RANLIB@
RC = @RC@
STRIP = @STRIP@
USE_INCLUDED_LIBINTL = @USE_INCLUDED_LIBINTL@
USE_NLS = @USE_NLS@
VERSION = @VERSION@
SUBDIRS_ = po gsmlib apps tests doc scripts win32 ext
EXTRA_DIST = gsmlib.spec
@COMPILE_INTL_TRUE@SUBDIRS = intl $(SUBDIRS_) # po - make automake happy
@COMPILE_INTL_FALSE@SUBDIRS = $(SUBDIRS_) # po intl - make automake happy
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
mkinstalldirs = $(SHELL) $(top_srcdir)/scripts/mkinstalldirs
CONFIG_HEADER = gsm_config.h
CONFIG_CLEAN_FILES =
DIST_COMMON = README ./stamp-h.in ABOUT-NLS AUTHORS COPYING ChangeLog \
INSTALL Makefile.am Makefile.in NEWS TODO acconfig.h acinclude.m4 \
aclocal.m4 configure configure.in gsm_config.h.in
DISTFILES = $(DIST_COMMON) $(SOURCES) $(HEADERS) $(TEXINFOS) $(EXTRA_DIST)
TAR = tar
GZIP_ENV = --best
DIST_SUBDIRS = intl po gsmlib apps tests doc scripts win32 ext po \
gsmlib apps tests doc scripts win32 ext
all: all-redirect
.SUFFIXES:
$(srcdir)/Makefile.in: Makefile.am $(top_srcdir)/configure.in $(ACLOCAL_M4)
cd $(top_srcdir) && $(AUTOMAKE) --gnu Makefile
Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status $(BUILT_SOURCES)
cd $(top_builddir) \
&& CONFIG_FILES=$@ CONFIG_HEADERS= $(SHELL) ./config.status
$(ACLOCAL_M4): configure.in acinclude.m4
cd $(srcdir) && $(ACLOCAL)
config.status: $(srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
$(SHELL) ./config.status --recheck
$(srcdir)/configure: $(srcdir)/configure.in $(ACLOCAL_M4) $(CONFIGURE_DEPENDENCIES)
cd $(srcdir) && $(AUTOCONF)
gsm_config.h: stamp-h
@if test ! -f $@; then \
rm -f stamp-h; \
$(MAKE) stamp-h; \
else :; fi
stamp-h: $(srcdir)/gsm_config.h.in $(top_builddir)/config.status
cd $(top_builddir) \
&& CONFIG_FILES= CONFIG_HEADERS=gsm_config.h \
$(SHELL) ./config.status
@echo timestamp > stamp-h 2> /dev/null
$(srcdir)/gsm_config.h.in: $(srcdir)/stamp-h.in
@if test ! -f $@; then \
rm -f $(srcdir)/stamp-h.in; \
$(MAKE) $(srcdir)/stamp-h.in; \
else :; fi
$(srcdir)/stamp-h.in: $(top_srcdir)/configure.in $(ACLOCAL_M4) acconfig.h
cd $(top_srcdir) && $(AUTOHEADER)
@echo timestamp > $(srcdir)/stamp-h.in 2> /dev/null
mostlyclean-hdr:
clean-hdr:
distclean-hdr:
-rm -f gsm_config.h
maintainer-clean-hdr:
# This directory's subdirectories are mostly independent; you can cd
# into them and run `make' without going through this Makefile.
# To change the values of `make' variables: instead of editing Makefiles,
# (1) if the variable is set in `config.status', edit `config.status'
# (which will cause the Makefiles to be regenerated when you run `make');
# (2) otherwise, pass the desired values on the `make' command line.
@SET_MAKE@
all-recursive install-data-recursive install-exec-recursive \
installdirs-recursive install-recursive uninstall-recursive \
check-recursive installcheck-recursive info-recursive dvi-recursive:
@set fnord $(MAKEFLAGS); amf=$$2; \
dot_seen=no; \
target=`echo $@ | sed s/-recursive//`; \
list='$(SUBDIRS)'; for subdir in $$list; do \
echo "Making $$target in $$subdir"; \
if test "$$subdir" = "."; then \
dot_seen=yes; \
local_target="$$target-am"; \
else \
local_target="$$target"; \
fi; \
(cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \
|| case "$$amf" in *=*) exit 1;; *k*) fail=yes;; *) exit 1;; esac; \
done; \
if test "$$dot_seen" = "no"; then \
$(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \
fi; test -z "$$fail"
mostlyclean-recursive clean-recursive distclean-recursive \
maintainer-clean-recursive:
@set fnord $(MAKEFLAGS); amf=$$2; \
dot_seen=no; \
rev=''; list='$(SUBDIRS)'; for subdir in $$list; do \
rev="$$subdir $$rev"; \
test "$$subdir" != "." || dot_seen=yes; \
done; \
test "$$dot_seen" = "no" && rev=". $$rev"; \
target=`echo $@ | sed s/-recursive//`; \
for subdir in $$rev; do \
echo "Making $$target in $$subdir"; \
if test "$$subdir" = "."; then \
local_target="$$target-am"; \
else \
local_target="$$target"; \
fi; \
(cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \
|| case "$$amf" in *=*) exit 1;; *k*) fail=yes;; *) exit 1;; esac; \
done && test -z "$$fail"
tags-recursive:
list='$(SUBDIRS)'; for subdir in $$list; do \
test "$$subdir" = . || (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) tags); \
done
tags: TAGS
ID: $(HEADERS) $(SOURCES) $(LISP)
list='$(SOURCES) $(HEADERS)'; \
unique=`for i in $$list; do echo $$i; done | \
awk ' { files[$$0] = 1; } \
END { for (i in files) print i; }'`; \
here=`pwd` && cd $(srcdir) \
&& mkid -f$$here/ID $$unique $(LISP)
TAGS: tags-recursive $(HEADERS) $(SOURCES) gsm_config.h.in $(TAGS_DEPENDENCIES) $(LISP)
tags=; \
here=`pwd`; \
list='$(SUBDIRS)'; for subdir in $$list; do \
if test "$$subdir" = .; then :; else \
test -f $$subdir/TAGS && tags="$$tags -i $$here/$$subdir/TAGS"; \
fi; \
done; \
list='$(SOURCES) $(HEADERS)'; \
unique=`for i in $$list; do echo $$i; done | \
awk ' { files[$$0] = 1; } \
END { for (i in files) print i; }'`; \
test -z "$(ETAGS_ARGS)gsm_config.h.in$$unique$(LISP)$$tags" \
|| (cd $(srcdir) && etags -o $$here/TAGS $(ETAGS_ARGS) $$tags gsm_config.h.in $$unique $(LISP))
mostlyclean-tags:
clean-tags:
distclean-tags:
-rm -f TAGS ID
maintainer-clean-tags:
distdir = $(PACKAGE)-$(VERSION)
top_distdir = $(distdir)
# This target untars the dist file and tries a VPATH configuration. Then
# it guarantees that the distribution is self-contained by making another
# tarfile.
distcheck: dist
-rm -rf $(distdir)
GZIP=$(GZIP_ENV) $(TAR) zxf $(distdir).tar.gz
mkdir $(distdir)/=build
mkdir $(distdir)/=inst
dc_install_base=`cd $(distdir)/=inst && pwd`; \
cd $(distdir)/=build \
&& ../configure --with-included-gettext --srcdir=.. --prefix=$$dc_install_base \
&& $(MAKE) $(AM_MAKEFLAGS) \
&& $(MAKE) $(AM_MAKEFLAGS) dvi \
&& $(MAKE) $(AM_MAKEFLAGS) check \
&& $(MAKE) $(AM_MAKEFLAGS) install \
&& $(MAKE) $(AM_MAKEFLAGS) installcheck \
&& $(MAKE) $(AM_MAKEFLAGS) dist
-rm -rf $(distdir)
@banner="$(distdir).tar.gz is ready for distribution"; \
dashes=`echo "$$banner" | sed s/./=/g`; \
echo "$$dashes"; \
echo "$$banner"; \
echo "$$dashes"
dist: distdir
-chmod -R a+r $(distdir)
GZIP=$(GZIP_ENV) $(TAR) chozf $(distdir).tar.gz $(distdir)
-rm -rf $(distdir)
dist-all: distdir
-chmod -R a+r $(distdir)
GZIP=$(GZIP_ENV) $(TAR) chozf $(distdir).tar.gz $(distdir)
-rm -rf $(distdir)
distdir: $(DISTFILES)
-rm -rf $(distdir)
mkdir $(distdir)
-chmod 777 $(distdir)
here=`cd $(top_builddir) && pwd`; \
top_distdir=`cd $(distdir) && pwd`; \
distdir=`cd $(distdir) && pwd`; \
cd $(top_srcdir) \
&& $(AUTOMAKE) --include-deps --build-dir=$$here --srcdir-name=$(top_srcdir) --output-dir=$$top_distdir --gnu Makefile
@for file in $(DISTFILES); do \
d=$(srcdir); \
if test -d $$d/$$file; then \
cp -pr $$d/$$file $(distdir)/$$file; \
else \
test -f $(distdir)/$$file \
|| ln $$d/$$file $(distdir)/$$file 2> /dev/null \
|| cp -p $$d/$$file $(distdir)/$$file || :; \
fi; \
done
for subdir in $(DIST_SUBDIRS); do \
if test "$$subdir" = .; then :; else \
test -d $(distdir)/$$subdir \
|| mkdir $(distdir)/$$subdir \
|| exit 1; \
chmod 777 $(distdir)/$$subdir; \
(cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) top_distdir=../$(distdir) distdir=../$(distdir)/$$subdir distdir) \
|| exit 1; \
fi; \
done
info-am:
info: info-recursive
dvi-am:
dvi: dvi-recursive
check-am: all-am
check: check-recursive
installcheck-am:
installcheck: installcheck-recursive
all-recursive-am: gsm_config.h
$(MAKE) $(AM_MAKEFLAGS) all-recursive
install-exec-am:
install-exec: install-exec-recursive
install-data-am:
install-data: install-data-recursive
install-am: all-am
@$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
install: install-recursive
uninstall-am:
uninstall: uninstall-recursive
all-am: Makefile gsm_config.h
all-redirect: all-recursive-am
install-strip:
$(MAKE) $(AM_MAKEFLAGS) AM_INSTALL_PROGRAM_FLAGS=-s install
installdirs: installdirs-recursive
installdirs-am:
mostlyclean-generic:
clean-generic:
distclean-generic:
-rm -f Makefile $(CONFIG_CLEAN_FILES)
-rm -f config.cache config.log stamp-h stamp-h[0-9]*
maintainer-clean-generic:
mostlyclean-am: mostlyclean-hdr mostlyclean-tags mostlyclean-generic
mostlyclean: mostlyclean-recursive
clean-am: clean-hdr clean-tags clean-generic mostlyclean-am
clean: clean-recursive
distclean-am: distclean-hdr distclean-tags distclean-generic clean-am
-rm -f libtool
distclean: distclean-recursive
-rm -f config.status
maintainer-clean-am: maintainer-clean-hdr maintainer-clean-tags \
maintainer-clean-generic distclean-am
@echo "This command is intended for maintainers to use;"
@echo "it deletes files that may require special tools to rebuild."
maintainer-clean: maintainer-clean-recursive
-rm -f config.status
.PHONY: mostlyclean-hdr distclean-hdr clean-hdr maintainer-clean-hdr \
install-data-recursive uninstall-data-recursive install-exec-recursive \
uninstall-exec-recursive installdirs-recursive uninstalldirs-recursive \
all-recursive check-recursive installcheck-recursive info-recursive \
dvi-recursive mostlyclean-recursive distclean-recursive clean-recursive \
maintainer-clean-recursive tags tags-recursive mostlyclean-tags \
distclean-tags clean-tags maintainer-clean-tags distdir info-am info \
dvi-am dvi check check-am installcheck-am installcheck all-recursive-am \
install-exec-am install-exec install-data-am install-data install-am \
install uninstall-am uninstall all-redirect all-am all installdirs-am \
installdirs mostlyclean-generic distclean-generic clean-generic \
maintainer-clean-generic clean mostlyclean distclean maintainer-clean
all:
# Tell versions [3.59,3.63) of GNU make to not export all variables.
# Otherwise a system limit (for SysV at least) may be exceeded.
.NOEXPORT:

View File

@ -0,0 +1,11 @@
NEWS - 9.1.2000
Version 1.0 - first release with RPM support and binary packages
NEWS - 15.11.1999
BETA version (details see ChangeLog)
NEWS - 16.7.1999
initial release

View File

@ -0,0 +1,166 @@
INTRODUCTION
This distribution contains a library to access GSM mobile phones
through GSM modems or IrDA devices. Features include:
* modification of phonebooks stored in the mobile phone or on the
SIM card
* reading and writing of SMS messages stored in the mobile phone
* sending and reception of SMS messages
Additionally, some simple command line programs are provided to
use these functionalities.
REQUIREMENTS
You need a mobile phone that conforms to the GSM
standards ETSI GSM 07.07, ETSI GSM 07.05, and others.
Non-GSM mobile phones will not work! Additionally,
to access the mobile phone from the computer you will probably need an
GSM modem (that would be a PC-CARD, usually). There might be some
mobile phones, however, that incorporate directly terminal
adapter (TA) functionality. Access via IrDA interfaces is also
reported to work.
If you want to compile the library yourself please also read
doc/README.developers.
INSTALLATION
This distribution uses autoconf/automake/libtool. See the file
INSTALL for generic installation instructions. The default
commands for installation under /usr/local would be:
./configure
make
make install
If there are any problems you can generate a debug version. See
doc/README.developers for details.
AVAILABLE DOCUMENTATION
For the command line tools UNIX manual pages are available in the
doc subdirectory of this distribution. These are installed by
default in the directories /usr/local/man1, man7, and man8.
See also the files doc/README.developers, doc/README.NLS and doc/FAQ.
HARDWARE
The following mobile phone/GSM modem combinations are reported to
be compatible in varying degrees with the current release:
- Nokia 6150/Xircom REM56G.100
- Nokia 6150/Options "GSM-Ready(R) Cellular-Only" modem
from Option International
- Nokia 6210/- (Linux IrDA serial device)
- Nokia 8810/- (Linux IrDA serial device)
- Siemens S10D/Dr Neuhaus Gipsy Card GSM
- Siemens S25/- (Linux IrDA serial device)
- Siemens S35i/- (Linux IrDA serial device)
- Siemens S45
- Ericcson SH888/- (Linux IrDA serial device)
- Ericsson 6050102/GM 12 GSM module
- Ericsson T28s (firmware 000809 1106)
- Ericsson T20e (firmware R3A007)
- -/Siemens M20T (stand-alone GSM module)
- -/Wavecom WM02 GSM (stand-alone GSM module)
- Nokia 7110 (firware rev 4.80)/- (Linux IrDA serial device)
- Nokia 8290 (USA GSM 1900MHz)/- (Linux IrDA serial device)
- Falcom A2-1/- (stand-alone GSM module)
- Ericsson R320s/- (Linux IrDA serial device)
- Motorola Timeport 260/- (Serial cable and Linux IrDA serial device)
- Motorola Timeport 250/- (Linux IrDA serial device)
- Motorola Timeport P7389/- (Linux IrDA serial device)
- Nokia Cellular Card Phone RPE-1 GSM900 and
- Nokia Card Phone RPM-1 GSM900/1800
- Nokia Cardphone/Compaq iPAQ
- Omnipoint technologies Redhawk 2000 GSM modem
- Ericsson T28 (but one firmware revision is reported to have problems)
- Ericcson T65
- Ericcson T39m/Bluetooth
- Option International GlobeTrotter PCMCIA
Note 1: Some of the mobile phones have an integrated GSM modem
that can be accessed via the Linux IrDA drivers.
Note 2: Some of the abovementioned phones have still some glitches
with gsmlib (and I haven't tested them myself).
For the following phones I receive a lot of errors reports:
- Ericcson SH888: SMS function don't work with many firmware releases
This list is not exhaustive, there are probably many other types of
phone or GSM modem that work with gsmlib. Just try it and report back
to me!
DISCLAIMER
Even though care has been taken in the design and implementation
of this software it can not be excluded that this software could
destroy data in your mobile phone or may even render your mobile
phone useless (by erroneous PIN settings, for example). The
author will not be held responsible legally, financially, or in any
other form for any kind of damage that might occur from using
this software.
This software is provided "as is" and without any expressed or implied
warranties, including, without limitation, the implied warranties of
merchantibility and fitness for any particular purpose.
If you are not ready to accept these conditions please don't use
this software.
COPYING
This software is available on the LGPL (GNU LIBRARY GENERAL
PUBLIC LICENSE), ie. it is allowed to link
the library to commercial programs.
See the file COPYING for details on the license.
BUGS
There still seem to be some problems with IrDA devices under
Linux. There have been reports of gsmlib-based applications
(eg. gsmctl) hanging upon startup after initializing the serial port
/dev/ircomm. I would be thankful for any input on this problem.
If something does not work with your OS platform or the mobile/TA
combination please send a complete trace of the compilation or the
program execution that did fail. Make sure to compile with debugging
information enabled. Otherwise it will not be possible for me to do
much about the problem. Send bug reports to the mailing list or
to software@pxh.de. I promise not to publish telephone numbers or other
private information that might be contained in the execution traces
that you send me.
MAILING LISTS
There are now two mailings lists available for announcements and
discussion of gsmlib-related issues (hosted on lists.over.net).
Refer to these pages for information on subscription procedures
and an archive of previous postings:
http://lists.over.net/mailman/listinfo/gsmlib-announce/
for announcements regarding GSMLIB
http://lists.over.net/mailman/listinfo/gsmlib-devel/
the GSMLIB development list
AUTHOR
Peter Hofmann <software@pxh.de>.

View File

@ -0,0 +1,289 @@
This is my list of TODOs for development of this software (not
necessarily in order of importance):
("+" = DONE)
+ handle:
> --> AT+COPS=?
> <--
> <-- +COPS: (1,"AMENA",,"21403"),(3,"MOVISTAR",,"21407"),
> <-- (3,"E VODAFONE",,"21401"),,(0,1),(2)
> <--
> <-- OK
> gsmctl[ERROR]: expected comma (at position 45 of string '(1,"AMENA",,"21403"),(3,"MOVISTAR",,"21407"),')
+ extend README and web site with names of working phones (Siemens S45,...)
+ add workaround:
> <ME0> Manufacturer: Nokia Mobile Phones
> <ME1> Model: 8290
> <ME2> Revision: SW5.22
> <ME3> Serial Number: 010070303406434
> <FUN> Functionality Level: 1
> gsmctl[ERROR]: expected number, got '(2)'
- add fork to gsmsmsd
+ document "on" and "off" operations of gsmctl
- Just assume full functionality and issue AT+CGMF=0 if we haven't already
done so for this MeTa.
+ make update po
+ add find function
+ specify exact location of manual files in /usr/man/man* in spec
file, so that erase does not try to delete these directories
+ update PO
+ add option to gsmsendsms/gsmsmsd to request delivery reports
+ Fix CBM reception in gsmsmsd, see testcb.cc program
+ fix gsmsmsd:
--> AT+CNMI=?
<--
<-- +CNMI: (1),(1),(0),(0),(0)
<--
<-- OK
--> AT+CNMI=1,0,0,0,0
<--
<-- +CME ERROR: 003
./gsmsmsd[ERROR]: ME/TA error 'operation not allowed' (code 003)
+ Wenn ich den SMS-Speicher auslesen möchte, bricht gsmlib ab, weil der
Speicherplatz 1 auf der SIM-Karte nicht belegt ist. Das kann z.B.
passieren, wenn man Nachrichten im Handy löscht. Es kommt der Fehlercode
321 (Invalid memory index). Wie wäre es, in der Leseroutine alle
ungültigen Plätze zu ignorieren und solange zu lesen, bis die Anzahl der
vorhandenen Nachrichten im Speicher eingelesen ist?
+ document --charset option of gsmpb
+ Problems with PDUs with alphanumeric SCA, e.g.:
07911497941902F00414D0E474989D769F5DE4320839001040122151820000
+ > 2. Ich kann mit meinem Nokia 6210 nicht den Telefon-SMS-Speicher
auslesen. Dies liegt an der Speicherwahl, die vor dem Auslesen
an das Telefon übermittelt wird. Von der gsmlib wird anscheinend
immer die Anzahl der Speicher aus dem "CPMS=?"-Befehl genommen
(z.B. "SM","SM","SM"). Notwendig ist es aber nur, die erste
Position (zum Lesen und Löschen) bzw. die ersten beiden
Positionen (zum Schreiben) zu benutzen.
Das Nokia 6210 unterstützt aber an der ritten Stelle nur "SM",
nicht "ME". So kann ich die SMS im Telefon leider nicht
auslesen :-(
- add option to gsmpb/gsmssmstore deletion to delete ALL entries
- recheck Solaris port
+ cache character set settings in MeTa
+ add documentation for new gsmctl and gsmpb charset parameters
+ support characters sets other than GSM default alphabet for phone books
+ create non-existent files (gsmpb and gsmsmsstore)
+ rename libgsm to libgsmme, new major version 1
+ document sca/setsca operations/parameters in gsmctl
+ document option to set SCA in SMS-related apps
+ implement option to set SCA in SMS-related apps
+ convert NDEBUG test output from cout to cerr
+ test new gsm_unix_serial behaviour
+ apply checks for telephone number in gsm_sorted_phonebook
+ add interrupted() checks
+ check for gcc-2.95.2 in configure
- document custom backend options of gsmpb (and gsmsmsstore)
- /var/lock/LCK..modem
+ make gsmctl all continue even if there are some failures
+ CPIN thing
+ bring German translations up-to-date
+ document -I parameter
+ make chat routines robust against TAs that insist on echoing AT commands
+ ericsson sh 888:
<-- AT+CLCK="P2",2,,1
<--
+CME ERROR: 4
gsmctl[ERROR]: ME/TA error 'operation not supported' (code 4)
+ put README etc. into gsmlib package (not only devel)
+ make SMS decoding routines more robust against bad SMS (especially
premature end of PDU)
+ stop gsm_sorted_sms_store.cc from copying back SMS that came from
the SC (SMS_DELIVER, SMS_STATUS_REPORT, SMS_SUBMIT_REPORT). Their
message type is ambiguous and the ME may misinterpret them.
+ gsmsmsd: reinitialize modem every hour or so (signal termination implemented)
+ implement store, flush and spool options of gsmsmsd,
document them in man pages
+ test case for COPS answer numeric operator name in quotation marks
(testparser.cc)
+ retry when initializing TA (ATZ/ATE0 sequences)
+ correctly parse malformed SMS PDUs without SCA with Ericsson phone,
introduce Capability object for that. Ericsson ID:
<ME0> Manufacturer: ERICSSON
<ME1> Model: 6050102
<ME2> Revision: 990225 1852 CXC112143
<ME3> Serial Number: 520001690279310
+ Determine CPMS number of parameters for CPMS command (Ericsson
phone/GM12 GSM modem):
AT+CPMS?
+CPMS: "ME",0,10,"ME",0,10
AT+CPMS=?
+CPMS: ("ME","SM"),("ME","SM")
+ accept string as numeric value when interpreting COPS=? response
(Ericsson phone + GSM12 GSM module)
+ accept string as numeric value when interpreting COPS? response
(Ericsson phone + GSM12 GSM module)
+ It would be nice if it was possible to send sms:es
via gsmsmsd as well, via a spool directory or a socket (or stdin, in which
case one can put another program in front of this program and then
feed it with outgoing messages any way one wants). That way the program
could be the gateway between programs and the sms network. Now one has
to stop gsmsmsd to send an sms and that's not so elegant or write
ones own program.
+ gsmsmsd geht davon aus, das ein platz frei ist und benutzt nur diesen....
Wenn also eine SMS kommt, dann zieht es Sie raus, und löscht den
Speicherplatz.
Wenn aber die Karte voll ist, passiert gar nichts. Für eine automatisierte
umgebung ist das schlecht. besser wäre es, bei startup von gsmsmsd alle
Speicherplätze abzufrühstücken, und die Action aufzurufen.
+ Ein RING bringt den gsmsmsd ziemlich heftig aus dem Tritt. Hab jetzt ´ne
Rufumleitung eingebaut.
+ Links section in homepage
+ AT+CNMI=? liefert bei mir folgendes zurück:
+CNMI: (0-3),(0-3),(0-2),0,(0-1)
Parameter 4 (<ds>) liefert also keine Liste sondern nur ein Int zurück, du
versuchts aber ein ( zu parsen.
Was sagt die ETSI-spec. dazu ?? Ist das konform ??
+ give name of command at beginning of synopsis in man pages
+ list combinations of mobiles phones/GSM modems in the README
+ test ALARM in case of timeout when writing or reading to TA
+ install headers in gsmlib subdirectory
+ RPM spec file
+ test index changes for sorted phonebook -> write second test case
+ sort phone numbers the same way in gsm_sorted_sms_store and
gsm_sorted_phonebook
+ write glossary for all these nice abbreviations (TA, ME, SC, SME, TE)
+ HAVE_VSNPRINTF instead of HAVE_VPRINTF
+ internationalization of messages with GNU gettext. Files:
+gsm_at.cc +gsm_parser.cc +gsm_sorted_phonebook.cc
+gsm_error.cc +gsm_phonebook.cc +gsm_sorted_sms_store.cc
+gsm_event.cc +gsm_sms.cc +gsm_unix_serial.cc
+gsm_me_ta.cc +gsm_sms_codec.cc +gsm_util.cc
+gsm_nls.cc +gsm_sms_store.cc
+gsmctl.cc +gsmpb.cc +gsmsendsms.cc
+gsmsmsd.cc +gsmsmsstore.cc
+ implement indexed phonebook ops in gsmpb.cc
+ describe phonebook file format in gsmpb.man
+ update list of compatible hardware in README
+ all #include <gsm_config.h> must be enclosed in #ifdef's
+ check for getopt_long in configure
+ remove asserts regarding lengths of numeric data types, put them
into configure script
(string)
+ sort options in apps/*.cc alphabetically
+ in gsm_sorted_sms_store compare telephone numbers numerically
+ introduce -v option to gsmpb and gsmsmsstore to report execution
statistics (gives a nicer feeling to users)
+ test new synchronization function in gsmpb program
+ implement equality operator for SMSSToreEntry
+ test 'make install'
+ implement operations in the gsmctl program
+ test operations in the gsmctl program
+ document operations in the gsmctl program
+ rewrite test cases (compare output)
+ write gsm_sorted_sms_store module (along the lines of gsm_sorted_phonebook)
+ complete gsmsmsstore program (using abovementioned modules)
TODO low priority:
- implement SMS text mode
- The action command of gsmsmsd would be easier to make, if the program
sent the values in environment variables instead (except the user data
which could be sent on stdin).
+ Upgrade to latest autoheader, autoconf, libtool
- provide German translations for manual pages
- organize doc subdirectory for translated READMEs, manual pages
+ Win32 port
- test: optimization when accessing phonebooks: use size information
available via AT command to stop reading entries known to be empty (I
cannot test this with my hardware since CPBS? is not fully supported)
- make apps accept stdin or stdout
+ maybe strip leading and trailing whitespace from phonebook entries
when reading them from ME/TA or file? (not done, perhaps users want to
achieve special effects with white space)
- support international character sets (8-bit, 16-bit) in phonebook
operations (I'd like to have input from users who need this)

View File

@ -0,0 +1,33 @@
/* used by libtool*/
#define PACKAGE 0
/* used by libtool*/
#define VERSION 0
/* Define if getopt_long() available */
#undef HAVE_GETOPT_LONG
/* Define if alarm() available */
#undef HAVE_ALARM
/* Define if netinet/in.h header available */
#undef HAVE_NETINET_IN_H
/* Define if string.h header available */
#undef HAVE_STRING_H
/* Define for NLS */
#undef ENABLE_NLS
#undef HAVE_CATGETS
#undef HAVE_GETTEXT
#undef HAVE_LC_MESSAGES
#undef HAVE_STPCPY
/* Define LOCALEDIR */
#define LOCALEDIR "/usr/share/locale"
/* Define if libintl.h header available */
#undef HAVE_LIBINTL_H
/* Define if vsnprintf() function available */
#undef HAVE_VSNPRINTF

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,36 @@
## Process this file with automake to produce Makefile.in
# *************************************************************************
# * GSM TA/ME library
# *
# * File: Makefile.am
# *
# * Purpose: apps Makefile
# *
# * Author: Peter Hofmann (software@pxh.de)
# *
# * Created: 5.6.1999
# *************************************************************************
INCLUDES = -I..
bin_PROGRAMS = gsmsmsstore gsmctl gsmsmsd gsmpb gsmsendsms
# build gsmsmsd from gsmsmsd.cc and libgsmme.la
gsmsmsd_SOURCES = gsmsmsd.cc
gsmsmsd_LDADD = ../gsmlib/libgsmme.la $(INTLLIBS)
# build gsmpb from gsmpb.cc and libgsmme.la
gsmpb_SOURCES = gsmpb.cc
gsmpb_LDADD = ../gsmlib/libgsmme.la $(INTLLIBS)
# build gsmctl from gsmctl.cc and libgsmme.la
gsmctl_SOURCES = gsmctl.cc
gsmctl_LDADD = ../gsmlib/libgsmme.la $(INTLLIBS)
# build gsmsendsms from gsmsendsms.cc and libgsmme.la
gsmsendsms_SOURCES = gsmsendsms.cc
gsmsendsms_LDADD = ../gsmlib/libgsmme.la $(INTLLIBS)
# build gsmsmsstore from gsmsmsstore.cc and libgsmme.la
gsmsmsstore_SOURCES = gsmsmsstore.cc
gsmsmsstore_LDADD = ../gsmlib/libgsmme.la $(INTLLIBS)

View File

@ -0,0 +1,442 @@
# Makefile.in generated by automake 1.6.3 from Makefile.am.
# @configure_input@
# Copyright 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002
# Free Software Foundation, Inc.
# This Makefile.in is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
# with or without modifications, as long as this notice is preserved.
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
# PARTICULAR PURPOSE.
@SET_MAKE@
# *************************************************************************
# * GSM TA/ME library
# *
# * File: Makefile.am
# *
# * Purpose: apps Makefile
# *
# * Author: Peter Hofmann (software@pxh.de)
# *
# * Created: 5.6.1999
# *************************************************************************
SHELL = @SHELL@
srcdir = @srcdir@
top_srcdir = @top_srcdir@
VPATH = @srcdir@
prefix = @prefix@
exec_prefix = @exec_prefix@
bindir = @bindir@
sbindir = @sbindir@
libexecdir = @libexecdir@
datadir = @datadir@
sysconfdir = @sysconfdir@
sharedstatedir = @sharedstatedir@
localstatedir = @localstatedir@
libdir = @libdir@
infodir = @infodir@
mandir = @mandir@
includedir = @includedir@
oldincludedir = /usr/include
pkgdatadir = $(datadir)/@PACKAGE@
pkglibdir = $(libdir)/@PACKAGE@
pkgincludedir = $(includedir)/@PACKAGE@
top_builddir = ..
ACLOCAL = @ACLOCAL@
AUTOCONF = @AUTOCONF@
AUTOMAKE = @AUTOMAKE@
AUTOHEADER = @AUTOHEADER@
am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
INSTALL = @INSTALL@
INSTALL_PROGRAM = @INSTALL_PROGRAM@
INSTALL_DATA = @INSTALL_DATA@
install_sh_DATA = $(install_sh) -c -m 644
install_sh_PROGRAM = $(install_sh) -c
install_sh_SCRIPT = $(install_sh) -c
INSTALL_SCRIPT = @INSTALL_SCRIPT@
INSTALL_HEADER = $(INSTALL_DATA)
transform = @program_transform_name@
NORMAL_INSTALL = :
PRE_INSTALL = :
POST_INSTALL = :
NORMAL_UNINSTALL = :
PRE_UNINSTALL = :
POST_UNINSTALL = :
host_alias = @host_alias@
host_triplet = @host@
EXEEXT = @EXEEXT@
OBJEXT = @OBJEXT@
PATH_SEPARATOR = @PATH_SEPARATOR@
AMTAR = @AMTAR@
AS = @AS@
AWK = @AWK@
BUILD_INCLUDED_LIBINTL = @BUILD_INCLUDED_LIBINTL@
CATOBJEXT = @CATOBJEXT@
CC = @CC@
CPP = @CPP@
CXX = @CXX@
DATADIRNAME = @DATADIRNAME@
DEPDIR = @DEPDIR@
DLLTOOL = @DLLTOOL@
ECHO = @ECHO@
GENCAT = @GENCAT@
GLIBC21 = @GLIBC21@
GMSGFMT = @GMSGFMT@
GSM_VERSION = @GSM_VERSION@
HAVE_LIB = @HAVE_LIB@
INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
INSTOBJEXT = @INSTOBJEXT@
INTLBISON = @INTLBISON@
INTLLIBS = @INTLLIBS@
INTLOBJS = @INTLOBJS@
INTL_LIBTOOL_SUFFIX_PREFIX = @INTL_LIBTOOL_SUFFIX_PREFIX@
LIB = @LIB@
LIBICONV = @LIBICONV@
LIBINTL = @LIBINTL@
LIBTOOL = @LIBTOOL@
LN_S = @LN_S@
LTLIB = @LTLIB@
LTLIBICONV = @LTLIBICONV@
LTLIBINTL = @LTLIBINTL@
MKINSTALLDIRS = @MKINSTALLDIRS@
OBJDUMP = @OBJDUMP@
PACKAGE = @PACKAGE@
POSUB = @POSUB@
RANLIB = @RANLIB@
STRIP = @STRIP@
USE_INCLUDED_LIBINTL = @USE_INCLUDED_LIBINTL@
USE_NLS = @USE_NLS@
VERSION = @VERSION@
am__include = @am__include@
am__quote = @am__quote@
install_sh = @install_sh@
INCLUDES = -I..
bin_PROGRAMS = gsmsmsstore gsmctl gsmsmsd gsmpb gsmsendsms
# build gsmsmsd from gsmsmsd.cc and libgsmme.la
gsmsmsd_SOURCES = gsmsmsd.cc
gsmsmsd_LDADD = ../gsmlib/libgsmme.la $(INTLLIBS)
# build gsmpb from gsmpb.cc and libgsmme.la
gsmpb_SOURCES = gsmpb.cc
gsmpb_LDADD = ../gsmlib/libgsmme.la $(INTLLIBS)
# build gsmctl from gsmctl.cc and libgsmme.la
gsmctl_SOURCES = gsmctl.cc
gsmctl_LDADD = ../gsmlib/libgsmme.la $(INTLLIBS)
# build gsmsendsms from gsmsendsms.cc and libgsmme.la
gsmsendsms_SOURCES = gsmsendsms.cc
gsmsendsms_LDADD = ../gsmlib/libgsmme.la $(INTLLIBS)
# build gsmsmsstore from gsmsmsstore.cc and libgsmme.la
gsmsmsstore_SOURCES = gsmsmsstore.cc
gsmsmsstore_LDADD = ../gsmlib/libgsmme.la $(INTLLIBS)
subdir = apps
mkinstalldirs = $(SHELL) $(top_srcdir)/scripts/mkinstalldirs
CONFIG_HEADER = $(top_builddir)/gsm_config.h
CONFIG_CLEAN_FILES =
bin_PROGRAMS = gsmsmsstore$(EXEEXT) gsmctl$(EXEEXT) gsmsmsd$(EXEEXT) \
gsmpb$(EXEEXT) gsmsendsms$(EXEEXT)
PROGRAMS = $(bin_PROGRAMS)
am_gsmctl_OBJECTS = gsmctl.$(OBJEXT)
gsmctl_OBJECTS = $(am_gsmctl_OBJECTS)
gsmctl_DEPENDENCIES = ../gsmlib/libgsmme.la
gsmctl_LDFLAGS =
am_gsmpb_OBJECTS = gsmpb.$(OBJEXT)
gsmpb_OBJECTS = $(am_gsmpb_OBJECTS)
gsmpb_DEPENDENCIES = ../gsmlib/libgsmme.la
gsmpb_LDFLAGS =
am_gsmsendsms_OBJECTS = gsmsendsms.$(OBJEXT)
gsmsendsms_OBJECTS = $(am_gsmsendsms_OBJECTS)
gsmsendsms_DEPENDENCIES = ../gsmlib/libgsmme.la
gsmsendsms_LDFLAGS =
am_gsmsmsd_OBJECTS = gsmsmsd.$(OBJEXT)
gsmsmsd_OBJECTS = $(am_gsmsmsd_OBJECTS)
gsmsmsd_DEPENDENCIES = ../gsmlib/libgsmme.la
gsmsmsd_LDFLAGS =
am_gsmsmsstore_OBJECTS = gsmsmsstore.$(OBJEXT)
gsmsmsstore_OBJECTS = $(am_gsmsmsstore_OBJECTS)
gsmsmsstore_DEPENDENCIES = ../gsmlib/libgsmme.la
gsmsmsstore_LDFLAGS =
DEFS = @DEFS@
DEFAULT_INCLUDES = -I. -I$(srcdir) -I$(top_builddir)
CPPFLAGS = @CPPFLAGS@
LDFLAGS = @LDFLAGS@
LIBS = @LIBS@
depcomp = $(SHELL) $(top_srcdir)/scripts/depcomp
am__depfiles_maybe = depfiles
@AMDEP_TRUE@DEP_FILES = ./$(DEPDIR)/gsmctl.Po ./$(DEPDIR)/gsmpb.Po \
@AMDEP_TRUE@ ./$(DEPDIR)/gsmsendsms.Po ./$(DEPDIR)/gsmsmsd.Po \
@AMDEP_TRUE@ ./$(DEPDIR)/gsmsmsstore.Po
CXXCOMPILE = $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \
$(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS)
LTCXXCOMPILE = $(LIBTOOL) --mode=compile $(CXX) $(DEFS) \
$(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \
$(AM_CXXFLAGS) $(CXXFLAGS)
CXXLD = $(CXX)
CXXLINK = $(LIBTOOL) --mode=link $(CXXLD) $(AM_CXXFLAGS) $(CXXFLAGS) \
$(AM_LDFLAGS) $(LDFLAGS) -o $@
CXXFLAGS = @CXXFLAGS@
DIST_SOURCES = $(gsmctl_SOURCES) $(gsmpb_SOURCES) $(gsmsendsms_SOURCES) \
$(gsmsmsd_SOURCES) $(gsmsmsstore_SOURCES)
DIST_COMMON = Makefile.am Makefile.in
SOURCES = $(gsmctl_SOURCES) $(gsmpb_SOURCES) $(gsmsendsms_SOURCES) $(gsmsmsd_SOURCES) $(gsmsmsstore_SOURCES)
all: all-am
.SUFFIXES:
.SUFFIXES: .cc .lo .o .obj
$(srcdir)/Makefile.in: Makefile.am $(top_srcdir)/configure.in $(ACLOCAL_M4)
cd $(top_srcdir) && \
$(AUTOMAKE) --gnu apps/Makefile
Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)
binPROGRAMS_INSTALL = $(INSTALL_PROGRAM)
install-binPROGRAMS: $(bin_PROGRAMS)
@$(NORMAL_INSTALL)
$(mkinstalldirs) $(DESTDIR)$(bindir)
@list='$(bin_PROGRAMS)'; for p in $$list; do \
p1=`echo $$p|sed 's/$(EXEEXT)$$//'`; \
if test -f $$p \
|| test -f $$p1 \
; then \
f=`echo "$$p1" | sed 's,^.*/,,;$(transform);s/$$/$(EXEEXT)/'`; \
echo " $(INSTALL_PROGRAM_ENV) $(LIBTOOL) --mode=install $(binPROGRAMS_INSTALL) $$p $(DESTDIR)$(bindir)/$$f"; \
$(INSTALL_PROGRAM_ENV) $(LIBTOOL) --mode=install $(binPROGRAMS_INSTALL) $$p $(DESTDIR)$(bindir)/$$f; \
else :; fi; \
done
uninstall-binPROGRAMS:
@$(NORMAL_UNINSTALL)
@list='$(bin_PROGRAMS)'; for p in $$list; do \
f=`echo "$$p" | sed 's,^.*/,,;s/$(EXEEXT)$$//;$(transform);s/$$/$(EXEEXT)/'`; \
echo " rm -f $(DESTDIR)$(bindir)/$$f"; \
rm -f $(DESTDIR)$(bindir)/$$f; \
done
clean-binPROGRAMS:
@list='$(bin_PROGRAMS)'; for p in $$list; do \
f=`echo $$p|sed 's/$(EXEEXT)$$//'`; \
echo " rm -f $$p $$f"; \
rm -f $$p $$f ; \
done
gsmctl$(EXEEXT): $(gsmctl_OBJECTS) $(gsmctl_DEPENDENCIES)
@rm -f gsmctl$(EXEEXT)
$(CXXLINK) $(gsmctl_LDFLAGS) $(gsmctl_OBJECTS) $(gsmctl_LDADD) $(LIBS)
gsmpb$(EXEEXT): $(gsmpb_OBJECTS) $(gsmpb_DEPENDENCIES)
@rm -f gsmpb$(EXEEXT)
$(CXXLINK) $(gsmpb_LDFLAGS) $(gsmpb_OBJECTS) $(gsmpb_LDADD) $(LIBS)
gsmsendsms$(EXEEXT): $(gsmsendsms_OBJECTS) $(gsmsendsms_DEPENDENCIES)
@rm -f gsmsendsms$(EXEEXT)
$(CXXLINK) $(gsmsendsms_LDFLAGS) $(gsmsendsms_OBJECTS) $(gsmsendsms_LDADD) $(LIBS)
gsmsmsd$(EXEEXT): $(gsmsmsd_OBJECTS) $(gsmsmsd_DEPENDENCIES)
@rm -f gsmsmsd$(EXEEXT)
$(CXXLINK) $(gsmsmsd_LDFLAGS) $(gsmsmsd_OBJECTS) $(gsmsmsd_LDADD) $(LIBS)
gsmsmsstore$(EXEEXT): $(gsmsmsstore_OBJECTS) $(gsmsmsstore_DEPENDENCIES)
@rm -f gsmsmsstore$(EXEEXT)
$(CXXLINK) $(gsmsmsstore_LDFLAGS) $(gsmsmsstore_OBJECTS) $(gsmsmsstore_LDADD) $(LIBS)
mostlyclean-compile:
-rm -f *.$(OBJEXT) core *.core
distclean-compile:
-rm -f *.tab.c
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gsmctl.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gsmpb.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gsmsendsms.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gsmsmsd.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gsmsmsstore.Po@am__quote@
distclean-depend:
-rm -rf ./$(DEPDIR)
.cc.o:
@AMDEP_TRUE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@ depfile='$(DEPDIR)/$*.Po' tmpdepfile='$(DEPDIR)/$*.TPo' @AMDEPBACKSLASH@
@AMDEP_TRUE@ $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
$(CXXCOMPILE) -c -o $@ `test -f '$<' || echo '$(srcdir)/'`$<
.cc.obj:
@AMDEP_TRUE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@ depfile='$(DEPDIR)/$*.Po' tmpdepfile='$(DEPDIR)/$*.TPo' @AMDEPBACKSLASH@
@AMDEP_TRUE@ $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
$(CXXCOMPILE) -c -o $@ `cygpath -w $<`
.cc.lo:
@AMDEP_TRUE@ source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@
@AMDEP_TRUE@ depfile='$(DEPDIR)/$*.Plo' tmpdepfile='$(DEPDIR)/$*.TPlo' @AMDEPBACKSLASH@
@AMDEP_TRUE@ $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
$(LTCXXCOMPILE) -c -o $@ `test -f '$<' || echo '$(srcdir)/'`$<
CXXDEPMODE = @CXXDEPMODE@
mostlyclean-libtool:
-rm -f *.lo
clean-libtool:
-rm -rf .libs _libs
distclean-libtool:
-rm -f libtool
uninstall-info-am:
ETAGS = etags
ETAGSFLAGS =
tags: TAGS
ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
unique=`for i in $$list; do \
if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
done | \
$(AWK) ' { files[$$0] = 1; } \
END { for (i in files) print i; }'`; \
mkid -fID $$unique
TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
$(TAGS_FILES) $(LISP)
tags=; \
here=`pwd`; \
list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
unique=`for i in $$list; do \
if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
done | \
$(AWK) ' { files[$$0] = 1; } \
END { for (i in files) print i; }'`; \
test -z "$(ETAGS_ARGS)$$tags$$unique" \
|| $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
$$tags $$unique
GTAGS:
here=`$(am__cd) $(top_builddir) && pwd` \
&& cd $(top_srcdir) \
&& gtags -i $(GTAGS_ARGS) $$here
distclean-tags:
-rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH
DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
top_distdir = ..
distdir = $(top_distdir)/$(PACKAGE)-$(VERSION)
distdir: $(DISTFILES)
@list='$(DISTFILES)'; for file in $$list; do \
if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
dir=`echo "$$file" | sed -e 's,/[^/]*$$,,'`; \
if test "$$dir" != "$$file" && test "$$dir" != "."; then \
dir="/$$dir"; \
$(mkinstalldirs) "$(distdir)$$dir"; \
else \
dir=''; \
fi; \
if test -d $$d/$$file; then \
if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \
fi; \
cp -pR $$d/$$file $(distdir)$$dir || exit 1; \
else \
test -f $(distdir)/$$file \
|| cp -p $$d/$$file $(distdir)/$$file \
|| exit 1; \
fi; \
done
check-am: all-am
check: check-am
all-am: Makefile $(PROGRAMS)
installdirs:
$(mkinstalldirs) $(DESTDIR)$(bindir)
install: install-am
install-exec: install-exec-am
install-data: install-data-am
uninstall: uninstall-am
install-am: all-am
@$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
installcheck: installcheck-am
install-strip:
$(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
INSTALL_STRIP_FLAG=-s \
`test -z '$(STRIP)' || \
echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install
mostlyclean-generic:
clean-generic:
distclean-generic:
-rm -f Makefile $(CONFIG_CLEAN_FILES)
maintainer-clean-generic:
@echo "This command is intended for maintainers to use"
@echo "it deletes files that may require special tools to rebuild."
clean: clean-am
clean-am: clean-binPROGRAMS clean-generic clean-libtool mostlyclean-am
distclean: distclean-am
distclean-am: clean-am distclean-compile distclean-depend \
distclean-generic distclean-libtool distclean-tags
dvi: dvi-am
dvi-am:
info: info-am
info-am:
install-data-am:
install-exec-am: install-binPROGRAMS
install-info: install-info-am
install-man:
installcheck-am:
maintainer-clean: maintainer-clean-am
maintainer-clean-am: distclean-am maintainer-clean-generic
mostlyclean: mostlyclean-am
mostlyclean-am: mostlyclean-compile mostlyclean-generic \
mostlyclean-libtool
uninstall-am: uninstall-binPROGRAMS uninstall-info-am
.PHONY: GTAGS all all-am check check-am clean clean-binPROGRAMS \
clean-generic clean-libtool distclean distclean-compile \
distclean-depend distclean-generic distclean-libtool \
distclean-tags distdir dvi dvi-am info info-am install \
install-am install-binPROGRAMS install-data install-data-am \
install-exec install-exec-am install-info install-info-am \
install-man install-strip installcheck installcheck-am \
installdirs maintainer-clean maintainer-clean-generic \
mostlyclean mostlyclean-compile mostlyclean-generic \
mostlyclean-libtool tags uninstall uninstall-am \
uninstall-binPROGRAMS uninstall-info-am
# Tell versions [3.59,3.63) of GNU make to not export all variables.
# Otherwise a system limit (for SysV at least) may be exceeded.
.NOEXPORT:

View File

@ -0,0 +1,635 @@
// *************************************************************************
// * GSM TA/ME library
// *
// * File: gsmctl.cc
// *
// * Purpose: GSM mobile phone control program
// *
// * Author: Peter Hofmann (software@pxh.de)
// *
// * Created: 11.7.1999
// *************************************************************************
#ifdef HAVE_CONFIG_H
#include <gsm_config.h>
#endif
#include <gsmlib/gsm_nls.h>
#include <string>
#if defined(HAVE_GETOPT_LONG) || defined(WIN32)
#include <getopt.h>
#endif
#include <strstream>
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <gsmlib/gsm_me_ta.h>
#include <gsmlib/gsm_util.h>
#include <gsmlib/gsm_sysdep.h>
#ifdef WIN32
#include <gsmlib/gsm_win32_serial.h>
#else
#include <gsmlib/gsm_unix_serial.h>
#include <unistd.h>
#endif
#include <iostream>
using namespace std;
using namespace gsmlib;
// my ME
static MeTa *m;
// information parameters
enum InfoParameter {AllInfo, // print all info
MeInfo, // MeInfo must be first!
FunctionalityInfo,
OperatorInfo,
CurrentOperatorInfo,
FacilityLockStateInfo,
FacilityLockCapabilityInfo,
PasswordInfo,
PINInfo,
CLIPInfo,
CallForwardingInfo,
BatteryInfo,
BitErrorInfo,
SCAInfo,
CharSetInfo,
SignalInfo}; // SignalInfo must be last!
// operation parameters
// FIXME operations not implemented yet
// options
#ifdef HAVE_GETOPT_LONG
static struct option longOpts[] =
{
{"xonxoff", no_argument, (int*)NULL, 'X'},
{"operation", required_argument, (int*)NULL, 'o'},
{"device", required_argument, (int*)NULL, 'd'},
{"baudrate", required_argument, (int*)NULL, 'b'},
{"init", required_argument, (int*)NULL, 'I'},
{"help", no_argument, (int*)NULL, 'h'},
{"version", no_argument, (int*)NULL, 'v'},
{(char*)NULL, 0, (int*)NULL, 0}
};
#else
#define getopt_long(argc, argv, options, longopts, indexptr) \
getopt(argc, argv, options)
#endif
// helper function, prints forwarding info
void printForwardReason(string s, ForwardInfo &info)
{
cout << s << " "
<< (info._active ? _("active ") : _("inactive "))
<< _("number: ") << info._number
<< _(" subaddr: ") << info._subAddr
<< _(" time: ") << info._time << endl;
}
// print information
static void printInfo(InfoParameter ip)
{
switch (ip)
{
case MeInfo:
{
MEInfo mei = m->getMEInfo();
cout << _("<ME0> Manufacturer: ") << mei._manufacturer << endl
<< _("<ME1> Model: ") << mei._model << endl
<< _("<ME2> Revision: ") << mei._revision << endl
<< _("<ME3> Serial Number: ") << mei._serialNumber << endl;
break;
}
case FunctionalityInfo:
{
try {
int fun;
fun = m->getFunctionalityLevel();
cout << _("<FUN> Functionality Level: ") << fun << endl;
} catch (GsmException &x) {
cout << _("<FUN> Functionality Level: ") << _("unsupported") << endl;
}
break;
}
case OperatorInfo:
{
int count = 0;
vector<OPInfo> opis = m->getAvailableOPInfo();
for (vector<OPInfo>::iterator i = opis.begin(); i != opis.end(); ++i)
{
cout << "<OP" << count << _("> Status: ");
switch (i->_status)
{
case UnknownOPStatus: cout << _("unknown"); break;
case CurrentOPStatus: cout << _("current"); break;
case AvailableOPStatus: cout << _("available"); break;
case ForbiddenOPStatus: cout << _("forbidden"); break;
}
cout << _(" Long name: '") << i->_longName << "' "
<< _(" Short name: '") << i->_shortName << "' "
<< _(" Numeric name: ") << i->_numericName << endl;
++count;
}
break;
}
case CurrentOperatorInfo:
{
OPInfo opi = m->getCurrentOPInfo();
cout << "<CURROP0>"
<< _(" Long name: '") << opi._longName << "' "
<< _(" Short name: '") << opi._shortName << "' "
<< _(" Numeric name: ") << opi._numericName
<< _(" Mode: ");
switch (opi._mode)
{
case AutomaticOPMode: cout << _("automatic"); break;
case ManualOPMode: cout << _("manual"); break;
case DeregisterOPMode: cout << _("deregister"); break;
case ManualAutomaticOPMode: cout << _("manual/automatic"); break;
}
cout << endl;
break;
}
case FacilityLockStateInfo:
{
int count = 0;
vector<string> fclc = m->getFacilityLockCapabilities();
for (vector<string>::iterator i = fclc.begin(); i != fclc.end(); ++i)
if (*i != "AB" && *i != "AG" && *i != "AC")
{
cout << "<FLSTAT" << count << "> '" << *i << "'";
try
{
if (m->getFacilityLockStatus(*i, VoiceFacility))
cout << _(" Voice");
}
catch (GsmException &e)
{
cout << _(" unknown");
}
try
{
if (m->getFacilityLockStatus(*i, DataFacility))
cout << _(" Data");
}
catch (GsmException &e)
{
cout << _(" unknown");
}
try
{
if (m->getFacilityLockStatus(*i, FaxFacility))
cout << _(" Fax");
}
catch (GsmException &e)
{
cout << _(" unknown");
}
cout << endl;
++count;
}
break;
}
case FacilityLockCapabilityInfo:
{
cout << "<FLCAP0> ";
vector<string> fclc = m->getFacilityLockCapabilities();
for (vector<string>::iterator i = fclc.begin(); i != fclc.end(); ++i)
cout << "'" << *i << "' ";
cout << endl;
break;
}
case PasswordInfo:
{
vector<PWInfo> pwi = m->getPasswords();
int count = 0;
for (vector<PWInfo>::iterator i = pwi.begin(); i != pwi.end(); ++i)
{
cout << "<PW" << count << "> '"
<< i->_facility << "' " << i->_maxPasswdLen << endl;
++count;
}
break;
}
case PINInfo:
{
cout << "<PIN0> " << m->getPINStatus() << endl;
break;
}
case CLIPInfo:
{
cout << "<CLIP0> " << (m->getNetworkCLIP() ? _("on") : _("off")) << endl;
break;
}
case CallForwardingInfo:
{
for (int r = 0; r < 4; ++r)
{
string text;
switch (r)
{
case 0: text = _("UnconditionalReason"); break;
case 1: text = _("MobileBusyReason"); break;
case 2: text = _("NoReplyReason"); break;
case 3: text = _("NotReachableReason"); break;
}
ForwardInfo voice, fax, data;
m->getCallForwardInfo((ForwardReason)r, voice, fax, data);
cout << "<FORW" << r << ".";
printForwardReason("0> " + text + _(" Voice"), voice);
cout << "<FORW" << r << ".";
printForwardReason("1> " + text + _(" Data"), data);
cout << "<FORW" << r << ".";
printForwardReason("2> " + text + _(" Fax"), fax);
}
break;
}
case BatteryInfo:
{
cout << "<BATT0> ";
int bcs = m->getBatteryChargeStatus();
switch (bcs)
{
case 0: cout << _("0 ME is powered by the battery") << endl; break;
case 1: cout << _("1 ME has a battery connected, but is not powered by it")
<< endl; break;
case 2: cout << _("2 ME does not have a battery connected") << endl; break;
case 3:
cout << _("3 Recognized power fault, calls inhibited") << endl;
break;
}
cout << "<BATT1> " << m->getBatteryCharge() << endl;
break;
}
case BitErrorInfo:
{
cout << "<BITERR0> " << m->getBitErrorRate() << endl;
break;
}
case SCAInfo:
{
cout << "<SCA0> " << m->getServiceCentreAddress() << endl;
break;
}
case CharSetInfo:
{
cout << "<CSET0> ";
vector<string> cs = m->getSupportedCharSets();
for (vector<string>::iterator i = cs.begin(); i != cs.end(); ++i)
cout << "'" << *i << "' ";
cout << endl;
cout << "<CSET1> '" << m->getCurrentCharSet() << "'" << endl;
break;
}
case SignalInfo:
{
cout << "<SIG0> " << m->getSignalStrength() << endl;
break;
}
default:
assert(0);
break;
}
}
// convert facility class string of the form "", "all", or any combination
// of "v" (voice), "d" (data), or "f" (fax) to numeric form
FacilityClass strToFacilityClass(string facilityClassS)
{
facilityClassS = lowercase(facilityClassS);
FacilityClass facilityClass = (FacilityClass)0;
if (facilityClassS == "all" || facilityClassS == "")
return (FacilityClass)ALL_FACILITIES;
// OR in facility class bits
for (unsigned int i = 0; i < facilityClassS.length(); ++i)
if (facilityClassS[i] == 'v')
facilityClass = (FacilityClass)(facilityClass | VoiceFacility);
else if (facilityClassS[i] == 'd')
facilityClass = (FacilityClass)(facilityClass | DataFacility);
else if (facilityClassS[i] == 'f')
facilityClass = (FacilityClass)(facilityClass | FaxFacility);
else
throw GsmException(
stringPrintf(_("unknown facility class parameter '%c'"),
facilityClassS[i]), ParameterError);
return facilityClass;
}
// check if argc - optind is in range min..max
// throw exception otherwise
void checkParamCount(int optind, int argc, int min, int max)
{
int paramCount = argc - optind;
if (paramCount < min)
throw GsmException(stringPrintf(_("not enough parameters, minimum number "
"of parameters is %d"), min),
ParameterError);
else if (paramCount > max)
throw GsmException(stringPrintf(_("too many parameters, maximum number "
"of parameters is %d"), max),
ParameterError);
}
// *** main program
int main(int argc, char *argv[])
{
try
{
// handle command line options
string device = "/dev/mobilephone";
string operation;
string baudrate;
string initString = DEFAULT_INIT_STRING;
bool swHandshake = false;
int opt;
int dummy;
while((opt = getopt_long(argc, argv, "I:o:d:b:hvX", longOpts, &dummy))
!= -1)
switch (opt)
{
case 'X':
swHandshake = true;
break;
case 'I':
initString = optarg;
break;
case 'd':
device = optarg;
break;
case 'o':
operation = optarg;
break;
case 'b':
baudrate = optarg;
break;
case 'v':
cerr << argv[0] << stringPrintf(_(": version %s [compiled %s]"),
VERSION, __DATE__) << endl;
exit(0);
break;
case 'h':
cerr << argv[0] << _(": [-b baudrate][-d device][-h]"
"[-I init string][-o operation]\n"
" [-v][-X]{parameters}") << endl
<< endl
<< _(" -b, --baudrate baudrate to use for device "
"(default: 38400)")
<< endl
<< _(" -d, --device sets the destination device to "
"connect to") << endl
<< _(" -h, --help prints this message") << endl
<< _(" -I, --init device AT init sequence") << endl
<< _(" -o, --operation operation to perform on the mobile \n"
" phone with the specified parameters")
<< endl
<< _(" -v, --version prints version and exits") << endl
<< _(" -X, --xonxoff switch on software handshake") << endl
<< endl
<< _(" parameters parameters to use for the operation\n"
" (if an operation is given) or\n"
" a specification which kind of\n"
" information to read from the mobile "
"phone")
<< endl << endl
<< _("Refer to gsmctl(1) for details on the available parameters"
" and operations.")
<< endl << endl;
exit(0);
break;
case '?':
throw GsmException(_("unknown option"), ParameterError);
break;
}
// open the port and ME/TA
m = new MeTa(new
#ifdef WIN32
Win32SerialPort
#else
UnixSerialPort
#endif
(device,
baudrate == "" ?
DEFAULT_BAUD_RATE :
baudRateStrToSpeed(baudrate),
initString, swHandshake));
if (operation == "")
{ // process info parameters
for (int i = optind; i < argc; ++i)
{
string param = lowercase(argv[i]);
if (param == "all")
for (int ip = MeInfo; ip <= SignalInfo; ++ip)
printInfo((InfoParameter)ip);
else if (param == "me")
printInfo(MeInfo);
else if (param == "fun")
printInfo(FunctionalityInfo);
else if (param == "op")
printInfo(OperatorInfo);
else if (param == "currop")
printInfo(CurrentOperatorInfo);
else if (param == "flstat")
printInfo(FacilityLockStateInfo);
else if (param == "flcap")
printInfo(FacilityLockCapabilityInfo);
else if (param == "pw")
printInfo(PasswordInfo);
else if (param == "pin")
printInfo(PINInfo);
else if (param == "clip")
printInfo(CLIPInfo);
else if (param == "forw")
printInfo(CallForwardingInfo);
else if (param == "batt")
printInfo(BatteryInfo);
else if (param == "biterr")
printInfo(BitErrorInfo);
else if (param == "sig")
printInfo(SignalInfo);
else if (param == "sca")
printInfo(SCAInfo);
else if (param == "cset")
printInfo(CharSetInfo);
else
throw GsmException(
stringPrintf(_("unknown information parameter '%s'"),
param.c_str()),
ParameterError);
}
}
else
{ // process operation
operation = lowercase(operation);
if (operation == "dial")
{
// dial: number
checkParamCount(optind, argc, 1, 1);
m->dial(argv[optind]);
// wait for keypress from stdin
char c;
read(1, &c, 1);
}
else if (operation == "on")
{
m->setFunctionalityLevel(1);
}
else if (operation == "off")
{
m->setFunctionalityLevel(0);
}
else if (operation == "pin")
{
// pin: PIN
checkParamCount(optind, argc, 1, 1);
m->setPIN(argv[optind]);
}
else if (operation == "setop")
{
// setop: opmode numeric FIXME allow long and numeric too
checkParamCount(optind, argc, 2, 2);
string opmodeS = lowercase(argv[optind]);
OPModes opmode;
if (opmodeS == "automatic")
opmode = AutomaticOPMode;
else if (opmodeS == "manual")
opmode = ManualOPMode;
else if (opmodeS == "deregister")
opmode = DeregisterOPMode;
else if (opmodeS == "manualautomatic")
opmode = ManualAutomaticOPMode;
else
throw GsmException(stringPrintf(_("unknown opmode parameter '%s'"),
opmodeS.c_str()), ParameterError);
m->setCurrentOPInfo(opmode, "" , "", checkNumber(argv[optind + 1]));
}
else if (operation == "lock")
{
// lock: facility [facilityclass] [passwd]
checkParamCount(optind, argc, 1, 3);
string passwd = (argc - optind == 3) ?
(string)argv[optind + 2] : (string)"";
m->lockFacility(argv[optind],
(argc - optind >= 2) ?
strToFacilityClass(argv[optind + 1]) :
(FacilityClass)ALL_FACILITIES,
passwd);
}
else if (operation == "unlock")
{
// unlock: facility [facilityclass] [passwd]
checkParamCount(optind, argc, 1, 3);
string passwd = argc - optind == 3 ? argv[optind + 2] : "";
m->unlockFacility(argv[optind],
(argc - optind >= 2) ?
strToFacilityClass(argv[optind + 1]) :
(FacilityClass)ALL_FACILITIES,
passwd);
}
else if (operation == "setpw")
{
// set password: facility oldpasswd newpasswd
checkParamCount(optind, argc, 1, 3);
string oldPasswd = argc - optind >= 2 ? argv[optind + 1] : "";
string newPasswd = argc - optind == 3 ? argv[optind + 2] : "";
m->setPassword(argv[optind], oldPasswd, newPasswd);
}
else if (operation == "forw")
{
// call forwarding: mode reason number [facilityclass] [forwardtime]
checkParamCount(optind, argc, 2, 5);
// get optional parameters facility class and forwardtime
int forwardTime = argc - optind == 5 ? checkNumber(argv[optind + 4]) :
NOT_SET;
FacilityClass facilityClass =
argc - optind >= 4 ? strToFacilityClass(argv[optind + 3]) :
(FacilityClass)ALL_FACILITIES;
// get forward reason
string reasonS = lowercase(argv[optind + 1]);
ForwardReason reason;
if (reasonS == "unconditional")
reason = UnconditionalReason;
else if (reasonS == "mobilebusy")
reason = MobileBusyReason;
else if (reasonS == "noreply")
reason = NoReplyReason;
else if (reasonS == "notreachable")
reason = NotReachableReason;
else if (reasonS == "all")
reason = AllReasons;
else if (reasonS == "allconditional")
reason = AllConditionalReasons;
else
throw GsmException(
stringPrintf(_("unknown forward reason parameter '%s'"),
reasonS.c_str()), ParameterError);
// get mode
string modeS = lowercase(argv[optind]);
ForwardMode mode;
if (modeS == "disable")
mode = DisableMode;
else if (modeS == "enable")
mode = EnableMode;
else if (modeS == "register")
mode = RegistrationMode;
else if (modeS == "erase")
mode = ErasureMode;
else
throw GsmException(
stringPrintf(_("unknown forward mode parameter '%s'"),
modeS.c_str()), ParameterError);
m->setCallForwarding(reason, mode,
(argc - optind >= 3) ? argv[optind + 2] : "",
"", // subaddr
facilityClass, forwardTime);
}
else if (operation == "setsca")
{
// set sca: number
checkParamCount(optind, argc, 1, 1);
m->setServiceCentreAddress(argv[optind]);
}
else if (operation == "cset")
{
// set charset: string
checkParamCount(optind, argc, 1, 1);
m->setCharSet(argv[optind]);
}
else
throw GsmException(stringPrintf(_("unknown operation '%s'"),
operation.c_str()), ParameterError);
}
}
catch (GsmException &ge)
{
cerr << argv[0] << _("[ERROR]: ") << ge.what() << endl;
return 1;
}
return 0;
}

View File

@ -0,0 +1,507 @@
// *************************************************************************
// * GSM TA/ME library
// *
// * File: gsmpb.cc
// *
// * Purpose: phonebook management program
// *
// * Author: Peter Hofmann (software@pxh.de)
// *
// * Created: 24.6.1999
// *************************************************************************
#ifdef HAVE_CONFIG_H
#include <gsm_config.h>
#endif
#include <gsmlib/gsm_nls.h>
#include <string>
#ifdef WIN32
#include <gsmlib/gsm_win32_serial.h>
#else
#include <gsmlib/gsm_unix_serial.h>
#include <unistd.h>
#endif
#if defined(HAVE_GETOPT_LONG) || defined(WIN32)
#include <getopt.h>
#endif
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <gsmlib/gsm_me_ta.h>
#include <gsmlib/gsm_util.h>
#include <gsmlib/gsm_sorted_phonebook.h>
#include <iostream>
using namespace std;
using namespace gsmlib;
#ifdef HAVE_GETOPT_LONG
static struct option longOpts[] =
{
{"xonxoff", no_argument, (int*)NULL, 'X'},
{"phonebook", required_argument, (int*)NULL, 'p'},
{"init", required_argument, (int*)NULL, 'I'},
{"destination", required_argument, (int*)NULL, 'd'},
{"source", required_argument, (int*)NULL, 's'},
{"destination-backend", required_argument, (int*)NULL, 'D'},
{"source-backend", required_argument, (int*)NULL, 'S'},
{"baudrate", required_argument, (int*)NULL, 'b'},
{"charset", required_argument, (int*)NULL, 't'},
{"copy", no_argument, (int*)NULL, 'c'},
{"synchronize", no_argument, (int*)NULL, 'y'},
{"help", no_argument, (int*)NULL, 'h'},
{"version", no_argument, (int*)NULL, 'v'},
{"verbose", no_argument, (int*)NULL, 'V'},
{"indexed", no_argument, (int*)NULL, 'i'},
{(char*)NULL, 0, (int*)NULL, 0}
};
#else
#define getopt_long(argc, argv, options, longopts, indexptr) \
getopt(argc, argv, options)
#endif
// insert those entries from sourcePhonebook into destPhonebook
// that are not already present in destPhonebook
void insertNotPresent(SortedPhonebookRef sourcePhonebook,
SortedPhonebookRef destPhonebook,
bool indexed, bool verbose)
{
for (SortedPhonebookBase::iterator i = sourcePhonebook->begin();
i != sourcePhonebook->end(); ++i)
{
pair<SortedPhonebookBase::iterator, SortedPhonebookBase::iterator> range;
if (indexed)
{
int index = i->index();
range = destPhonebook->equal_range(index);
}
else
{
string text = i->text();
range = destPhonebook->equal_range(text);
}
// do nothing if the entry is already present in the destination
bool alreadyPresent = false;
for (SortedPhonebookBase::iterator j = range.first;
j != range.second; ++j)
{
i->setUseIndex(indexed);
if (i->telephone() == j->telephone())
{
alreadyPresent = true;
break;
}
}
// ... else insert it
if (! alreadyPresent)
{
if (verbose)
{
cout << stringPrintf(_("inserting '%s' tel# %s"),
i->text().c_str(), i->telephone().c_str());
if (indexed)
cout << stringPrintf(_(" (index #%d)"), i->index());
cout << endl;
}
i->setUseIndex(indexed);
destPhonebook->insert(*i); // insert
}
}
}
// update those entries in destPhonebook, that
// - have the same name as one entry in destPhonebook
// - but have a different telephone number
// this is only done if the name in question is unique in the destPhonebook
// the case of several entries having the same in the sourcePhonebook
// is handled - only the first is considered for updating
void updateEntries(SortedPhonebookRef sourcePhonebook,
SortedPhonebookRef destPhonebook,
bool verbose)
{
bool firstLoop = true;
string lastText;
for (SortedPhonebookBase::iterator i = sourcePhonebook->begin();
i != sourcePhonebook->end(); ++i)
{
string text = i->text();
if (! firstLoop && text != lastText)
{
pair<SortedPhonebookBase::iterator,
SortedPhonebookBase::iterator> range =
destPhonebook->equal_range(text);
SortedPhonebookBase::iterator first = range.first;
if (first != destPhonebook->end() && range.second == ++first)
{ // just one text in the destPhonebook
if (! (*range.first == *i)) // overwrite if different in destination
{
if (verbose)
cout << stringPrintf(_("updating '%s' tel# %s to new tel# %s"),
range.first->text().c_str(),
range.first->telephone().c_str(),
i->telephone().c_str())
<< endl;
*range.first = *i;
}
}
lastText = text;
}
firstLoop = false;
}
}
// the same but for indexed phonebooks
void updateEntriesIndexed(SortedPhonebookRef sourcePhonebook,
SortedPhonebookRef destPhonebook,
bool verbose)
{
for (SortedPhonebookBase::iterator i = sourcePhonebook->begin();
i != sourcePhonebook->end(); ++i)
{
int index = i->index();
SortedPhonebookBase::iterator j = destPhonebook->find(index);
if (j != destPhonebook->end())
{ // index present in the destPhonebook
if (! (*j == *i)) // overwrite if different in destination
{
if (verbose)
cout << stringPrintf(_("updating '%s' tel# %s to new tel# %s"
"(index %d)"),
j->text().c_str(),
j->telephone().c_str(),
i->telephone().c_str(), i->index())
<< endl;
*j = *i;
}
}
}
}
// delete those entries from destPhonebook, that are not present
// in sourcePhonebook
void deleteNotPresent(SortedPhonebookRef sourcePhonebook,
SortedPhonebookRef destPhonebook,
bool indexed, bool verbose)
{
for (SortedPhonebookBase::iterator i = destPhonebook->begin();
i != destPhonebook->end(); ++i)
{
pair<SortedPhonebookBase::iterator, SortedPhonebookBase::iterator> range;
if (indexed)
{
int index = i->index();
range = sourcePhonebook->equal_range(index);
}
else
{
string text = i->text();
range = sourcePhonebook->equal_range(text);
}
bool found = false;
for (SortedPhonebookBase::iterator j = range.first;
j != range.second; ++j)
{
i->setUseIndex(indexed);
if (j->telephone() == i->telephone())
{
found = true;
break;
}
}
if (! found)
{
if (verbose)
{
cout << stringPrintf(_("deleting '%s' tel# %s"),
i->text().c_str(), i->telephone().c_str());
if (indexed)
cout << stringPrintf(_(" (index #%d)"), i->index());
cout << endl;
}
destPhonebook->erase(i);
#ifdef BUGGY_MAP_ERASE
deleteNotPresent(sourcePhonebook, destPhonebook, indexed, verbose);
return;
#endif
}
}
}
// *** main program
int main(int argc, char *argv[])
{
try
{
// handle command line options
string destination;
string source;
string destinationBackend;
string sourceBackend;
string baudrate;
bool doSynchronize = true;
string phonebook;
SortedPhonebookRef sourcePhonebook, destPhonebook;
bool verbose = false;
bool indexed = false;
string initString = DEFAULT_INIT_STRING;
bool swHandshake = false;
string charSet;
Ref<MeTa> sourceMeTa, destMeTa;
int opt;
int dummy;
while((opt = getopt_long(argc, argv, "I:p:s:d:b:cyhvViD:S:Xt:", longOpts,
&dummy))
!= -1)
switch (opt)
{
case 'X':
swHandshake = true;
break;
case 'I':
initString = optarg;
break;
case 'V':
verbose = true;
break;
case 'p':
phonebook = optarg;
break;
case 'd':
destination = optarg;
break;
case 's':
source = optarg;
break;
case 'D':
destinationBackend = optarg;
break;
case 'S':
sourceBackend = optarg;
break;
case 'b':
baudrate = optarg;
break;
case 't':
charSet = optarg;
break;
case 'c':
doSynchronize = false;
break;
case 'i':
indexed = true;
break;
case 'y':
doSynchronize = true;
break;
case 'v':
cerr << argv[0] << stringPrintf(_(": version %s [compiled %s]"),
VERSION, __DATE__) << endl;
exit(0);
break;
case 'h':
cerr << argv[0] << _(": [-b baudrate][-c][-d device or file][-h]"
"[-I init string]\n"
" [-p phonebook name][-s device or file]"
"[-t charset][-v]"
"[-V][-y][-X]") << endl
<< endl
<< _(" -b, --baudrate baudrate to use for device "
"(default: 38400)")
<< endl
<< _(" -c, --copy copy source entries to destination")
<< endl
<< _(" -d, --destination sets the destination device to "
"connect \n"
" to, or the file to write") << endl
<< _(" -D, --destination-backend sets the destination backend")
<< endl
<< _(" -h, --help prints this message") << endl
<< _(" -i, --index takes index positions into account")
<< endl
<< _(" -I, --init device AT init sequence") << endl
<< _(" -p, --phonebook name of phonebook to use") << endl
<< _(" -s, --source sets the source device to connect to,\n"
" or the file to read") << endl
<< _(" -t, --charset sets the character set to use for\n"
" phonebook entries") << endl
<< _(" -S, --source-backend sets the source backend")
<< endl
<< _(" -v, --version prints version and exits") << endl
<< _(" -V, --verbose print detailed progress messages")
<< endl
<< _(" -X, --xonxoff switch on software handshake") << endl
<< _(" -y, --synchronize synchronize destination with source\n"
" entries (destination is overwritten)\n"
" (see gsmpb(1) for details)")
<< endl << endl;
exit(0);
break;
case '?':
throw GsmException(_("unknown option"), ParameterError);
break;
}
// check if all parameters all present
if (destination == "" || source == "")
throw GsmException(_("both source and destination must be given"),
ParameterError);
// start accessing source mobile phone or file
if (sourceBackend != "")
sourcePhonebook =
CustomPhonebookRegistry::createPhonebook(sourceBackend, source);
else if (source == "-")
sourcePhonebook = new SortedPhonebook(true, indexed);
else if (isFile(source))
sourcePhonebook = new SortedPhonebook(source, indexed);
else
{
if (phonebook == "")
throw GsmException(_("phonebook name must be given"), ParameterError);
sourceMeTa = new MeTa(new
#ifdef WIN32
Win32SerialPort
#else
UnixSerialPort
#endif
(source,
baudrate == "" ? DEFAULT_BAUD_RATE :
baudRateStrToSpeed(baudrate), initString,
swHandshake));
if (charSet != "")
sourceMeTa->setCharSet(charSet);
sourcePhonebook =
new SortedPhonebook(sourceMeTa->getPhonebook(phonebook));
}
// make sure destination.c_str file exists
if (destination != "")
{
try
{
ofstream f(destination.c_str(), ios::out | ios::app);
}
catch (exception)
{
}
}
// start accessing destination mobile phone or file
if (destinationBackend != "")
destPhonebook =
CustomPhonebookRegistry::createPhonebook(destinationBackend,
destination);
else if (destination == "-")
destPhonebook = new SortedPhonebook(false, indexed);
else if (isFile(destination))
destPhonebook = new SortedPhonebook(destination, indexed);
else
{
if (phonebook == "")
throw GsmException(_("phonebook name must be given"), ParameterError);
destMeTa = new MeTa(new
#ifdef WIN32
Win32SerialPort
#else
UnixSerialPort
#endif
(destination,
baudrate == "" ? DEFAULT_BAUD_RATE :
baudRateStrToSpeed(baudrate), initString,
swHandshake));
if (charSet != "")
destMeTa->setCharSet(charSet);
PhonebookRef destPb = destMeTa->getPhonebook(phonebook);
// check maximum lengths of source text and phonenumber when writing to
// mobile phone
unsigned int maxTextLen = destPb->getMaxTextLen();
unsigned int maxTelLen = destPb->getMaxTelephoneLen();
for (SortedPhonebookBase::iterator i = sourcePhonebook->begin();
i != sourcePhonebook->end(); ++i)
if (i->text().length() > maxTextLen)
throw GsmException(
stringPrintf(_("text '%s' is too large to fit into destination "
"(maximum size %d characters)"),
i->text().c_str(), maxTextLen),
ParameterError);
else if (i->telephone().length() > maxTelLen)
throw GsmException(
stringPrintf(_("phone number '%s' is too large to fit into "
"destination (maximum size %d characters)"),
i->telephone().c_str(), maxTelLen),
ParameterError);
// read phonebook
destPhonebook = new SortedPhonebook(destPb);
}
// now do the actual work
if (doSynchronize)
{ // synchronizing
if (indexed)
{
sourcePhonebook->setSortOrder(ByIndex);
destPhonebook->setSortOrder(ByIndex);
// for an explanation see below
updateEntriesIndexed(sourcePhonebook, destPhonebook, verbose);
deleteNotPresent(sourcePhonebook, destPhonebook, true, verbose);
insertNotPresent(sourcePhonebook, destPhonebook, true, verbose);
}
else
{
sourcePhonebook->setSortOrder(ByText);
destPhonebook->setSortOrder(ByText);
// the following is done to avoid superfluous writes to the TA
// (that takes time) and keep updated (ie. telephone number changed)
// entries at the same place
// 1. update entries in place where just the number changed
updateEntries(sourcePhonebook, destPhonebook, verbose);
// 2. delete those that are not present anymore
deleteNotPresent(sourcePhonebook, destPhonebook, false, verbose);
// 3. insert the new ones
insertNotPresent(sourcePhonebook, destPhonebook, false, verbose);
}
}
else
{ // copying
destPhonebook->clear();
for (SortedPhonebookBase::iterator i = sourcePhonebook->begin();
i != sourcePhonebook->end(); ++i)
{
if (verbose)
{
cout << stringPrintf(_("inserting '%s' tel# %s"),
i->text().c_str(), i->telephone().c_str());
if (indexed)
cout << stringPrintf(_(" (index #%d)"), i->index());
cout << endl;
}
destPhonebook->insert(*i);
}
}
}
catch (GsmException &ge)
{
cerr << argv[0] << _("[ERROR]: ") << ge.what() << endl;
return 1;
}
return 0;
}

View File

@ -0,0 +1,257 @@
// *************************************************************************
// * GSM TA/ME library
// *
// * File: gsmsendsms.cc
// *
// * Purpose: GSM sms send program
// *
// * Author: Peter Hofmann (software@pxh.de)
// *
// * Created: 16.7.1999
// *************************************************************************
#ifdef HAVE_CONFIG_H
#include <gsm_config.h>
#endif
#include <gsmlib/gsm_nls.h>
#include <string>
#ifdef WIN32
#include <gsmlib/gsm_win32_serial.h>
#else
#include <gsmlib/gsm_unix_serial.h>
#include <unistd.h>
#endif
#if defined(HAVE_GETOPT_LONG) || defined(WIN32)
#include <getopt.h>
#endif
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <gsmlib/gsm_me_ta.h>
#include <gsmlib/gsm_util.h>
#include <iostream>
using namespace std;
using namespace gsmlib;
// options
#ifdef HAVE_GETOPT_LONG
static struct option longOpts[] =
{
{"requeststat", no_argument, (int*)NULL, 'r'},
{"xonxoff", no_argument, (int*)NULL, 'X'},
{"sca", required_argument, (int*)NULL, 'C'},
{"device", required_argument, (int*)NULL, 'd'},
{"init", required_argument, (int*)NULL, 'I'},
{"concatenate", required_argument, (int*)NULL, 'c'},
{"baudrate", required_argument, (int*)NULL, 'b'},
{"test", no_argument, (int*)NULL, 't'},
{"help", no_argument, (int*)NULL, 'h'},
{"version", no_argument, (int*)NULL, 'v'},
{(char*)NULL, 0, (int*)NULL, 0}
};
#else
#define getopt_long(argc, argv, options, longopts, indexptr) \
getopt(argc, argv, options)
#endif
// convert /r and /n to CR and LF
static string unescapeString(char *line)
{
string result;
bool escaped = false;
int index = 0;
while (line[index] != 0 &&
line[index] != CR && line[index] != LF)
{
if (escaped)
{
escaped = false;
if (line[index] == 'r')
result += CR;
else if (line[index] == 'n')
result += LF;
else if (line[index] == '\\')
result += '\\';
else
result += line[index];
}
else
if (line[index] == '\\')
escaped = true;
else
result += line[index];
++index;
}
return result;
}
// *** main program
int main(int argc, char *argv[])
{
try
{
// handle command line options
string device = "/dev/mobilephone";
bool test = false;
string baudrate;
Ref<GsmAt> at;
string initString = DEFAULT_INIT_STRING;
bool swHandshake = false;
bool requestStatusReport = false;
// service centre address (set on command line)
string serviceCentreAddress;
MeTa *m = NULL;
string concatenatedMessageIdStr;
int concatenatedMessageId = -1;
int opt;
int dummy;
while((opt = getopt_long(argc, argv, "c:C:I:d:b:thvXr", longOpts, &dummy))
!= -1)
switch (opt)
{
case 'c':
concatenatedMessageIdStr = optarg;
break;
case 'C':
serviceCentreAddress = optarg;
break;
case 'X':
swHandshake = true;
break;
case 'I':
initString = optarg;
break;
case 'd':
device = optarg;
break;
case 'b':
baudrate = optarg;
break;
case 't':
test = true;
break;
case 'r':
requestStatusReport = true;
break;
case 'v':
cerr << argv[0] << stringPrintf(_(": version %s [compiled %s]"),
VERSION, __DATE__) << endl;
exit(0);
break;
case 'h':
cerr << argv[0] << _(": [-b baudrate][-c concatenatedID]"
"[-C sca][-d device][-h][-I init string]\n"
" [-t][-v][-X] phonenumber [text]") << endl
<< endl
<< _(" -b, --baudrate baudrate to use for device "
"(default: 38400)")
<< endl
<< _(" -c, --concatenate ID for concatenated SMS messages")
<< endl
<< _(" -C, --sca SMS service centre address") << endl
<< _(" -d, --device sets the destination device to connect "
"to") << endl
<< _(" -h, --help prints this message") << endl
<< _(" -I, --init device AT init sequence") << endl
<< _(" -r, --requeststat request SMS status report") << endl
<< _(" -t, --test convert text to GSM alphabet and "
"vice\n"
" versa, no SMS message is sent") << endl
<< _(" -v, --version prints version and exits")
<< endl
<< _(" -X, --xonxoff switch on software handshake") << endl
<< endl
<< _(" phonenumber recipient's phone number") << endl
<< _(" text optional text of the SMS message\n"
" if omitted: read from stdin")
<< endl << endl;
exit(0);
break;
case '?':
throw GsmException(_("unknown option"), ParameterError);
break;
}
if (! test)
{
// open the port and ME/TA
Ref<Port> port = new
#ifdef WIN32
Win32SerialPort
#else
UnixSerialPort
#endif
(device,
baudrate == "" ? DEFAULT_BAUD_RATE :
baudRateStrToSpeed(baudrate),
initString, swHandshake);
// switch message service level to 1
// this enables acknowledgement PDUs
m = new MeTa(port);
m->setMessageService(1);
at = new GsmAt(*m);
}
// check parameters
if (optind == argc)
throw GsmException(_("phone number and text missing"), ParameterError);
if (optind + 2 < argc)
throw GsmException(_("more than two parameters given"), ParameterError);
if (concatenatedMessageIdStr != "")
concatenatedMessageId = checkNumber(concatenatedMessageIdStr);
// get phone number
string phoneNumber = argv[optind];
// get text
string text;
if (optind + 1 == argc)
{ // read from stdin
char s[1000];
cin.get(s, 1000);
text = unescapeString(s);
if (text.length() > 160)
throw GsmException(_("text is larger than 160 characters"),
ParameterError);
}
else
text = argv[optind + 1];
if (test)
cout << gsmToLatin1(latin1ToGsm(text)) << endl;
else
{
// send SMS
Ref<SMSSubmitMessage> submitSMS = new SMSSubmitMessage();
// set service centre address in new submit PDU if requested by user
if (serviceCentreAddress != "")
{
Address sca(serviceCentreAddress);
submitSMS->setServiceCentreAddress(sca);
}
submitSMS->setStatusReportRequest(requestStatusReport);
Address destAddr(phoneNumber);
submitSMS->setDestinationAddress(destAddr);
if (concatenatedMessageId == -1)
m->sendSMSs(submitSMS, text, true);
else
m->sendSMSs(submitSMS, text, false, concatenatedMessageId);
}
}
catch (GsmException &ge)
{
cerr << argv[0] << _("[ERROR]: ") << ge.what() << endl;
return 1;
}
return 0;
}

View File

@ -0,0 +1,719 @@
// *************************************************************************
// * GSM TA/ME library
// *
// * File: gsmsmsd.cc
// *
// * Purpose: SMS receiver daemon
// *
// * Author: Peter Hofmann (software@pxh.de)
// *
// * Created: 5.6.1999
// *************************************************************************
#ifdef HAVE_CONFIG_H
#include <gsm_config.h>
#endif
#include <gsmlib/gsm_nls.h>
#include <string>
#ifdef WIN32
#include <io.h>
#include <gsmlib/gsm_util.h>
#include <gsmlib/gsm_win32_serial.h>
#define popen _popen
#define pclose _pclose
#else
#include <gsmlib/gsm_unix_serial.h>
#include <unistd.h>
#include <dirent.h>
#include <syslog.h>
#endif
#if defined(HAVE_GETOPT_LONG) || defined(WIN32)
#include <getopt.h>
#endif
#include <stdio.h>
#include <errno.h>
#include <stdlib.h>
#include <signal.h>
#include <fstream>
#include <iostream>
#include <gsmlib/gsm_me_ta.h>
#include <gsmlib/gsm_event.h>
using namespace std;
using namespace gsmlib;
#ifdef HAVE_GETOPT_LONG
static struct option longOpts[] =
{
{"requeststat", no_argument, (int*)NULL, 'r'},
{"direct", no_argument, (int*)NULL, 'D'},
{"xonxoff", no_argument, (int*)NULL, 'X'},
{"init", required_argument, (int*)NULL, 'I'},
{"store", required_argument, (int*)NULL, 't'},
{"device", required_argument, (int*)NULL, 'd'},
{"spool", required_argument, (int*)NULL, 's'},
{"sent", required_argument, (int*)NULL, 'S'},
{"failed", required_argument, (int*)NULL, 'F'},
{"priorities", required_argument, (int*)NULL, 'P'},
#ifndef WIN32
{"syslog", no_argument, (int*)NULL, 'L'},
#endif
{"sca", required_argument, (int*)NULL, 'C'},
{"flush", no_argument, (int*)NULL, 'f'},
{"concatenate", required_argument, (int*)NULL, 'c'},
{"action", required_argument, (int*)NULL, 'a'},
{"baudrate", required_argument, (int*)NULL, 'b'},
{"help", no_argument, (int*)NULL, 'h'},
{"version", no_argument, (int*)NULL, 'v'},
{(char*)NULL, 0, (int*)NULL, 0}
};
#else
#define getopt_long(argc, argv, options, longopts, indexptr) \
getopt(argc, argv, options)
#endif
// my ME
static MeTa *me = NULL;
string receiveStoreName; // store name for received SMSs
// service centre address (set on command line)
static string serviceCentreAddress;
// ID if concatenated messages should be sent
static int concatenatedMessageId = -1;
// signal handler for terminate signal
bool terminateSent = false;
void terminateHandler(int signum)
{
terminateSent = true;
}
// local class to handle SMS events
struct IncomingMessage
{
// used if new message is put into store
int _index; // -1 means message want send directly
string _storeName;
// used if SMS message was sent directly to TA
SMSMessageRef _newSMSMessage;
// used if CB message was sent directly to TA
CBMessageRef _newCBMessage;
// used in both cases
GsmEvent::SMSMessageType _messageType;
IncomingMessage() : _index(-1) {}
};
vector<IncomingMessage> newMessages;
class EventHandler : public GsmEvent
{
public:
// inherited from GsmEvent
void SMSReception(SMSMessageRef newMessage,
SMSMessageType messageType);
void CBReception(CBMessageRef newMessage);
void SMSReceptionIndication(string storeName, unsigned int index,
SMSMessageType messageType);
virtual ~EventHandler() {}
};
void EventHandler::SMSReception(SMSMessageRef newMessage,
SMSMessageType messageType)
{
IncomingMessage m;
m._messageType = messageType;
m._newSMSMessage = newMessage;
newMessages.push_back(m);
}
void EventHandler::CBReception(CBMessageRef newMessage)
{
IncomingMessage m;
m._messageType = GsmEvent::CellBroadcastSMS;
m._newCBMessage = newMessage;
newMessages.push_back(m);
}
void EventHandler::SMSReceptionIndication(string storeName, unsigned int index,
SMSMessageType messageType)
{
IncomingMessage m;
m._index = index;
if (receiveStoreName != "" && ( storeName == "MT" || storeName == "mt"))
m._storeName = receiveStoreName;
else
m._storeName = storeName;
m._messageType = messageType;
newMessages.push_back(m);
}
// execute action on string
void doAction(string action, string result)
{
if (action != "")
{
FILE *fd = popen(action.c_str(), "w");
if (fd == NULL)
throw GsmException(stringPrintf(_("could not execute '%s'"),
action.c_str()), OSError);
fputs(result.c_str(), fd);
if (ferror(fd))
throw GsmException(stringPrintf(_("error writing to '%s'"),
action.c_str()), OSError);
pclose(fd);
}
else
// default if no action: output on stdout
cout << result << endl;
}
// send all SMS messages in spool dir
bool requestStatusReport = false;
void sendSMS(string spoolDirBase, string sentDirBase, string failedDirBase,
unsigned int priority, bool enableSyslog, Ref<GsmAt> at)
{
string spoolDir = spoolDirBase;
string sentDir = sentDirBase;
string failedDir = failedDirBase;
if ( priority >= 1 )
{
spoolDir = spoolDirBase + stringPrintf(_("%d"),priority);
sentDir = sentDirBase + stringPrintf(_("%d"),priority);
failedDir = failedDirBase + stringPrintf(_("%d"),priority);
}
if ( priority > 1 )
sendSMS(spoolDirBase, sentDirBase, failedDirBase, priority-1, enableSyslog, at);
if (spoolDirBase != "")
{
// look into spoolDir for any outgoing SMS that should be sent
#ifdef WIN32
struct _finddata_t fileInfo;
long fileHandle;
string pattern = spoolDir + "\\*";
fileHandle = _findfirst(pattern.c_str(), &fileInfo);
bool moreFiles = fileHandle != -1L;
#else
DIR *dir = opendir(spoolDir.c_str());
if (dir == (DIR*)NULL)
throw GsmException(
stringPrintf(_("error when calling opendir('%s')"
"(errno: %d/%s)"),
spoolDir.c_str(), errno, strerror(errno)),
OSError);
#endif
#ifdef WIN32
while (moreFiles)
{
if (strcmp(fileInfo.name, ".") != 0 &&
strcmp(fileInfo.name, "..") != 0)
#else
struct dirent *entry;
while ((entry = readdir(dir)) != (struct dirent*)NULL)
if (strcmp(entry->d_name, ".") != 0 &&
strcmp(entry->d_name, "..") != 0)
#endif
{
if ( priority > 1 )
sendSMS(spoolDirBase, sentDirBase, failedDirBase, priority-1, enableSyslog, at);
// read in file
// the first line is interpreted as the phone number
// the rest is the message
#ifdef WIN32
string filename = spoolDir + "\\" + fileInfo.name;
#else
string filename = spoolDir + "/" + entry->d_name;
#endif
ifstream ifs(filename.c_str());
if (! ifs)
#ifndef WIN32
if (enableSyslog)
{
syslog(LOG_WARNING, "Could not open SMS spool file %s",
filename.c_str());
if (failedDirBase != "") {
string failedfilename = failedDir + "/" + entry->d_name;
rename(filename.c_str(),failedfilename.c_str());
}
continue;
}
else
#endif
throw GsmException(
stringPrintf(_("count not open SMS spool file %s"),
filename.c_str()), ParameterError);
char phoneBuf[1001];
ifs.getline(phoneBuf, 1000);
for(int i=0;i<1000;i++)
if(phoneBuf[i]=='\t' || phoneBuf[i]==0)
{ // ignore everything after a <TAB> in the phone number
phoneBuf[i]=0;
break;
}
string text;
while (! ifs.eof())
{
char c;
ifs.get(c);
text += c;
}
ifs.close();
// remove trailing newline/linefeed
while (text[text.length() - 1] == '\n' ||
text[text.length() - 1] == '\r')
text = text.substr(0, text.length() - 1);
// send the message
string phoneNumber(phoneBuf);
Ref<SMSSubmitMessage> submitSMS = new SMSSubmitMessage();
// set service centre address in new submit PDU if requested by user
if (serviceCentreAddress != "")
{
Address sca(serviceCentreAddress);
submitSMS->setServiceCentreAddress(sca);
}
submitSMS->setStatusReportRequest(requestStatusReport);
Address destAddr(phoneNumber);
submitSMS->setDestinationAddress(destAddr);
try
{
if (concatenatedMessageId == -1)
me->sendSMSs(submitSMS, text, true);
else
{
// maximum for concatenatedMessageId is 255
if (concatenatedMessageId > 256)
concatenatedMessageId = 0;
me->sendSMSs(submitSMS, text, false, concatenatedMessageId++);
}
#ifndef WIN32
if (enableSyslog)
syslog(LOG_NOTICE, "Sent SMS to %s from file %s", phoneBuf, filename.c_str());
#endif
if (sentDirBase != "") {
#ifdef WIN32
string sentfilename = sentDir + "\\" + fileInfo.name;
#else
string sentfilename = sentDir + "/" + entry->d_name;
#endif
rename(filename.c_str(),sentfilename.c_str());
} else {
unlink(filename.c_str());
}
}
catch (GsmException &me)
{
#ifndef WIN32
if (enableSyslog)
syslog(LOG_WARNING, "Failed sending SMS to %s from file %s: %s", phoneBuf,
filename.c_str(), me.what());
else
#endif
cerr << "Failed sending SMS to " << phoneBuf << " from "
<< filename << ": " << me.what() << endl;
if (failedDirBase != "") {
#ifdef WIN32
string failedfilename = failedDir + "\\" + fileInfo.name;
#else
string failedfilename = failedDir + "/" + entry->d_name;
#endif
rename(filename.c_str(),failedfilename.c_str());
}
}
#ifdef WIN32
}
moreFiles = _findnext(fileHandle, &fileInfo) == 0;
#endif
}
#ifdef WIN32
_findclose(fileHandle);
#else
closedir(dir);
#endif
}
}
#ifndef WIN32
void syslogExit(int exitcode, int *dummy)
{
syslog(LOG_NOTICE, "exited (exit %d)",exitcode);
}
#endif
// *** main program
int main(int argc, char *argv[])
{
bool enableSyslog = false;
try
{
string device = "/dev/mobilephone";
string action;
string baudrate;
bool enableSMS = true;
bool enableCB = true;
bool enableStat = true;
bool flushSMS = false;
bool onlyReceptionIndication = true;
string spoolDir;
string sentDir = "";
string failedDir = "";
unsigned int priorities = 0;
string initString = DEFAULT_INIT_STRING;
bool swHandshake = false;
string concatenatedMessageIdStr;
int opt;
int dummy;
while((opt = getopt_long(argc, argv, "c:C:I:t:fd:a:b:hvs:S:F:P:LXDr",
longOpts, &dummy)) != -1)
switch (opt)
{
case 'c':
concatenatedMessageIdStr = optarg;
break;
case 'r':
requestStatusReport = true;
break;
case 'D':
onlyReceptionIndication = false;
break;
case 'X':
swHandshake = true;
break;
case 'I':
initString = optarg;
break;
case 't':
receiveStoreName = optarg;
break;
case 'd':
device = optarg;
break;
case 'C':
serviceCentreAddress = optarg;
break;
case 's':
spoolDir = optarg;
break;
case 'S':
sentDir = optarg;
break;
case 'F':
failedDir = optarg;
break;
case 'P':
priorities = abs(atoi(optarg));
break;
case 'f':
flushSMS = true;
break;
case 'a':
action = optarg;
break;
case 'b':
baudrate = optarg;
break;
case 'v':
cerr << argv[0] << stringPrintf(_(": version %s [compiled %s]"),
VERSION, __DATE__) << endl;
exit(0);
break;
case 'h':
cerr << argv[0] << _(": [-a action][-b baudrate][-C sca][-d device]"
"[-f][-h][-I init string]\n"
" [-s spool dir][-t][-v]{sms_type}")
<< endl << endl
<< _(" -a, --action the action to execute when an SMS "
"arrives\n"
" (SMS is send to stdin of action)")
<< endl
<< _(" -b, --baudrate baudrate to use for device "
"(default: 38400)")
<< endl
<< _(" -c, --concatenate start ID for concatenated SMS messages")
<< endl
<< _(" -C, --sca SMS service centre address") << endl
<< _(" -d, --device sets the device to connect to") << endl
<< _(" -D, --direct enable direct routing of SMSs") << endl
<< _(" -f, --flush flush SMS from store") << endl
<< _(" -F, --failed directory to move failed SMS to,") << endl
<< _(" if unset, the SMS will be deleted") << endl
<< _(" -h, --help prints this message") << endl
<< _(" -I, --init device AT init sequence") << endl
#ifndef WIN32
<< _(" -L, --syslog log errors and information to syslog")
<< endl
#endif
<< _(" -P, --priorities number of priority levels to use,") << endl
<< _(" (default: none)") << endl
<< _(" -r, --requeststat request SMS status report") << endl
<< _(" -s, --spool spool directory for outgoing SMS")
<< endl
<< _(" -S, --sent directory to move sent SMS to,") << endl
<< _(" if unset, the SMS will be deleted") << endl
<< _(" -t, --store name of SMS store to use for flush\n"
" and/or temporary SMS storage") << endl
<< endl
<< _(" -v, --version prints version and exits") << endl
<< _(" -X, --xonxoff switch on software handshake") << endl
<< endl
<< _(" sms_type may be any combination of") << endl << endl
<< _(" sms, no_sms controls reception of normal SMS")
<< endl
<< _(" cb, no_cb controls reception of cell broadcast"
" messages") << endl
<< _(" stat, no_stat controls reception of status reports")
<< endl << endl
<< _(" default is \"sms cb stat\"") << endl << endl
<< _("If no action is given, the SMS is printed to stdout")
<< endl << endl
<< _("If -P is given, it activates the priority system and sets the") << endl
<< _("number or levels to use. For every level, there must be directories") << endl
<< _("named <spool directory>+<priority level>.") << endl
<< _("For example \"-P 2 -s queue -S send -F failed\" needs the following") <<endl
<< _("directories: queue1/ queue2/ send1/ send2/ failed1/ failed2/") <<endl
<< _("Before sending one SMS from queue2, all pending SMS from queue1") <<endl
<< _("will be sent.") <<endl
<< endl << endl;
exit(0);
break;
case '?':
throw GsmException(_("unknown option"), ParameterError);
break;
}
// find out which kind of message to route
for (int i = optind; i < argc; ++i)
{
string s = lowercase(argv[i]);
if (s == "sms")
enableSMS = true;
else if (s == "no_sms")
enableSMS = false;
else if (s == "cb")
enableCB = true;
else if (s == "no_cb")
enableCB = false;
else if (s == "stat")
enableStat = true;
else if (s == "no_stat")
enableStat = false;
}
// check parameters
if (concatenatedMessageIdStr != "")
concatenatedMessageId = checkNumber(concatenatedMessageIdStr);
// register signal handler for terminate signal
#ifndef WIN32
struct sigaction terminateAction;
terminateAction.sa_handler = terminateHandler;
sigemptyset(&terminateAction.sa_mask);
terminateAction.sa_flags = SA_RESTART;
if (sigaction(SIGINT, &terminateAction, NULL) != 0 ||
sigaction(SIGTERM, &terminateAction, NULL) != 0)
#else
if(signal(SIGINT, terminateHandler) == SIG_ERR ||
signal(SIGTERM, terminateHandler) == SIG_ERR)
#endif
throw GsmException(
stringPrintf(_("error when calling sigaction() (errno: %d/%s)"),
errno, strerror(errno)),
OSError);
// open GSM device
me = new MeTa(new
#ifdef WIN32
Win32SerialPort
#else
UnixSerialPort
#endif
(device,
baudrate == "" ? DEFAULT_BAUD_RATE :
baudRateStrToSpeed(baudrate), initString,
swHandshake));
// if flush option is given get all SMS from store and dispatch them
if (flushSMS)
{
if (receiveStoreName == "")
throw GsmException(_("store name must be given for flush option"),
ParameterError);
SMSStoreRef store = me->getSMSStore(receiveStoreName);
for (SMSStore::iterator s = store->begin(); s != store->end(); ++s)
if (! s->empty())
{
string result = _("Type of message: ");
switch (s->message()->messageType())
{
case SMSMessage::SMS_DELIVER:
result += _("SMS message\n");
break;
case SMSMessage::SMS_SUBMIT_REPORT:
result += _("submit report message\n");
break;
case SMSMessage::SMS_STATUS_REPORT:
result += _("status report message\n");
break;
}
result += s->message()->toString();
doAction(action, result);
store->erase(s);
}
}
// set default SMS store if -t option was given or
// read from ME otherwise
if (receiveStoreName == "")
{
string dummy1, dummy2;
me->getSMSStore(dummy1, dummy2, receiveStoreName );
}
else
me->setSMSStore(receiveStoreName, 3);
// switch message service level to 1
// this enables SMS routing to TA
me->setMessageService(1);
// switch on SMS routing
me->setSMSRoutingToTA(enableSMS, enableCB, enableStat,
onlyReceptionIndication);
// register event handler to handle routed SMSs, CBMs, and status reports
me->setEventHandler(new EventHandler());
// wait for new messages
bool exitScheduled = false;
while (1)
{
#ifdef WIN32
::timeval timeoutVal;
timeoutVal.tv_sec = 5;
timeoutVal.tv_usec = 0;
me->waitEvent((gsmlib::timeval *)&timeoutVal);
#else
struct timeval timeoutVal;
timeoutVal.tv_sec = 5;
timeoutVal.tv_usec = 0;
me->waitEvent(&timeoutVal);
#endif
// if it returns, there was an event or a timeout
while (newMessages.size() > 0)
{
// get first new message and remove it from the vector
SMSMessageRef newSMSMessage = newMessages.begin()->_newSMSMessage;
CBMessageRef newCBMessage = newMessages.begin()->_newCBMessage;
GsmEvent::SMSMessageType messageType =
newMessages.begin()->_messageType;
int index = newMessages.begin()->_index;
string storeName = newMessages.begin()->_storeName;
newMessages.erase(newMessages.begin());
// process the new message
string result = _("Type of message: ");
switch (messageType)
{
case GsmEvent::NormalSMS:
result += _("SMS message\n");
break;
case GsmEvent::CellBroadcastSMS:
result += _("cell broadcast message\n");
break;
case GsmEvent::StatusReportSMS:
result += _("status report message\n");
break;
}
if (! newSMSMessage.isnull())
result += newSMSMessage->toString();
else if (! newCBMessage.isnull())
result += newCBMessage->toString();
else
{
SMSStoreRef store = me->getSMSStore(storeName);
store->setCaching(false);
if (messageType == GsmEvent::CellBroadcastSMS)
result += (*store.getptr())[index].cbMessage()->toString();
else
result += (*store.getptr())[index].message()->toString();
store->erase(store->begin() + index);
}
// call the action
doAction(action, result);
}
// if no new SMS came in and program exit was scheduled, then exit
if (exitScheduled)
exit(0);
// handle terminate signal
if (terminateSent)
{
exitScheduled = true;
// switch off SMS routing
try
{
me->setSMSRoutingToTA(false, false, false);
}
catch (GsmException &ge)
{
// some phones (e.g. Motorola Timeport 260) don't allow to switch
// off SMS routing which results in an error. Just ignore this.
}
// the AT sequences involved in switching of SMS routing
// may yield more SMS events, so go round the loop one more time
}
// send spooled SMS
if (! terminateSent)
sendSMS(spoolDir, sentDir, failedDir, priorities, enableSyslog, me->getAt());
}
}
catch (GsmException &ge)
{
cerr << argv[0] << _("[ERROR]: ") << ge.what() << endl;
if (ge.getErrorClass() == MeTaCapabilityError)
cerr << argv[0] << _("[ERROR]: ")
<< _("(try setting sms_type, please refer to gsmsmsd manpage)")
<< endl;
// switch off message routing, so that following invocations of gsmsmd
// are not swamped with message deliveries while they start up
if (me != NULL)
{
try
{
me->setSMSRoutingToTA(false, false, false);
}
catch (GsmException &ge)
{
// some phones (e.g. Motorola Timeport 260) don't allow to switch
// off SMS routing which results in an error. Just ignore this.
}
}
return 1;
}
return 0;
}

View File

@ -0,0 +1,439 @@
// *************************************************************************
// * GSM TA/ME library
// *
// * File: gsmsmsstore.cc
// *
// * Purpose: SMS store management program
// *
// * Author: Peter Hofmann (software@pxh.de)
// *
// * Created: 4.8.1999
// *************************************************************************
#ifdef HAVE_CONFIG_H
#include <gsm_config.h>
#endif
#include <gsmlib/gsm_nls.h>
#include <string>
#include <ctype.h>
#ifdef WIN32
#include <gsmlib/gsm_win32_serial.h>
#else
#include <gsmlib/gsm_unix_serial.h>
#include <unistd.h>
#endif
#if defined(HAVE_GETOPT_LONG) || defined(WIN32)
#include <getopt.h>
#endif
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <gsmlib/gsm_me_ta.h>
#include <gsmlib/gsm_util.h>
#include <gsmlib/gsm_sorted_sms_store.h>
#include <iostream>
using namespace std;
using namespace gsmlib;
#ifdef HAVE_GETOPT_LONG
static struct option longOpts[] =
{
{"xonxoff", no_argument, (int*)NULL, 'X'},
{"init", required_argument, (int*)NULL, 'I'},
{"store", required_argument, (int*)NULL, 't'},
{"erase", no_argument, (int*)NULL, 'e'},
{"add", no_argument, (int*)NULL, 'a'},
{"list", no_argument, (int*)NULL, 'l'},
{"destination", required_argument, (int*)NULL, 'd'},
{"source", required_argument, (int*)NULL, 's'},
{"baudrate", required_argument, (int*)NULL, 'b'},
{"sca", required_argument, (int*)NULL, 'C'},
{"copy", no_argument, (int*)NULL, 'c'},
{"delete", no_argument, (int*)NULL, 'x'},
{"backup", no_argument, (int*)NULL, 'k'},
{"help", no_argument, (int*)NULL, 'h'},
{"version", no_argument, (int*)NULL, 'v'},
{"verbose", no_argument, (int*)NULL, 'V'},
{(char*)NULL, 0, (int*)NULL, 0}
};
#else
#define getopt_long(argc, argv, options, longopts, indexptr) \
getopt(argc, argv, options)
#endif
bool verbose = false; // true if --verbose option given
// type of operation to perform
enum Operation {CopyOp = 'c', BackupOp = 'k', DeleteOp = 'x',
AddOp = 'a', ListOp = 'l', NoOp = 0};
// aux function, insert entry only if not already present in dest
void backup(SortedSMSStoreRef destStore, SMSStoreEntry &entry)
{
// the following only works because we know that the default sort order
// is by date
assert(destStore->sortOrder() == ByDate);
Timestamp date = entry.message()->serviceCentreTimestamp();
pair<SortedSMSStore::iterator, SortedSMSStore::iterator> range =
destStore->equal_range(date);
for (SortedSMSStore::iterator j = range.first;
j != range.second; ++j)
if (entry == *j)
// do nothing if the entry is already present in the destination
return;
if (verbose)
cout << stringPrintf(_("inserting entry #%d from source into destination"),
entry.index()) << endl
<< entry.message()->toString();
destStore->insert(entry); // insert
}
// aux function, throw exception if operation != NoOp
void checkNoOp(Operation operation, int opt)
{
if (operation != NoOp)
throw GsmException(stringPrintf(_("incompatible options '%c' and '%c'"),
(char)operation, (char)opt),
ParameterError);
}
// *** main program
int main(int argc, char *argv[])
{
try
{
// handle command line options
string destination;
string source;
string baudrate;
string storeName;
char operation = NoOp;
SortedSMSStoreRef sourceStore, destStore;
bool useIndices = false; // use indices in delete, copy, backup op
string initString = DEFAULT_INIT_STRING;
bool swHandshake = false;
// service centre address (set on command line)
string serviceCentreAddress;
Ref<MeTa> sourceMeTa, destMeTa;
int opt;
int dummy;
while((opt = getopt_long(argc, argv, "I:t:s:d:b:cxlakhvVXC:",
longOpts, &dummy))
!= -1)
switch (opt)
{
case 'C':
serviceCentreAddress = optarg;
break;
case 'X':
swHandshake = true;
break;
case 'I':
initString = optarg;
break;
case 'V':
verbose = true;
break;
case 't':
storeName = optarg;
break;
case 'd':
destination = optarg;
break;
case 's':
source = optarg;
break;
case 'b':
baudrate = optarg;
break;
case 'c':
checkNoOp((Operation)operation, opt);
operation = CopyOp;
break;
case 'x':
checkNoOp((Operation)operation, opt);
operation = DeleteOp;
break;
case 'l':
checkNoOp((Operation)operation, opt);
operation = ListOp;
break;
case 'a':
checkNoOp((Operation)operation, opt);
operation = AddOp;
break;
case 'k':
checkNoOp((Operation)operation, opt);
operation = BackupOp;
break;
case 'v':
cerr << argv[0] << stringPrintf(_(": version %s [compiled %s]"),
VERSION, __DATE__) << endl;
exit(0);
break;
case 'h':
cerr << argv[0] << _(": [-a][-b baudrate][-c][-C sca]"
"[-d device or file]\n"
" [-h][-I init string][-k][-l]"
"[-s device or file]"
"[-t SMS store name]\n [-v][-V][-x][-X]"
"{indices}|[phonenumber text]") << endl
<< endl
<< _(" -a, --add add new SMS submit message\n"
" (phonenumber and text) to destination")
<< endl
<< _(" -b, --baudrate baudrate to use for device "
"(default: 38400)")
<< endl
<< _(" -c, --copy copy source entries to destination\n"
" (if indices are given, "
"copy only these entries)") << endl
<< _(" -C, --sca SMS service centre address") << endl
<< _(" -d, --destination sets the destination device to\n"
" connect to, or the file to write to")
<< endl
<< _(" -h, --help prints this message") << endl
<< _(" -I, --init device AT init sequence") << endl
<< _(" -k, --backup backup new entries to destination\n"
" (if indices are given, "
"copy only these entries)") << endl
<< _(" -l, --list list source to stdout") << endl
<< _(" -s, --source sets the source device to connect to,\n"
" or the file to read") << endl
<< _(" -t, --store name of SMS store to use") << endl
<< _(" -v, --version prints version and exits") << endl
<< _(" -V, --verbose print detailed progress messages")
<< endl
<< _(" -x, --delete delete entries denoted by indices")
<< endl
<< _(" -X, --xonxoff switch on software handshake") << endl
<< endl;
exit(0);
break;
case '?':
throw GsmException(_("unknown option"), ParameterError);
break;
}
// check if parameters are complete
if (operation == NoOp)
throw GsmException(_("no operation option given"), ParameterError);
if (operation == BackupOp || operation == CopyOp)
if (destination.length() == 0 || source.length() == 0)
throw GsmException(_("both source and destination required"),
ParameterError);
if (operation == ListOp)
{
if (destination.length() != 0)
throw GsmException(_("destination must not be given"), ParameterError);
if (source.length() == 0)
throw GsmException(_("source required"), ParameterError);
}
if (operation == AddOp || operation == DeleteOp)
{
if (source.length() != 0)
throw GsmException(_("source must not be given"), ParameterError);
if (destination.length() == 0)
throw GsmException(_("destination required"), ParameterError);
}
if (operation == CopyOp || operation == DeleteOp || operation == BackupOp)
{
// check if all indices are numbers
for (int i = optind; i < argc; ++i)
for (char *pp = argv[i]; *pp != 0; ++pp)
if (! isdigit(*pp))
throw GsmException(stringPrintf(_("expected number, got '%s'"),
argv[i]), ParameterError);
useIndices = optind != argc;
}
else if (operation == AddOp)
{
if (optind + 2 < argc)
throw GsmException(_("more than two parameters given"),
ParameterError);
if (optind + 2 > argc)
throw GsmException(_("not enough parameters given"),
ParameterError);
}
else
if (optind != argc)
throw GsmException(_("unexpected parameters"), ParameterError);
// start accessing source store or file if required by operation
if (operation == CopyOp || operation == BackupOp || operation == ListOp)
if (source == "-")
sourceStore = new SortedSMSStore(true);
else if (isFile(source))
sourceStore = new SortedSMSStore(source);
else
{
if (storeName == "")
throw GsmException(_("store name must be given"), ParameterError);
sourceMeTa = new MeTa(new
#ifdef WIN32
Win32SerialPort
#else
UnixSerialPort
#endif
(source,
baudrate == "" ? DEFAULT_BAUD_RATE :
baudRateStrToSpeed(baudrate), initString,
swHandshake));
sourceStore = new SortedSMSStore(sourceMeTa->getSMSStore(storeName));
}
// make sure destination file exists
if (destination != "")
{
try
{
ofstream f(destination.c_str(), ios::out | ios::app | ios::binary);
}
catch (exception)
{
}
}
// start accessing destination destination store or file
if (operation == CopyOp || operation == BackupOp || operation == AddOp ||
operation == DeleteOp)
if (destination == "-")
destStore = new SortedSMSStore(false);
else if (isFile(destination))
destStore = new SortedSMSStore(destination);
else
{
if (storeName == "")
throw GsmException(_("store name must be given"), ParameterError);
destMeTa = new MeTa(new
#ifdef WIN32
Win32SerialPort
#else
UnixSerialPort
#endif
(destination,
baudrate == "" ? DEFAULT_BAUD_RATE :
baudRateStrToSpeed(baudrate), initString,
swHandshake));
destStore = new SortedSMSStore(destMeTa->getSMSStore(storeName));
}
// now do the actual work
switch (operation)
{
case BackupOp:
{
sourceStore->setSortOrder(ByIndex); // needed in loop
if (useIndices)
for (int i = optind; i < argc; ++i)
{
SortedSMSStore::iterator j = sourceStore->find(atoi(argv[i]));
if (j == sourceStore->end())
throw GsmException(stringPrintf(_("no index '%s' in source"),
argv[i]), ParameterError);
backup(destStore, *j);
}
else
for (SortedSMSStore::iterator i = sourceStore->begin();
i != sourceStore->end(); ++i)
backup(destStore, *i);
break;
}
case CopyOp:
{
destStore->clear();
if (! useIndices) // copy all entries
{
for (SortedSMSStore::iterator i = sourceStore->begin();
i != sourceStore->end(); ++i)
{
if (verbose)
cout << stringPrintf(_("inserting entry #%d from source "
"into destination"), i->index()) << endl
<< i->message()->toString();
destStore->insert(*i);
}
}
else // copy indexed entries
{
sourceStore->setSortOrder(ByIndex); // needed in loop
for (int i = optind; i < argc; ++i)
{
SortedSMSStore::iterator j = sourceStore->find(atoi(argv[i]));
if (j == sourceStore->end())
throw GsmException(stringPrintf(_("no index '%s' in source"),
argv[i]), ParameterError);
if (verbose)
cout << stringPrintf(_("inserting entry #%d from source into "
"destination"), j->index()) << endl
<< j->message()->toString();
destStore->insert(*j);
}
}
break;
}
case ListOp:
{
for (SortedSMSStore::iterator i = sourceStore->begin();
i != sourceStore->end(); ++i)
cout << stringPrintf(_("index #%d"), i->index()) << endl
<< i->message()->toString();
break;
}
case AddOp:
{
SMSMessageRef sms = new SMSSubmitMessage(argv[optind + 1], argv[optind]);
// set service centre address in new submit PDU if requested by user
if (serviceCentreAddress != "")
{
Address sca(serviceCentreAddress);
sms->setServiceCentreAddress(sca);
}
if (verbose)
cout << _("inserting new entry into destination") << endl
<< sms->toString();
destStore->insert(sms);
break;
}
case DeleteOp:
{
destStore->setSortOrder(ByIndex);
for (int i = optind; i < argc; ++i)
{
int index = atoi(argv[i]);
if (verbose)
{
SortedSMSStore::iterator e = destStore->find(index);
if (e != destStore->end())
cout << stringPrintf(_("deleting entry #%d from destination"),
index) << endl
<< e->message()->toString();
}
if (destStore->erase(index) != 1)
throw GsmException(stringPrintf(_("no index '%s' in destination"),
argv[i]), ParameterError);
}
break;
}
}
}
catch (GsmException &ge)
{
cerr << argv[0] << _("[ERROR]: ") << ge.what() << endl;
return 1;
}
return 0;
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,131 @@
dnl *************************************************************************
dnl * GSM TA/ME library
dnl *
dnl * File: configure.in
dnl *
dnl * Purpose: autoconf configure script template
dnl *
dnl * Author: Peter Hofmann (software@pxh.de)
dnl *
dnl * Created: 11.11.1999
dnl *************************************************************************
dnl Process this file with autoconf to produce a configure script.
AC_INIT(gsmlib/gsm_error.h)
dnl Other
AC_CONFIG_AUX_DIR(scripts)
AC_PROG_INSTALL
dnl check for libintl
AC_CHECK_LIB(intl, textdomain)
dnl use config header
AM_CONFIG_HEADER(gsm_config.h)
dnl use automake
AM_INIT_AUTOMAKE(gsmlib, 1.10)
dnl change to no if you want no shared libraries for debugging purposes
AM_ENABLE_SHARED(yes)
dnl use -O2 optimization by default
if test "$CXXFLAGS" = ""; then
CXXFLAGS="-O2"
fi
dnl comment out this line to get extensive debugging output and asserts
dnl CXXFLAGS="-DNDEBUG $CXXFLAGS"
dnl uncomment to get translations without installing gsmlib
dnl CXXFLAGS="-DLOCAL_TRANSLATIONS $CXXFLAGS"
dnl check _REENTRANT in header files
if test x"`egrep _REENTRANT /usr/include/features.h`" != x; then
CXXFLAGS="-D_REENTRANT $CXXFLAGS"
CFLAGS="-D_REENTRANT $CFLAGS"
fi
dnl output all warnings
CXXFLAGS="-Wall $CXXFLAGS"
dnl use libtool
AM_PROG_LIBTOOL
dnl Checks for programs.
AC_PROG_CPP
AC_PROG_CXX
dnl check for gcc 2.95.x
AC_TRY_RUN([
#include <unistd.h>
main()
{
#if defined(__GNUC__) && \
! (__GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 95))
return 1;
#endif
return 0;
}
],,
[echo "need at least gcc 2.95 to compile correctly"
exit 1])
dnl check for alloca
AC_FUNC_ALLOCA
dnl check for getopt_long in the C library
AC_CHECK_LIB(c, getopt_long, AC_DEFINE(HAVE_GETOPT_LONG))
dnl check for alarm in the C library
AC_CHECK_LIB(c, alarm, AC_DEFINE(HAVE_ALARM))
dnl check for netinet/in.h header
AC_CHECK_HEADERS(netinet/in.h)
dnl check for string.h header
AC_CHECK_HEADERS(string.h)
dnl check for libintl.h header
AC_CHECK_HEADERS(libintl.h)
dnl Checks for typedefs, structures, and compiler characteristics.
AC_C_CONST
dnl check for vsnprintf()
dnl AC_FUNC_VPRINTF
AC_EGREP_HEADER(vsnprintf, stdio.h, AC_DEFINE(HAVE_VSNPRINTF))
dnl checks for builtin data type sizes
AC_CHECK_SIZEOF(unsigned short int, 2)
AC_CHECK_SIZEOF(unsigned long int, 4)
AC_CHECK_SIZEOF(unsigned int, 4)
dnl Project-specific settings
GSM_VERSION="1:4:0"
AC_SUBST(GSM_VERSION)
dnl national language support (NLS)
LINGUAS="de"
ALL_LINGUAS=$LINGUAS
AM_GNU_GETTEXT
dnl set locale dir (FIXME there must be a better way)
_localedir=`eval "echo $datadir/locale"`
if test "$_localedir" = "NONE/share/locale"; then
AC_DEFINE_UNQUOTED(LOCALEDIR, "/usr/local/share/locale")
else
_localedir=`echo \"$_localedir\"`
AC_DEFINE_UNQUOTED(LOCALEDIR, $_localedir)
fi
dnl whether to compile the intl directory
AM_CONDITIONAL(COMPILE_INTL, test x$USE_INCLUDED_LIBINTL = xyes)
AC_OUTPUT(Makefile gsmlib/Makefile tests/Makefile apps/Makefile win32/Makefile
doc/Makefile scripts/Makefile intl/Makefile po/Makefile.in
ext/Makefile,
echo timestamp > stamp-h)
dnl repair Makefile in po subdir
dnl sed -e "/POTFILES =/r po/POTFILES" po/Makefile.in > po/Makefile

View File

@ -0,0 +1,3 @@
# /etc/cron.d/gsm-utils: crontab fragment for gsm-utils
*/5 * * * * root if [ -x /usr/bin/gsmsmsrequeue ]; then /usr/bin/gsmsmsrequeue; fi

View File

@ -0,0 +1,13 @@
PHONEDEV=/dev/mobilephone # or /dev/ttyS0 or /dev/ircomm0
BAUDRATE=9600
PIN="" # or 1234
SPOOLDIR=/var/spool/sms
PRIORITIES=3
SMSADMIN=root
SUBJECT="SMS delivery report:"
SMSPROCESSOR="" # or /usr/bin/gsmsmsprocessor
function do_accounting { true; } # it's your turn

View File

@ -0,0 +1,72 @@
#! /bin/sh
#
# /etc/init.d/gsm-utils: Controls the GSM SMS send daemon
#
# written by Matthias Goebl <matthias@goebl.net>
PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin
DAEMON=/usr/bin/gsmsmsd
NAME=gsmsmsd
DESC="GSM SMS send daemon"
test -x $DAEMON || exit 0
PHONEDEV=/dev/mobilephone # or /dev/ttyS0 or /dev/ircomm0
BAUDRATE=9600
PIN="" # or 1234
SMSPROCESSOR="" # or /usr/bin/gsmsmsprocessor
SPOOLDIR=/var/spool/sms
PRIORITIES=3
STARTOPTS=""
SMSUSER="gsmsms:gsmsms"
test -r /etc/default/gsm-utils && . /etc/default/gsm-utils # for overwriting some parameters
OPTIONS="-d $PHONEDEV -b $BAUDRATE -L -P $PRIORITIES"
OPTIONS="$OPTIONS -s $SPOOLDIR/queue -S $SPOOLDIR/sent -F $SPOOLDIR/failed"
test -n "$SMSPROCESSOR" && OPTIONS="$OPTIONS -a $SMSPROCESSOR"
test -n "$SMSUSER" && STARTOPTS="$STARTOPTS --chuid $SMSUSER"
test -r /etc/default/gsm-utils && . /etc/default/gsm-utils # for overwriting OPTIONS
case "$1" in
start)
echo -n "Starting $DESC: "
if [ -n "$PIN" ];then
echo -n "entering PIN.. "
(
# This is ugly.. But if the PIN is already entered, the ME returns
# "ERROR" and makes gsmctl retrying..
/usr/bin/gsmctl -d $PHONEDEV -b $BAUDRATE -I "+cpin=$PIN" &
PID=$!
sleep 3
kill $PID 2>/dev/null
) >/dev/null 2>&1
fi
echo -n "$NAME"
start-stop-daemon --start --quiet --pidfile /var/run/gsm-utils/$NAME.pid \
--make-pidfile --background $STARTOPTS --exec $DAEMON -- $OPTIONS
echo "."
;;
stop)
echo -n "Stopping $DESC: $NAME "
start-stop-daemon --stop --quiet --pidfile /var/run/gsm-utils/$NAME.pid \
--exec $DAEMON
sleep 5
echo "."
;;
restart|force-reload)
echo -n "Restarting $DESC: $NAME"
start-stop-daemon --start --quiet --pidfile /var/run/gsm-utils/$NAME.pid \
--make-pidfile --background $STARTOPTS --exec $DAEMON -- $OPTIONS
sleep 5
start-stop-daemon --start --quiet --pidfile /var/run/gsm-utils/$NAME.pid \
--make-pidfile --background --exec $DAEMON -- $OPTIONS
echo "."
;;
*)
N=/etc/init.d/gsm-utils
echo "Usage: $N {start|stop|restart|force-reload}" >&2
exit 1
;;
esac
exit 0

View File

@ -0,0 +1,44 @@
#! /bin/sh
#
# /usr/bin/gsmsmsrequeue: Re-queues failed SMS
#
# written by Matthias Goebl <matthias@goebl.net>
SPOOLDIR=/var/spool/sms
PRIORITIES=3
SMSADMIN=root
SUBJECT="SMS delivery report:"
function send_notify {
tmpfile="$SPOOLDIR/tmp/"`basename "$1"`
status="$2"
if mv "$1" "$tmpfile" 2>/dev/null; then
# extract the first tab-separated field after the phone number as
# email-address to send the notification to
mailto=` cat "$tmpfile" | sed -ne '1s/^[^ ]* \([^ ]*\).*/\1/p' `
test -z "$mailto" && mailto="$SMSADMIN"
cat "$tmpfile" | mail -s "$SUBJECT $status" "$mailto"
rm "$tmpfile"
fi
}
function do_accounting { true; }
test -r /etc/default/gsm-utils && . /etc/default/gsm-utils
for p in `seq 1 $PRIORITIES`; do
ls "$SPOOLDIR/failed$p" | while read file; do
if expr "$file" : ".*rrrrrrrrrrrr" >/dev/null; then
send_notify "$SPOOLDIR/failed$p/$file" "failed"
else
# re-queue SMS
mv "$SPOOLDIR/failed$p/$file" "$SPOOLDIR/queue$p/${file}r" 2>/dev/null
fi
done
done
for p in `seq 1 $PRIORITIES`; do
ls "$SPOOLDIR/sent$p" | while read file; do
do_accounting "$SPOOLDIR/sent$p/$file" "sent"
send_notify "$SPOOLDIR/sent$p/$file" "sent"
done
done

View File

@ -0,0 +1,34 @@
#! /bin/sh
#
# /usr/bin/gsmsmsspool: Queues SMS for sending
#
# written by Matthias Goebl <matthias@goebl.net>
SPOOLDIR=/var/spool/sms
PRIORITIES=3
test -r /etc/default/gsm-utils && . /etc/default/gsm-utils
if [ -z "$1" ]; then
echo "Usage: gsmsmsspool NUMBER [MESSAGE]"
exit 1
fi
priority=$PRIORITIES # default priority
test -n "$GSMSMS_PRIORITY" && priority="$GSMSMS_PRIORITY"
mailto=`id -un`
test -n "$GSMSMS_NOTIFY" && mailto="$GSMSMS_NOTIFY"
tmpfile="$SPOOLDIR/tmp/`date +%s`.$$"
umask 022
echo "$1 $mailto" > "$tmpfile"
if [ -n "$2" ]; then
echo "$2" | head -c 160 >> "$tmpfile"
else
head -c 160 >> "$tmpfile"
fi
if [ "`id -un`" = "root" ]; then
chown gsmsms:gsmsms "$tmpfile"
fi
mv "$tmpfile" "$SPOOLDIR/queue$priority/"

View File

@ -0,0 +1,244 @@
gsmlib (1.10-12ubuntu1) hardy; urgency=low
* Merge from Debian unstable. Remaining Ubuntu changes:
- [debian/gsm-utils.postinst, debian/gsm-utils.init]
Create /var/run/gsm-utils if it does not exist
- Actually fix the init script (debian #377448)
- Set Ubuntu maintainer adress.
-- Albin Tonnerre <lutin@ubuntu.com> Wed, 12 Dec 2007 00:45:00 +0100
gsmlib (1.10-12) unstable; urgency=low
* addgroup --system gsmsms works better. Thanks Jon
* only delete gsmsms on purge
- gsm-utils: deletes and recreates the gsmsms user on each upgrade
(Closes: #346238)
- gsm-utils fails installation / addgroup: The user gsmsms; does
not exist (Closes: #445404)
* lintian cleanup: debian-rules-ignores-make-clean-error substvar-
source-version-is-deprecated
* Scripts are installed +x
- gsm-utils: uselessly installs non-executable scripts into /usr/bin
(Closes: #346230)
* Remove bogus symlink
- gsm-utils: wrong symlink for manpage gsmsiectl.1 (Closes: #322382)
- gsm-utils: gsmsiectl.1 dangling symlink (Closes: #399582)
* debian/gsm-utils.init reload/restart was not calling --stop. Thanks
Barry
- init script calls --start twice (Closes: #377448)
-- Mark Purcell <msp@debian.org> Mon, 08 Oct 2007 21:44:00 +0100
gsmlib (1.10-11) unstable; urgency=low
* Create system group gsmsms - Thanks Emmanuel
- gsm-utils: creates group in non-system gid range (Closes: #353967)
- gsm-utils: postinst should create system grp gsmsms (Closes:
#390266)
* Upgrade to compat 4
* Apply gcc-4.3 patch from Martin
- FTBFS with GCC 4.3: missing #includes (Closes: #417222)
-- Mark Purcell <msp@debian.org> Sat, 29 Sep 2007 18:22:56 +0100
gsmlib (1.10-10ubuntu3) feisty; urgency=low
* Rebuild for ldbl128 change (powerpc, sparc).
* Set Ubuntu maintainer address.
-- Matthias Klose <doko@ubuntu.com> Thu, 1 Mar 2007 22:37:57 +0000
gsmlib (1.10-10ubuntu2) edgy; urgency=low
* [debian/gsm-utils.postinst, debian/gsm-utils.init]
Create /var/run/gsm-utils if it does not exist
-- Matt Zimmerman <mdz@ubuntu.com> Tue, 11 Jul 2006 13:59:12 -0700
gsmlib (1.10-10ubuntu1) edgy; urgency=low
* Re-sync with Debian
* debian/gsm-utils.init reload/restart was not calling --stop
-- Barry deFreese <bddebian@comcast.net> Sat, 8 Jul 2006 22:52:23 -0400
gsmlib (1.10-10) unstable; urgency=low
* FTBFS with G++ 4.1: extra qualifications (Closes: #356109)
-- Mark Purcell <msp@debian.org> Sat, 20 May 2006 21:54:42 +0100
gsmlib (1.10-9) unstable; urgency=low
* library package needs to be renamed (libstdc++ allocator change)
(Closes: #339179)
-- Mark Purcell <msp@debian.org> Mon, 21 Nov 2005 21:19:51 +0000
gsmlib (1.10-8) unstable; urgency=low
* removal of automake1.6 (Closes: #335123)
* fails with dash [bashisms in scripts] (Closes: #309834)
* Update libtool Fixes: gsmlib(GNU/k*BSD): FTBFS: out of date libtool scripts (Closes:
#319688)
* [INTL:de] German PO file corrections (Closes: #314060)
* Fix: old-fsf-address-in-copyright-file
-- Mark Purcell <msp@debian.org> Thu, 3 Nov 2005 22:40:19 +0000
gsmlib (1.10-7) unstable; urgency=low
* C++ 4.0 transition
* Closes: #315864: Missing manpages
* gsm-utils: maintainer-script-needs-depends-on-adduser postinst
-- Mark Purcell <msp@debian.org> Sat, 23 Jul 2005 00:46:31 +1000
gsmlib (1.10-6) unstable; urgency=low
* Rebuild for invalid dependancies
* Closes: #258056: libgsmme 99% cpu usage
- Patch from Emard
* Closes: #274382: FTBFS with gcc-3.4: template-id `operator&lt;
&lt;&gt;' for `bool gsmlib::operator&lt;(const
gsmlib::MapKey&lt;gsmlib::SortedPhonebookBase&gt;&amp;, const
gsmlib::MapKey&lt;gsmlib::SortedPhonebookBase&gt;&amp;)' does not
match any template declaration
- Patch from Andreas Jochens
* Closes: #294251: FTBFS (amd64/gcc-4.0): explicit qualification in
declaration of `bool gsmlib::operator&lt;(const
gsmlib::MapKey&lt;SortedStore&gt;&amp;, const
gsmlib::MapKey&lt;SortedStore&gt;&amp;)'
- Patch from Andreas Jochens
* Closes: #200189: Patch and contribution
+ Added multi-queue-priority-system and syslog patch (Matthias Goebl)
+ Included init, spool and requeue scripts for gsmsmsd (Matthias Goebl)
+ gsmsmsd runs with own user and group (gsmsms:gsmsms) (Matthias Goebl)
-- Mark Purcell <msp@debian.org> Tue, 17 May 2005 11:34:45 +0100
gsmlib (1.10-5) unstable; urgency=low
* Change Section: libdevel
* gsm_unix_serial.cc patch from Daniel Schepler to fix g++-3.3
compliation. Thanks. (Closes: Bug#195151)
-- Mark Purcell <msp@debian.org> Sat, 19 Jul 2003 15:57:28 +1000
gsmlib (1.10-4) unstable; urgency=low
* Include file descriptor leak patch from Edd Dumbill (Closes:
Bug#168475)
* lintian cleanup: description-synopsis-might-not-be-phrased-properly
* lintian cleanup: configure-generated-file-in-source
-- Mark Purcell <msp@debian.org> Sun, 9 Feb 2003 14:04:54 +1100
gsmlib (1.10-3) unstable; urgency=low
* New Maintainer (Closes: Bug#180061). Thanks Mikael for your work.
-- Mark Purcell <msp@debian.org> Sat, 8 Feb 2003 16:55:26 +1100
gsmlib (1.10-2) unstable; urgency=low
* Rebuild to use the new c++ ABI (GCC 3.2)
-- Mikael Hedin <micce@debian.org> Thu, 23 Jan 2003 20:57:50 +0100
gsmlib (1.10-1) unstable; urgency=low
* New upstrem release.
-- Mikael Hedin <micce@debian.org> Wed, 6 Nov 2002 17:44:17 +0100
gsmlib (1.9-2) unstable; urgency=low
* Made new rules for the config.guess/sub update thing (closes: #146865,
#146867).
-- Mikael Hedin <micce@debian.org> Tue, 14 May 2002 09:28:03 +0200
gsmlib (1.9-1) unstable; urgency=low
* New upstream version.
* Use chrpath to get rid of rpaths.
* Add mini-manpage for gsmsiexfer.
* Remove b-d on auto-stuff, we don't use them.
-- Mikael Hedin <micce@debian.org> Mon, 13 May 2002 22:10:28 +0200
gsmlib (1.8-2) unstable; urgency=low
* Removed b-d on gcc 3.0, as they are no longer nessecary.
-- Mikael Hedin <micce@debian.org> Thu, 24 Jan 2002 12:59:07 +0100
gsmlib (1.8-1) unstable; urgency=low
* New upstream version.
* Revert the arch hack, now it should compile with either g++.
* Include the new lib in libgsmme1. Run dh_makeshlibs -V because of this.
* Added info for gsmsiectl in gsmctl(1).
-- Mikael Hedin <micce@debian.org> Wed, 9 Jan 2002 22:38:45 +0100
gsmlib (1.7-2) unstable; urgency=low
* gsm-utils: Added shlibs:Depends (closes: #126127).
* Spelling correction (closes: #124705, #124972)
* Rm libgsmme1.postins, and let dh_makeshlibs take care of ldconfig.
* Made explicit arch list without sparc and arm, they cannot use g++-3.0
right now.
-- Mikael Hedin <micce@debian.org> Sat, 22 Dec 2001 20:27:54 +0100
gsmlib (1.7-1) unstable; urgency=low
* New upstream
* Use gcc-3.0 and g++-3.0, 2.95 doesn't compile.
-- Mikael Hedin <micce@debian.org> Thu, 1 Nov 2001 10:24:33 +0100
gsmlib (1.6-5) unstable; urgency=low
* Updated manpage (closes: #110973)
* Corrected problem with OP status (closes: #110970)
-- Mikael Hedin <micce@debian.org> Sat, 8 Sep 2001 18:12:17 +0200
gsmlib (1.6-4) unstable; urgency=low
* Support DEB_BUILD_OPTIONS
* Changed libgsmme-dev to section devel.
* Reran libtoolize.
* Lots of small patches to compile with g++-3.0. (Closes: #104411)
* Removed dh_testversion.
-- Mikael Hedin <micce@debian.org> Thu, 12 Jul 2001 16:06:23 +0200
gsmlib (1.6-3) unstable; urgency=low
* Various minor corrections.
-- Mikael Hedin <mikael.hedin@irf.se> Thu, 8 Mar 2001 16:24:07 +0100
gsmlib (1.6-2) unstable; urgency=low
* Dont install INSTALL. Correct indentation for libgsmme1 description.
-- Mikael Hedin <mikael.hedin@irf.se> Tue, 6 Mar 2001 14:55:05 +0100
gsmlib (1.6-1) unstable; urgency=low
* New upstream version.
-- Mikael Hedin <mikael.hedin@irf.se> Mon, 29 Jan 2001 17:57:21 +0100
gsmlib (1.5-1) unstable; urgency=low
* Initial Release.
-- Mikael Hedin <mikael.hedin@irf.se> Thu, 14 Dec 2000 01:06:40 +0100

View File

@ -0,0 +1,52 @@
Source: gsmlib
Section: comm
Priority: extra
Maintainer: Ubuntu MOTU Developers <ubuntu-motu@lists.ubuntu.com>
XSBC-Original-Maintainer: Mark Purcell <msp@debian.org>
Build-Depends: debhelper (>= 3.0.0), chrpath
Standards-Version: 3.2.1
Package: libgsmme-dev
Section: libdevel
Architecture: any
Depends: libgsmme1c2a (= ${binary:Version}), libc6-dev
Description: Header files and static libraries for gsmlib
Headers and static libraries for use when compiling programs with
gsmlib.
.
gsmlib is a library for access to a GSM mobile phone using the
standards ETSI GSM 07.07, ETSI GSM 07.05, and others.
.
Website: http://www.pxh.de/fs/gsmlib/
Package: libgsmme1c2a
Conflicts: libgsmme1, libgsmme1c102, libgsmme1c2
Replaces: libgsmme1c102, libgsmme1c2
Section: libs
Architecture: any
Depends: ${shlibs:Depends}
Description: GSM mobile phone access library
Library to access GSM mobile phones through GSM modems or IrDA devices.
Features include:
.
* modification of phone books stored in the mobile phone or on the
SIM card
* reading and writing of SMS messages stored in the mobile phone
* sending and reception of SMS messages
.
gsmlib uses standard ETSI GSM 07.07, ETSI GSM 07.05, and others.
.
Website: http://www.pxh.de/fs/gsmlib/
Package: gsm-utils
Section: comm
Architecture: any
Depends: ${shlibs:Depends}, adduser
Description: GSM mobile phone access applications
Some simple command line programs to access a GSM mobile phone via
GSM modem or IrDA. Functions include: modification of phone books and
reading, writing, sending and receiving SMS messages. Uses the GSM
standards ETSI GSM 07.07, ETSI GSM 07.05, and others.
.
Website: http://www.pxh.de/fs/gsmlib/

View File

@ -0,0 +1,26 @@
This package was debianized by Mikael Hedin <mikael.hedin@irf.se> on
Thu, 14 Dec 2000 01:06:40 +0100.
It was downloaded from http://www.pxh.de/fs/gsmlib/index.html
Upstream Author: Peter Hofmann <software@pxh.de>
Copyright:
This package 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; version 2 dated June, 1991.
This package is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this package; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,
MA 02110-1301, USA.
On Debian GNU/Linux systems, the complete text of the GNU General
Public License can be found in `/usr/share/common-licenses/GPL'.

View File

@ -0,0 +1,3 @@
# /etc/cron.d/gsm-utils: crontab fragment for gsm-utils
*/5 * * * * root if [ -x /usr/bin/gsmsmsrequeue ]; then /usr/bin/gsmsmsrequeue; fi

View File

@ -0,0 +1,13 @@
PHONEDEV=/dev/mobilephone # or /dev/ttyS0 or /dev/ircomm0
BAUDRATE=9600
PIN="" # or 1234
SPOOLDIR=/var/spool/sms
PRIORITIES=3
SMSADMIN=root
SUBJECT="SMS delivery report:"
SMSPROCESSOR="" # or /usr/bin/gsmsmsprocessor
function do_accounting { true; } # it's your turn

View File

@ -0,0 +1,11 @@
var/spool/sms/queue1
var/spool/sms/queue2
var/spool/sms/queue3
var/spool/sms/sent1
var/spool/sms/sent2
var/spool/sms/sent3
var/spool/sms/failed1
var/spool/sms/failed2
var/spool/sms/failed3
var/spool/sms/tmp
var/run/gsm-utils

View File

@ -0,0 +1,4 @@
NEWS
README
TODO
doc/FAQ

View File

@ -0,0 +1,77 @@
#! /bin/sh
#
# /etc/init.d/gsm-utils: Controls the GSM SMS send daemon
#
# written by Matthias Goebl <matthias@goebl.net>
PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin
DAEMON=/usr/bin/gsmsmsd
NAME=gsmsmsd
DESC="GSM SMS send daemon"
test -x $DAEMON || exit 0
PHONEDEV=/dev/mobilephone # or /dev/ttyS0 or /dev/ircomm0
BAUDRATE=9600
PIN="" # or 1234
SMSPROCESSOR="" # or /usr/bin/gsmsmsprocessor
SPOOLDIR=/var/spool/sms
PRIORITIES=3
STARTOPTS=""
SMSUSER="gsmsms:gsmsms"
test -r /etc/default/gsm-utils && . /etc/default/gsm-utils # for overwriting some parameters
OPTIONS="-d $PHONEDEV -b $BAUDRATE -L -P $PRIORITIES"
OPTIONS="$OPTIONS -s $SPOOLDIR/queue -S $SPOOLDIR/sent -F $SPOOLDIR/failed"
test -n "$SMSPROCESSOR" && OPTIONS="$OPTIONS -a $SMSPROCESSOR"
test -n "$SMSUSER" && STARTOPTS="$STARTOPTS --chuid $SMSUSER"
test -r /etc/default/gsm-utils && . /etc/default/gsm-utils # for overwriting OPTIONS
if [ ! -d /var/run/gsm-utils ]; then
mkdir /var/run/gsm-utils
chown gsmsms:gsmsms /var/run/gsm-utils
fi
case "$1" in
start)
echo -n "Starting $DESC: "
if [ -n "$PIN" ];then
echo -n "entering PIN.. "
(
# This is ugly.. But if the PIN is already entered, the ME returns
# "ERROR" and makes gsmctl retrying..
/usr/bin/gsmctl -d $PHONEDEV -b $BAUDRATE -I "+cpin=$PIN" &
PID=$!
sleep 3
kill $PID 2>/dev/null
) >/dev/null 2>&1
fi
echo -n "$NAME"
start-stop-daemon --start --quiet --pidfile /var/run/gsm-utils/$NAME.pid \
--make-pidfile --background $STARTOPTS --exec $DAEMON -- $OPTIONS
echo "."
;;
stop)
echo -n "Stopping $DESC: $NAME "
start-stop-daemon --stop --quiet --pidfile /var/run/gsm-utils/$NAME.pid \
--exec $DAEMON
sleep 5
echo "."
;;
restart|force-reload)
echo -n "Restarting $DESC: $NAME"
start-stop-daemon --stop --quiet --pidfile /var/run/gsm-utils/$NAME.pid \
--make-pidfile --background --exec $DAEMON -- $OPTIONS
sleep 5
start-stop-daemon --start --quiet --pidfile /var/run/gsm-utils/$NAME.pid \
--make-pidfile --background $STARTOPTS --exec $DAEMON -- $OPTIONS
echo "."
;;
*)
N=/etc/init.d/gsm-utils
echo "Usage: $N {start|stop|restart|force-reload}" >&2
exit 1
;;
esac
exit 0

View File

@ -0,0 +1,31 @@
#!/bin/sh -e
# create gsmsms group if necessary.
if ! grep -q ^gsmsms: /etc/group; then
# echo Adding system group: gsmsms.
addgroup --system gsmsms
fi
# create gsmsms user if necessary.
if ! grep -q ^gsmsms: /etc/passwd; then
# echo Adding system user: gsmsms.
adduser --system --ingroup gsmsms \
--no-create-home --home /var/spool/sms gsmsms
fi
# allow gsmsms to use serial lines
if ! groups gsmsms | grep -q dialout ; then
adduser gsmsms dialout
fi
# echo Updating spool directory structure: /var/spool/sms
if [ ! -d /var/run/gsm-utils ]; then
mkdir /var/run/gsm-utils
fi
chown -R gsmsms:gsmsms /var/spool/sms /var/run/gsm-utils
chmod 700 /var/spool/sms/*
chmod 750 /var/spool/sms
chmod 730 /var/spool/sms/queue* /var/spool/sms/tmp
# Add the rest automatically..
#DEBHELPER#

View File

@ -0,0 +1,43 @@
#!/bin/sh
# postrm script for #PACKAGE#
#
# see: dh_installdeb(1)
set -e
# summary of how this script can be called:
# * <postrm> `remove'
# * <postrm> `purge'
# * <old-postrm> `upgrade' <new-version>
# * <new-postrm> `failed-upgrade' <old-version>
# * <new-postrm> `abort-install'
# * <new-postrm> `abort-install' <old-version>
# * <new-postrm> `abort-upgrade' <old-version>
# * <disappearer's-postrm> `disappear' <overwriter>
# <overwriter-version>
# for details, see http://www.debian.org/doc/debian-policy/ or
# the debian-policy package
case "$1" in
remove|upgrade|failed-upgrade|abort-install|abort-upgrade|disappear)
;;
purge)
deluser gsmsms
;;
*)
echo "postrm called with unknown argument \`$1'" >&2
exit 1
;;
esac
# dh_installdeb will replace this with shell code automatically
# generated by other debhelper scripts.
#DEBHELPER#
exit 0

View File

@ -0,0 +1,2 @@
gsmsmsspool.1
gsmsmsrequeue.8

View File

@ -0,0 +1,29 @@
.\" -*- eval: (nroff-mode) -*-
.de TQ
.br
.ns
.TP \\$1
..
.\" Like TP, but if specified indent is more than half
.\" the current line-length - indent, use the default indent.
.de Tp
.ie \\n(.$=0:((0\\$1)*2u>(\\n(.lu-\\n(.iu)) .TP
.el .TP "\\$1"
..
.TH GSMSIEXFER 1 "" "gsmsiexfer"
.SH NAME
gsmsiexfer \- Siemens ME file transfer program for Siemens phones S25, S35, S45, ME45, SL45
.SH SYNOPSIS
.B gsmsiexfer --help
.PP
.SH DESCRIPTION
\fIgsmsiexer\fP comes with no man page. Try gsmsiexfer --help, or
read the source.
.PP
.SH "SEE ALSO"
.BR gsminfo(7),
.BR gsmctl(1),
.BR gsmsendsms(1),
.BR gsmsmsd(8),
.BR gsmsmsstore(1).

View File

@ -0,0 +1,2 @@
doc/README.developers
doc/README.NLS

View File

@ -0,0 +1,137 @@
#!/usr/bin/make -f
# Sample debian/rules that uses debhelper.
# GNU copyright 1997 to 1999 by Joey Hess.
# Uncomment this to turn on verbose mode.
#export DH_VERBOSE=1
# shared library versions, option 1
#version=2.0.5
#major=2
# option 2, assuming the library is created as src/.libs/libfoo.so.2.0.5 or so
me_version=`ls gsmlib/.libs/libgsmme*.so.* | \
awk '{if (match($$0,/[0-9]+\.[0-9]+\.[0-9]+$$/)) print substr($$0,RSTART)}'`
me_major=`ls gsmlib/.libs/libgsmme*.so.* | \
awk '{if (match($$0,/\.so\.[0-9]+$$/)) print substr($$0,RSTART+4)}'`
ex_version=`ls ext/.libs/libgsmext*.so.* | \
awk '{if (match($$0,/[0-9]+\.[0-9]+\.[0-9]+$$/)) print substr($$0,RSTART)}'`
ex_major=`ls ext/.libs/libgsmext*.so.* | \
awk '{if (match($$0,/\.so\.[0-9]+$$/)) print substr($$0,RSTART+4)}'`
export DEB_HOST_GNU_TYPE ?= $(shell dpkg-architecture -qDEB_HOST_GNU_TYPE)
export DEB_BUILD_GNU_TYPE ?= $(shell dpkg-architecture -qDEB_BUILD_GNU_TYPE)
# FOR AUTOCONF 2.13 ONLY
ifeq ($(DEB_BUILD_GNU_TYPE), $(DEB_HOST_GNU_TYPE))
confflags += $(DEB_HOST_GNU_TYPE)
else
confflags += --host $(DEB_BUILD_GNU_TYPE) --build $(DEB_HOST_GNU_TYPE)
endif
ifneq (,$(findstring debug,$(DEB_BUILD_OPTIONS)))
CFLAGS += -g
CXXFLAGS += -g
endif
configure: configure-stamp
configure-stamp:
dh_testdir
# Add here commands to configure the package.
CFLAGS=$(CFLAGS) CXXFLAGS=$(CXXFLAGS) INSTALL_PROGRAM=$(INSTALL_PROGRAM) \
./configure $(confflags) --prefix=/usr --mandir=\$${prefix}/share/man \
--infodir=\$${prefix}/share/info
touch configure-stamp
build: configure-stamp build-stamp
build-stamp:
dh_testdir
# Add here commands to compile the package.
$(MAKE)
touch build-stamp
clean:
dh_testdir
dh_testroot
# Add here commands to clean up after the build process.
[ ! -f Makefile ] || $(MAKE) distclean
rm -f build-stamp configure-stamp config.log config.status po/de.gmo
-test -r /usr/share/misc/config.sub && \
cp -f /usr/share/misc/config.sub scripts/config.sub
-test -r /usr/share/misc/config.guess && \
cp -f /usr/share/misc/config.guess scripts/config.guess
dh_clean
install: build
dh_testdir
dh_testroot
dh_clean -k
dh_installdirs
dh_installdirs -pgsm-utils
# Add here commands to install the package into debian/gsmlib.
$(MAKE) install DESTDIR=$(CURDIR)/debian/tmp
chrpath -d debian/tmp/usr/bin/*
cp contrib/gsmsmsspool contrib/gsmsmsrequeue debian/tmp/usr/bin
cp contrib/gsm-utils.init contrib/gsm-utils.default debian
cp contrib/gsm-utils.cron.d debian
# Build architecture-independent files here.
binary-indep: build install
# We have nothing to do by default.
# Build architecture-dependent files here.
binary-arch: build install
dh_testdir
dh_testroot
#
# build libgsmlib${major} package by moving files from gsmlib-dev
#
dh_movefiles -plibgsmme$(me_major)c2a \
usr/lib/libgsmme.so.$(me_major) \
usr/lib/libgsmme.so.$(me_version) \
usr/lib/libgsmext.so.$(ex_major) \
usr/lib/libgsmext.so.$(ex_version) \
usr/share/locale
dh_movefiles -plibgsmme-dev \
usr/include \
usr/lib
dh_movefiles -pgsm-utils \
usr/bin
# dh_installdebconf
dh_installdocs
dh_installexamples
dh_installmenu
# dh_installemacsen
# dh_installpam
dh_installinit
dh_installcron
dh_installman -pgsm-utils debian/*.1 debian/tmp/usr/share/man/man*/*
dh_installinfo
dh_installchangelogs ChangeLog
dh_link
dh_strip
dh_compress
dh_fixperms
dh_makeshlibs -V
dh_installdeb
# dh_perl
dh_shlibdeps -ldebian/libgsmme1c2a/usr/lib
dh_gencontrol
dh_md5sums
dh_builddeb
binary: binary-indep binary-arch
.PHONY: build clean binary-indep binary-arch binary install configure

View File

@ -0,0 +1,2 @@
version=2
http://www.pxh.de/fs/gsmlib/download/content.html gsmlib-(.*)\.tar\.gz

View File

@ -0,0 +1,101 @@
*** 1. I get the error
/usr/local/bin/gsmsmsd [ERROR]: cannot route status report message to TE
Some phones/modems cannot route all kinds of SMS to the TE
(computer). Please try
gsmsmsd no_stat
This is documented in the gsmsmsd manual page.
*** 2. Siemens M20T expects an initial PIN.
For the Siemens M20T an initial PIN must be send once (probably when
it is switched on or the computer is powered on). This PIN is used for
all subsequent invocations of gsmlib-based programs. The trick is to
issue the following program (eg. in the rc-scripts of the operating system):
gsmctl -I "+cpin=<MY PIN>"
*** 3. Sending SMS with or retrieving SMS from my Ericsson SH888 does
not work.
Set the environment variable GSMLIB_SH888_FIX:
export GSMLIB_SH888_FIX=1 (bash)
setenv GSMLIB_SH888_FIX 1 (tcsh)
If it works now, I need your model number. You could just enter
"AT+CGMM" in a terminal program and send me the results. Alternatively
set the environment variable GSMLIB_DEBUG=2 and me the dump.
*** 4. I get the error "ME/TA error 'Unidentified subscriber' (code
28)" when trying to send SMS using gsmsendsms or gsmsmsd.
The SMS service centre address (SCA, the phone number of the centre that is
accepting SMS for delivery) is not set correctly in your phone. There
are three ways to correct this:
1. set the default SCA (example is for Germany T-D1):
gsmctl -o setsca "+491710760000"
2. Use the menus of your phone to set the SMS SCA.
3. Use the option "--sca 1234567" for the gsmsmsd, gsmsmsstore, and
gsmsendsms programs. This tries to set the SCA in the SMS itself (does
not change default SCA) and might not work with all phones.
*** 5. gsmlib works unreliably with my phone.
Try another baudrate, even higher baudrates sometimes work better then
lower ones.
*** 6. On Win32 accessing the COM device fails.
Use COMx: (x is the number of the COM device) instead of the UNIX
device name. If this doesn't work use "\\.\COMx:".
*** 7. Windows 2000 Does Not Support Mapping Virtual COM Ports to
Infrared Ports.
Windows 2000 users should follow the instructions in
support.microsoft.com article Q252795 in order to connect with their
mobile.
*** 8. gcc-compiled shared C++ libraries do not work properly on some
commercial UNIX systems and with older version of gcc.
The symptoms may be that the program dumps core on exceptions (AIX) or that
global constructors are not called (Solaris).
Try to compile gsmlib with
./configure --disable-shared --enable-static
if you encounter strange problems.
*** 9. How to support unicode?
You need 6 steps:
1. set datacodingschema to DCS_SIXTEEN_BIT_ALPHABET
2. set your locale correctly, for example, my locale, china.
setlocale(LC_ALL, "chs");
3. translate MBCS(multiple byte character set) string to unicode string.
wchar_t wstr[ 1000 ];
memset(wstr, 0, 2000);
mbstowcs(wstr, data.c_str(), data.length());
4. get unicode string length.
int wcs_len = wcslen(wstr);
5. change unicode string to net order.
for (int i = 0; i < wcs_len; i++)
wstr[ i ] = htons(wstr[ i ]);
6. put unicode string into pdu.

View File

@ -0,0 +1,33 @@
## Process this file with automake to produce Makefile.in
# *************************************************************************
# * GSM TA/ME library
# *
# * File: Makefile.am
# *
# * Purpose: doc Makefile
# *
# * Author: Peter Hofmann (software@pxh.de)
# *
# * Created: 11.6.1999
# *************************************************************************
man_MANS = gsmsmsd.8 gsmctl.1 gsmpb.1 gsmsendsms.1 gsmsmsstore.1 gsminfo.7
EXTRA_DIST = gsmsmsd.man gsmctl.man gsmpb.man gsmsendsms.man \
gsmsmsstore.man gsmlib.lsm gsminfo.man \
README.NLS README.developers FAQ
%.1: %.man
sed -e "s/##VERSION##/$(VERSION)/g;s/##DATE##/`date`/g" \
$< > $@
%.7: %.man
sed -e "s/##VERSION##/$(VERSION)/g;s/##DATE##/`date`/g" \
$< > $@
%.8: %.man
sed -e "s/##VERSION##/$(VERSION)/g;s/##DATE##/`date`/g" \
$< > $@
clean-local:
rm -f *.1 *.7 *.8

View File

@ -0,0 +1,412 @@
# Makefile.in generated by automake 1.6.3 from Makefile.am.
# @configure_input@
# Copyright 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002
# Free Software Foundation, Inc.
# This Makefile.in is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
# with or without modifications, as long as this notice is preserved.
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
# PARTICULAR PURPOSE.
@SET_MAKE@
# *************************************************************************
# * GSM TA/ME library
# *
# * File: Makefile.am
# *
# * Purpose: doc Makefile
# *
# * Author: Peter Hofmann (software@pxh.de)
# *
# * Created: 11.6.1999
# *************************************************************************
SHELL = @SHELL@
srcdir = @srcdir@
top_srcdir = @top_srcdir@
VPATH = @srcdir@
prefix = @prefix@
exec_prefix = @exec_prefix@
bindir = @bindir@
sbindir = @sbindir@
libexecdir = @libexecdir@
datadir = @datadir@
sysconfdir = @sysconfdir@
sharedstatedir = @sharedstatedir@
localstatedir = @localstatedir@
libdir = @libdir@
infodir = @infodir@
mandir = @mandir@
includedir = @includedir@
oldincludedir = /usr/include
pkgdatadir = $(datadir)/@PACKAGE@
pkglibdir = $(libdir)/@PACKAGE@
pkgincludedir = $(includedir)/@PACKAGE@
top_builddir = ..
ACLOCAL = @ACLOCAL@
AUTOCONF = @AUTOCONF@
AUTOMAKE = @AUTOMAKE@
AUTOHEADER = @AUTOHEADER@
am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
INSTALL = @INSTALL@
INSTALL_PROGRAM = @INSTALL_PROGRAM@
INSTALL_DATA = @INSTALL_DATA@
install_sh_DATA = $(install_sh) -c -m 644
install_sh_PROGRAM = $(install_sh) -c
install_sh_SCRIPT = $(install_sh) -c
INSTALL_SCRIPT = @INSTALL_SCRIPT@
INSTALL_HEADER = $(INSTALL_DATA)
transform = @program_transform_name@
NORMAL_INSTALL = :
PRE_INSTALL = :
POST_INSTALL = :
NORMAL_UNINSTALL = :
PRE_UNINSTALL = :
POST_UNINSTALL = :
host_alias = @host_alias@
host_triplet = @host@
EXEEXT = @EXEEXT@
OBJEXT = @OBJEXT@
PATH_SEPARATOR = @PATH_SEPARATOR@
AMTAR = @AMTAR@
AS = @AS@
AWK = @AWK@
BUILD_INCLUDED_LIBINTL = @BUILD_INCLUDED_LIBINTL@
CATOBJEXT = @CATOBJEXT@
CC = @CC@
CPP = @CPP@
CXX = @CXX@
DATADIRNAME = @DATADIRNAME@
DEPDIR = @DEPDIR@
DLLTOOL = @DLLTOOL@
ECHO = @ECHO@
GENCAT = @GENCAT@
GLIBC21 = @GLIBC21@
GMSGFMT = @GMSGFMT@
GSM_VERSION = @GSM_VERSION@
HAVE_LIB = @HAVE_LIB@
INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
INSTOBJEXT = @INSTOBJEXT@
INTLBISON = @INTLBISON@
INTLLIBS = @INTLLIBS@
INTLOBJS = @INTLOBJS@
INTL_LIBTOOL_SUFFIX_PREFIX = @INTL_LIBTOOL_SUFFIX_PREFIX@
LIB = @LIB@
LIBICONV = @LIBICONV@
LIBINTL = @LIBINTL@
LIBTOOL = @LIBTOOL@
LN_S = @LN_S@
LTLIB = @LTLIB@
LTLIBICONV = @LTLIBICONV@
LTLIBINTL = @LTLIBINTL@
MKINSTALLDIRS = @MKINSTALLDIRS@
OBJDUMP = @OBJDUMP@
PACKAGE = @PACKAGE@
POSUB = @POSUB@
RANLIB = @RANLIB@
STRIP = @STRIP@
USE_INCLUDED_LIBINTL = @USE_INCLUDED_LIBINTL@
USE_NLS = @USE_NLS@
VERSION = @VERSION@
am__include = @am__include@
am__quote = @am__quote@
install_sh = @install_sh@
man_MANS = gsmsmsd.8 gsmctl.1 gsmpb.1 gsmsendsms.1 gsmsmsstore.1 gsminfo.7
EXTRA_DIST = gsmsmsd.man gsmctl.man gsmpb.man gsmsendsms.man \
gsmsmsstore.man gsmlib.lsm gsminfo.man \
README.NLS README.developers FAQ
subdir = doc
mkinstalldirs = $(SHELL) $(top_srcdir)/scripts/mkinstalldirs
CONFIG_HEADER = $(top_builddir)/gsm_config.h
CONFIG_CLEAN_FILES =
DIST_SOURCES =
NROFF = nroff
MANS = $(man_MANS)
DIST_COMMON = Makefile.am Makefile.in
all: all-am
.SUFFIXES:
$(srcdir)/Makefile.in: Makefile.am $(top_srcdir)/configure.in $(ACLOCAL_M4)
cd $(top_srcdir) && \
$(AUTOMAKE) --gnu doc/Makefile
Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)
mostlyclean-libtool:
-rm -f *.lo
clean-libtool:
-rm -rf .libs _libs
distclean-libtool:
-rm -f libtool
uninstall-info-am:
man1dir = $(mandir)/man1
install-man1: $(man1_MANS) $(man_MANS)
@$(NORMAL_INSTALL)
$(mkinstalldirs) $(DESTDIR)$(man1dir)
@list='$(man1_MANS) $(dist_man1_MANS) $(nodist_man1_MANS)'; \
l2='$(man_MANS) $(dist_man_MANS) $(nodist_man_MANS)'; \
for i in $$l2; do \
case "$$i" in \
*.1*) list="$$list $$i" ;; \
esac; \
done; \
for i in $$list; do \
if test -f $(srcdir)/$$i; then file=$(srcdir)/$$i; \
else file=$$i; fi; \
ext=`echo $$i | sed -e 's/^.*\\.//'`; \
case "$$ext" in \
1*) ;; \
*) ext='1' ;; \
esac; \
inst=`echo $$i | sed -e 's/\\.[0-9a-z]*$$//'`; \
inst=`echo $$inst | sed -e 's/^.*\///'`; \
inst=`echo $$inst | sed '$(transform)'`.$$ext; \
echo " $(INSTALL_DATA) $$file $(DESTDIR)$(man1dir)/$$inst"; \
$(INSTALL_DATA) $$file $(DESTDIR)$(man1dir)/$$inst; \
done
uninstall-man1:
@$(NORMAL_UNINSTALL)
@list='$(man1_MANS) $(dist_man1_MANS) $(nodist_man1_MANS)'; \
l2='$(man_MANS) $(dist_man_MANS) $(nodist_man_MANS)'; \
for i in $$l2; do \
case "$$i" in \
*.1*) list="$$list $$i" ;; \
esac; \
done; \
for i in $$list; do \
ext=`echo $$i | sed -e 's/^.*\\.//'`; \
inst=`echo $$i | sed -e 's/\\.[0-9a-z]*$$//'`; \
inst=`echo $$inst | sed -e 's/^.*\///'`; \
inst=`echo $$inst | sed '$(transform)'`.$$ext; \
echo " rm -f $(DESTDIR)$(man1dir)/$$inst"; \
rm -f $(DESTDIR)$(man1dir)/$$inst; \
done
man7dir = $(mandir)/man7
install-man7: $(man7_MANS) $(man_MANS)
@$(NORMAL_INSTALL)
$(mkinstalldirs) $(DESTDIR)$(man7dir)
@list='$(man7_MANS) $(dist_man7_MANS) $(nodist_man7_MANS)'; \
l2='$(man_MANS) $(dist_man_MANS) $(nodist_man_MANS)'; \
for i in $$l2; do \
case "$$i" in \
*.7*) list="$$list $$i" ;; \
esac; \
done; \
for i in $$list; do \
if test -f $(srcdir)/$$i; then file=$(srcdir)/$$i; \
else file=$$i; fi; \
ext=`echo $$i | sed -e 's/^.*\\.//'`; \
case "$$ext" in \
7*) ;; \
*) ext='7' ;; \
esac; \
inst=`echo $$i | sed -e 's/\\.[0-9a-z]*$$//'`; \
inst=`echo $$inst | sed -e 's/^.*\///'`; \
inst=`echo $$inst | sed '$(transform)'`.$$ext; \
echo " $(INSTALL_DATA) $$file $(DESTDIR)$(man7dir)/$$inst"; \
$(INSTALL_DATA) $$file $(DESTDIR)$(man7dir)/$$inst; \
done
uninstall-man7:
@$(NORMAL_UNINSTALL)
@list='$(man7_MANS) $(dist_man7_MANS) $(nodist_man7_MANS)'; \
l2='$(man_MANS) $(dist_man_MANS) $(nodist_man_MANS)'; \
for i in $$l2; do \
case "$$i" in \
*.7*) list="$$list $$i" ;; \
esac; \
done; \
for i in $$list; do \
ext=`echo $$i | sed -e 's/^.*\\.//'`; \
inst=`echo $$i | sed -e 's/\\.[0-9a-z]*$$//'`; \
inst=`echo $$inst | sed -e 's/^.*\///'`; \
inst=`echo $$inst | sed '$(transform)'`.$$ext; \
echo " rm -f $(DESTDIR)$(man7dir)/$$inst"; \
rm -f $(DESTDIR)$(man7dir)/$$inst; \
done
man8dir = $(mandir)/man8
install-man8: $(man8_MANS) $(man_MANS)
@$(NORMAL_INSTALL)
$(mkinstalldirs) $(DESTDIR)$(man8dir)
@list='$(man8_MANS) $(dist_man8_MANS) $(nodist_man8_MANS)'; \
l2='$(man_MANS) $(dist_man_MANS) $(nodist_man_MANS)'; \
for i in $$l2; do \
case "$$i" in \
*.8*) list="$$list $$i" ;; \
esac; \
done; \
for i in $$list; do \
if test -f $(srcdir)/$$i; then file=$(srcdir)/$$i; \
else file=$$i; fi; \
ext=`echo $$i | sed -e 's/^.*\\.//'`; \
case "$$ext" in \
8*) ;; \
*) ext='8' ;; \
esac; \
inst=`echo $$i | sed -e 's/\\.[0-9a-z]*$$//'`; \
inst=`echo $$inst | sed -e 's/^.*\///'`; \
inst=`echo $$inst | sed '$(transform)'`.$$ext; \
echo " $(INSTALL_DATA) $$file $(DESTDIR)$(man8dir)/$$inst"; \
$(INSTALL_DATA) $$file $(DESTDIR)$(man8dir)/$$inst; \
done
uninstall-man8:
@$(NORMAL_UNINSTALL)
@list='$(man8_MANS) $(dist_man8_MANS) $(nodist_man8_MANS)'; \
l2='$(man_MANS) $(dist_man_MANS) $(nodist_man_MANS)'; \
for i in $$l2; do \
case "$$i" in \
*.8*) list="$$list $$i" ;; \
esac; \
done; \
for i in $$list; do \
ext=`echo $$i | sed -e 's/^.*\\.//'`; \
inst=`echo $$i | sed -e 's/\\.[0-9a-z]*$$//'`; \
inst=`echo $$inst | sed -e 's/^.*\///'`; \
inst=`echo $$inst | sed '$(transform)'`.$$ext; \
echo " rm -f $(DESTDIR)$(man8dir)/$$inst"; \
rm -f $(DESTDIR)$(man8dir)/$$inst; \
done
tags: TAGS
TAGS:
DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
top_distdir = ..
distdir = $(top_distdir)/$(PACKAGE)-$(VERSION)
distdir: $(DISTFILES)
@list='$(DISTFILES)'; for file in $$list; do \
if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
dir=`echo "$$file" | sed -e 's,/[^/]*$$,,'`; \
if test "$$dir" != "$$file" && test "$$dir" != "."; then \
dir="/$$dir"; \
$(mkinstalldirs) "$(distdir)$$dir"; \
else \
dir=''; \
fi; \
if test -d $$d/$$file; then \
if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \
fi; \
cp -pR $$d/$$file $(distdir)$$dir || exit 1; \
else \
test -f $(distdir)/$$file \
|| cp -p $$d/$$file $(distdir)/$$file \
|| exit 1; \
fi; \
done
check-am: all-am
check: check-am
all-am: Makefile $(MANS)
installdirs:
$(mkinstalldirs) $(DESTDIR)$(man1dir) $(DESTDIR)$(man7dir) $(DESTDIR)$(man8dir)
install: install-am
install-exec: install-exec-am
install-data: install-data-am
uninstall: uninstall-am
install-am: all-am
@$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
installcheck: installcheck-am
install-strip:
$(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
INSTALL_STRIP_FLAG=-s \
`test -z '$(STRIP)' || \
echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install
mostlyclean-generic:
clean-generic:
distclean-generic:
-rm -f Makefile $(CONFIG_CLEAN_FILES)
maintainer-clean-generic:
@echo "This command is intended for maintainers to use"
@echo "it deletes files that may require special tools to rebuild."
clean: clean-am
clean-am: clean-generic clean-libtool clean-local mostlyclean-am
distclean: distclean-am
distclean-am: clean-am distclean-generic distclean-libtool
dvi: dvi-am
dvi-am:
info: info-am
info-am:
install-data-am: install-man
install-exec-am:
install-info: install-info-am
install-man: install-man1 install-man7 install-man8
installcheck-am:
maintainer-clean: maintainer-clean-am
maintainer-clean-am: distclean-am maintainer-clean-generic
mostlyclean: mostlyclean-am
mostlyclean-am: mostlyclean-generic mostlyclean-libtool
uninstall-am: uninstall-info-am uninstall-man
uninstall-man: uninstall-man1 uninstall-man7 uninstall-man8
.PHONY: all all-am check check-am clean clean-generic clean-libtool \
clean-local distclean distclean-generic distclean-libtool \
distdir dvi dvi-am info info-am install install-am install-data \
install-data-am install-exec install-exec-am install-info \
install-info-am install-man install-man1 install-man7 \
install-man8 install-strip installcheck installcheck-am \
installdirs maintainer-clean maintainer-clean-generic \
mostlyclean mostlyclean-generic mostlyclean-libtool uninstall \
uninstall-am uninstall-info-am uninstall-man uninstall-man1 \
uninstall-man7 uninstall-man8
%.1: %.man
sed -e "s/##VERSION##/$(VERSION)/g;s/##DATE##/`date`/g" \
$< > $@
%.7: %.man
sed -e "s/##VERSION##/$(VERSION)/g;s/##DATE##/`date`/g" \
$< > $@
%.8: %.man
sed -e "s/##VERSION##/$(VERSION)/g;s/##DATE##/`date`/g" \
$< > $@
clean-local:
rm -f *.1 *.7 *.8
# Tell versions [3.59,3.63) of GNU make to not export all variables.
# Otherwise a system limit (for SysV at least) may be exceeded.
.NOEXPORT:

View File

@ -0,0 +1,72 @@
0 Introduction
--------------
This version of gsmlib contains national language support (NLS) using
the GNU (or OS-supplied) gettext library. gettext eases the handling
of translations of (usually english) output messages to other
languages by introducing the concept of message catalogs.
Message catalogs can exist in various formats. The human-readable and
-editable format is the PO file format. I have written a PO-file for
the german language (de.po). These human-readable files are then
translated to MO files which can be used by the gettext library.
Please refer to the GNU gettext documentation (at the time of this
writing gettext-0.10) for further details.
1 Compiling gsmlib with localized messages
------------------------------------------
Gsmlib is compiled by default with NLS enabled. If you don't want
NLS invoke configure with the option
./configure --disable-nls
2 Adding new message dialogs
----------------------------
1. Edit the ALL_LINGUAS line in "source/configure.in" and add your
language, eg. French:
ALL_LINGUAS="de fr"
2. Execute "autoconf" to create a new "configure" script (possible
problem: incompatible "autoconf")
3. Now issue "./configure" in the "sources" directory.
4. go to the "po" subdirectory
5. do a "touch fr.po" to create an initially empty PO-file.
6. do a "make update-po". This extracts all the strings from the files
listed in "POTFILES" and puts them with empty translations into "fr.po"
(it also updates existing po-Files such as "de.po").
7. Now use the editor of your choice to provide translations in
"fr.po". There is an emacs major mode (po-mode) that eases this
process.
8. now issue "make". This causes an "fr.mo" to be created.
3 Adding new strings to gsmlib source code
------------------------------------------
1. If you add new strings to the gsmlib source code that need
translation enclose them with "_(" and ")" (see gettext documentation
for special cases).
2. go to the "po" directory.
3. do a "make update-po". This updates all existing PO-files (removing
obsolete translations, providing new, emptry entries).
4. Provide translations for the new, empty entries (ideally using
emacs po-mode)
5. now issue "make". This causes up-to-date MO-files to be created.

View File

@ -0,0 +1,138 @@
OVERVIEW
The GSM library is written in C++ and uses the latest C++
features: namespaces, exceptions, the standard template library.
The actual library source code is in the gsmlib subdirectory of
this distribution. The following modules are available:
gsm_alloca.h OS-specific alloca defines
gsm_at.h Utility classes for AT command sequence handling
gsm_error.h Error codes and error handling functions
gsm_event.h Event handler interface
gsm_me_ta.h Mobile Equipment/Terminal Adapter and SMS functions
(ETSI GSM 07.07 and 07.05)
gsm_parser.h Parser to parse MA/TA result strings
gsm_phonebook.h Phonebook management functions
gsm_port.h Abstract port definition
gsm_sms.h SMS functions (ETSI GSM 07.05)
gsm_sms_codec.h Coder and Encoder for SMS TPDUs
gsm_sms_store.h SMS functions, SMS store (ETSI GSM 07.05)
gsm_sorted_phonebook.h Alphabetically sorted phonebook
(residing in files or in the ME)
gsm_sorted_sms_store.h Sorted SMS store
(sorted by address, time or type)
(residing in files or in the ME)
gsm_unix_serial.h UNIX serial port implementation
gsm_util.h Various utilities
REQUIREMENTS
I have used egcs-1.1.2 and libstdc++.so.2.8.0 for compiling the
library and all programs. Older probably don't work because of
missing features.
AVAILABLE DOCUMENTATION
If you want to do your own programming using the GSM library please
refer to the extensively documented header files or to the example
programs in the test or apps subdirectory.
I have used the following documentation to develop this software:
gts_gsm_02.30_v5.2.0.pdf
gts_gsm_03.40_v5.3.0.pdf
gts_gsm_04.11_v5.1.0.pdf
gts_gsm_02.82_v5.0.0.pdf
gts_gsm_03.41_v5.2.0.pdf
gts_gsm_07.05_v5.3.0.pdf
gts_gsm_03.38_v5.3.0.pdf
gts_gsm_04.08_v5.1.0.pdf
gts_gsm_07.07_v5.0.0.pdf
Due to copyright reasons I cannot include this documentation in
this distribution. You can download it from the ETSI website
(www.etsi.org) for free, though.
COMPILATION
The code is automatically compiled without debugging code enabled
(mostly assert()'s).
If there are any problems you can generate a debug version
by issuing
CXXFLAGS="-g" ./configure --disable-shared
To switch on asserts and additional debugging output change the line
CXXFLAGS="-DNEBUG $CXXFLAGS"
in configure.in do
dnl CXXFLAGS="-DNEBUG $CXXFLAGS"
Then regenerate configure by executing autoconf.
You must use at least gcc-2.95.2 to compile gsmlib successfully.
TESTS
The tests directory contains a number of software tests. Two kinds
of test programs are provided: Those, that run without a mobile
phone and those that require a mobile phone to be connected to a
serial port.
No access to mobile phone needed:
runparser.sh Test the parser for AT responses
runsms.sh Test SMS message encoding and decoding routines
runspb.sh Test sorted phonebook module
runssms.sh Test sorted SMS store module
Give mobile phone device as argument:
testsms2 Manipulate SMS store in the mobile phone (read/write)
testgsmlib Test the gsm_me_ta module (readonly)
testpb Dump all phonebooks in the mobile phone to the stdout
(readonly)
testpb2 Manipulate phonebook in the mobile phone (read/write)
The tests that do not require a mobile phone can be executed by
issuing "make check" in the tests subdirectory. The others must be
invoked manually. WARNING: These tests alter the contents of the
mobile phone's phonebook or SMS message memory!!! Make sure, that
you understand what the test does and be prepared for loss of data in
the mobile phone.
HINTS
- By default gsmlib is compiled with NDEBUG set. There are lots
of assert()s all over the library that may help to find problems
in programs that use the library. Disable NDEBUG to get best
debugging support.
CUSTOM BACKENDS
gsmlib now allows custom backends to be defined for sorted phonebooks
and sorted SMS stores. This can be used to store phonebook entries in
relational databases or LDAP servers. The interfaces are defined in
gsm_sorted_phonebook_base.h and gsm_sorted_sms_store_base.h,
respectively.
To register a custom backend (eg. for sorted phonebooks) follow
these steps:
1. Define a subclass of CustomPhonebookFactory.
2. Define a static initializer class in your module that uses the
interface CustomPhonebookRegistry::registerCustomPhonebookFactory()
to make your custom backend available.
3. Link your module to any application that should use your custom
backend. The gsmpb and gsmsmsstore programs are prepared to use the
CustomPhonebookRegistry class to obtain your custom backend
objects.

View File

@ -0,0 +1,683 @@
.TH GSMCTL 8 "##DATE##" "gsmctl v##VERSION##"
.SH NAME
gsmctl, gsmsiectl \- GSM mobile phone control program
.SH SYNOPSIS
.B gsmctl
.RB [\| \-b
.IR baudrate \|]
.RB [\| \-\-baudrate
.IR baudrate\| ]
.RB [ \|\-d
.IR device\| ]
.RB [ \|\-\-device
.IR device\fP ]
.RB [ \|\-h\| ]
.RB [ \|\-\-help\| ]
.RB [ \|\-I
.IR "init string" \|]
.RB [ \|\-\-init
.IR "init string" \|]
.RB [ \|\-v\| ]
.RB [ \|\-\-version\| ]
.RB [ \|\-X\| ]
.RB [ \|\-\-xonxoff\| ]
.BI \-o \ operation
.RB | \ \-\-operation
.IR operation \ |
.I parameters
.PP
.B gsmsiectl
.RB [\| \-b
.IR baudrate \|]
.RB [\| \-\-baudrate
.IR baudrate\| ]
.RB [ \|\-d
.IR device\| ]
.RB [ \|\-\-device
.IR device\fP ]
.RB [ \|\-h\| ]
.RB [ \|\-\-help\| ]
.RB [ \|\-I
.IR "init string" \|]
.RB [ \|\-\-init
.IR "init string" \|]
.RB [ \|\-v\| ]
.RB [ \|\-\-version\| ]
.RB [ \|\-X\| ]
.RB [ \|\-\-xonxoff\| ]
.BI \-o \ operation
.RB | \ \-\-operation
.IR operation \ |
.I parameters
.SH DESCRIPTION
.B gsmctl
can request information from or perform operations on an GSM mobile
phone.
.PP
.B gsmctl
attaches itself to the
.I device
given on the command line (usually an GSM modem) using the specified
.IR baudrate .
If no
.I device
is given, the device
.I/dev/mobilephone
is used. If no
.I baudrate
is given, a default baud rate of 38400 is used.
.PP
.B gsmctl
can be used in to modes: If no
.B \-\-operation
option is given the
.I parameters
specify the status information to be retrieved from
the mobile phone. See the section
.B STATUS INFORMATION
for more details. If an
.B \-\-operation
option is given the requested
.I operation
is performed on the mobile using the
.IR parameters .
See the section
.B OPERATIONS
for more details.
.PP
.B gsmsiectl
is the same program with some extension for Siemens mobile phones.
Some extra
.B OPERATIONS
are available in this case.
.PP
Error messages are printed to the standard error output. If the
program terminates on error the error code 1 is returned.
.SH OPTIONS
.TP
.BI \-b\ baudrate ,\ \-\-baudrate\ baudrate
The baud rate to use. Defaults to 38400.
.TP
.BI \-d\ device ,\ \-\-device\ device
The device to which the GSM modem is connected. The default is
.IR /dev/mobilephone .
.TP
.B \-h,\ \-\-help
Prints an option summary.
.TP
.BI \-I\ "init string" ,\ \-\-init\ "init string"
Initialization string to send to the TA (default: "E0"). Note that the
sequence "ATZ" is sent first.
.TP
.BI \-o\ operation ,\ \-\-operation\ operation
This option is used to perform an operation on the mobile phone. Refer
to the section
.B OPERATIONS
for more information on the available
operations and the
.I parameters
required for each operation.
.TP
.B \-v,\ \-\-version
Prints the program version.
.TP
.B \-X,\ \-\-xonxoff
Uses software handshaking (XON/XOFF) for accessing the device.
.SH STATUS INFORMATION
If called without the
.B \-\-operation
option
.B gsmctl
prints out default mobile phone status information as specified by the
.I parameters
described below:
.TP 7
.B ALL
Prints all available information.
.TP 7
.B BATT
Prints out information about the current battery status. Two lines of
the form "<BATT0> text" and "<BATT1> charge" are printed. Text may be
of "0 ME is powered by the battery", "1 ME has a battery connected,
but is not powered by it", "2 ME does not have a battery connected",
or "3 Recognized power fault, calls inhibited". Charge is a number in
the range 0..100 where 0 means that the battery is empty or not
connected and 100 means full charge.
.TP 7
.B BITERR
Prints information about the current bit error rate. The output is of
form "<BITERR0> value" where value can be of 0..7, 99 (99 means not
available or not detectable).
.TP 7
.B CLIP
This option prints a line of the form "<CLIP0> on" if caller line
identification is turned on in the network, "<CLIP0> off" otherwise.
.TP 7
.B CSET
Display info about charsets. The output is in the form "<CSET0>
available" and "<CSET1> current", which describes the charsets
available and which is current.
.TP 7
.B CURROP
Prints information about the current operator. The output line has the
form "<CURROP0> Long name: \'xxxx\' Short name: \'yyyy\' Numeric Name: zzzz".
.TP 7
.B FLCAP
Prints out the two-letter names of available facility locks. The
meaning of standardized facility lock names is as follows:
.RS
.TP 3
.I CS
Lock control surface (eg. phone keyboard)
.TP 3
.I PS
Lock phone to SIM card (mobile phone asks password when other than
current SIM card inserted)
.TP 3
.I SC
Lock SIM card (SIM asks password in mobile phone power-up and when
this lock command issued)
.TP 3
.I AO
Barr all outgoing calls
.TP 3
.I OI
Barr outgoing international calls
.TP 3
.I OX
Barr outgoing international calls except to home country
.TP 3
.I AI
Barr all incoming calls
.TP 3
.I IR
Barr incoming calls when roaming outside the home country
.TP 3
.I NT
Barr incoming calls from numbers not stored to TA memory
.TP 3
.I NM
Barr incoming calls from numbers not stored to mobile phone memory
.TP 3
.I NS
Barr incoming calls from numbers not stored to SIM memory
.TP 3
.I NA
Barr incoming calls from numbers not stored in Any memory
.TP 3
.I AB
All Barring services (FIXME)
.TP 3
.I AG
All outGoing barring services (FIXME)
.TP 3
.I AC
All inComing barring services (FIXME)
.TP 3
.I FD
SIM fixed dialling memory feature (if PIN2 authentication has not been
done during the current session, PIN2 is required as <passwd>)
.PP
Note that mobile phones may implement facility locks not documented
here.
.RE
.TP 7
.B FLSTAT
Prints information about the status of facility locking in the mobile
phone. For each facility a line of the form "<FLSTATn> \'facilityname\'
classes" is printed. The classes may be "Voice", "Data", and/or "Fax"
depending on the class for which the facility is enabled. If "unknown"
is printed out this means that the TA is not able to report the
status. If the facility is not enabled for any class, no class
identifier is printed. See
.B FLCAP
for information about the available two-letter names of facility
locks.
.TP 7
.B FORW
Prints information about call forwarding enabled in the mobile
phone. For each combination of reason (UnconditionalReason,
MobileBusyReason, NoReplyReason, and NotReachableReason) and class
(Voice, Data, and Fax) a line of the form "<FORWn.m> reason class
number: xxx subaddr: yyy time: zzz" is printed. The time is the number
of seconds to wait before forwarding in case of NoReplyReason.
.TP 7
.B ME
Prints manufacturer, model, revision, and serial number of
the mobile phone (ME = mobile equipment). Output lines are numbered from
"<ME0>" to "<ME3>".
.TP 7
.B OP
Prints information about the currently available mobile network
operators. For each operator an output line of the form "<OPn> status
Long name: \'xxxx\' Short name: \'yyyy\' Numeric name: zzz" is returned
where status may be of:
.RS
.TP 10
.I unknown
The status of the operator is unknown.
.TP
.I current
This is the currently selected operator.
.TP
.I available
This operator is available for selection.
.TP
.I forbidden
This operator is not available for selection, ie. not
accessible with this SIM card.
.RE
.TP 7
.B PIN
Prints information about the current PIN status. The output is of
form "<PIN0> status". Where status can be one of the following lines:
.RS
.TP 10
.I READY
ME is not pending for any password.
.TP
.I SIM PIN
ME is waiting SIM PIN to be given.
.TP
.I SIM PUK
ME is waiting SIM PUK to be given.
.TP
.I PH-SIM PIN
ME is waiting phone-to-SIM card password to be given.
.TP
.I PH-FSIM PIN
ME is waiting phone-to-very first SIM card password to be given.
.TP
.I PH-FSIM PUK
ME is waiting phone-to-very first SIM card unblocking password to be
given.
.TP
.I SIM PIN2
ME is waiting SIM PIN2 to be given.
.TP
.I SIM PUK2
ME is waiting SIM PUK2 to be given.
.TP
.I PH-NET PIN
ME is waiting network personalisation password to be given.
.TP
.I PH-NET PUK
ME is waiting network personalisation unblocking password to be given.
.TP
.I PH-NETSUB PIN
ME is waiting network subset personalisation password to be given.
.RE
.TP 7
.B PW
Facilities in the mobile phone may be protected by passwords (ie. PINs
or PUKs). This option prints out lines of the form "<PWn>
\'facilityname\' len" for each facility for which a facility lock
password exists. See
.B FLCAP
for information about the available two-letter names of facility
locks.
.TP 7
.B SCA
Reports the default SMS service centre address currently set in the
mobile phone.
.TP 7
.B SIG
Prints information about the current network signal
strength. The output is of the form "<SIG0> value". Following values
are possible:
.TP
.po +7
.I 0
-113 dBm or less
.TP
.I 1
-111 dBm
.TP
.I 2...30
-109... -53 dBm (in steps of 2 dBm)
.TP
.I 31
-51 dBm or greater
.TP
.I 99
not known or not detectable
.PP
.po
.SH OPERATIONS
.TP
.BI dial\ number
Dials
.IR number .
After dialling
.B gsmctl
waits for a <CR> keypress to terminate.
.PP
.B forw
.IR mode\ reason\ number\ [\| facilityclass\| ]\ [ forwardtime ]
.RS
Changes the call forwarding behaviour in the network.
.I mode
can be any of:
.RS 3
.I disable
Call forwarding is disabled.
.PP
.I enable
Call forwarding is enabled. The call forwarding reason, number, and
(optionally) forwardtime must be registered beforehand.
.PP
.I register
This registers the call forwarding reason, number, and forwardtime in
the network.
.PP
.I erase
This is the counterpart to register. It erase the call forwarding info
in the network.
.RE
.PP
.I reason
can be any of:
.RS 3
.I unconditional
This applies to every call.
.PP
.I mobilebusy
The mobile phone is busy.
.PP
.I noreply
The call is not answered in \fIforwardtime\fP seconds.
.PP
.I notreachable
Mobile phone cannot be reached (ie. switched off).
.PP
.I all
This refers to all forwarding reasons.
.PP
.I allconditional
This refers to all conditional forward reasons
.RI ( mobilebusy ,\ noreply ,\ notreachable ).
.RE
.PP
.I number
is the number the incoming call is forwarded to. See the explanation
for
.I lock
operation for the meaning of
.IR facilityclass .
The default for
.I forwardtime
is 20 seconds if omitted.
.I forwardtime
can be in the range 1..30.
.RE
.PP
.TP
.BI off
Sets functionality level of the phone to 0 (low functionality). The
effects of this command depend on the phone (eg. sets low power
consumption).
.PP
.TP
.BI on
Sets functionality level of the phone to 1 (high functionality). The
effects of this command depend on the phone.
.PP
.TP
.BI pin\ pin
Sets PIN code. Use
.BI gsmctl\ pin
to get the current pin status.
.PP
.B lock
.IR facility\ [\| facilityclass \|]\ [\| passwd \|]
.RS
Locks the named facility. Use
.BI gsmctl\ flcap
to get a list of supported facilities. The
.I facilityclass
can be any of:
.RS 3
.I all
Voice, data, and fax.
.PP
.I v\ vf\ vd\ f\ fd\ d
Any combination of voice, data and fax.
.RE
.PP
The default is \fIall\fP if \fIfacilityclass\fP is omitted. The
\fIpasswd\fP is password for the facility. If no password is given
this parameter can be omitted.
.RE
.PP
.BI setop\ opmode\ numericname
.RS
Sets the current operator to
.IR numericname .
Use
.BI gsmctl\ op
to get a list of operators with their numeric codes.
.I opmode
can be any of:
.RS 3
.I automatic
.PP
.I manual
.PP
.I deregister
Deregister from network.
.PP
.I manualautomatic
If manual selection fails, automatic mode is entered.
.RE
.RE
.PP
.B setpw
.IR facility\ [\| oldpasswd\| ]\ [\| newpasswd\| ]
.RS
Sets the password for the facility. If one of the passwords is omitted
this means that the facility has no password protection. Passwords are
PIN1, PIN2, PUK etc.
.RE
.TP
.BI setsca\ service\ centre\ address
Sets the default SMS service centre address.
.PP
.B unlock
.IR facility\ [\| facilityclass\| ]\ [ \|passwd\| ]
.RS
This is the reverse operation to \fBlock\fP. See above for a
description of the parameters.
.RE
.PP
.B Extra operators for gsmsiectl:
.PP
.B cset
.RS
Charset info.
.RE
.PP
.B pbook
.RS
Phone book info.
.RE
.PP
.B signal
.RS
Signal tone info.
.RE
.PP
.B ring
.RS
Ringing tone info.
.RE
.PP
.B binary
.RS
Binary info.
.RE
.SH EXAMPLES
The following invocation of
.I gsmctl
prints out all available status information for the mobile phone
connected to
.B /dev/mobilephone
.PP
.nf
.IP "" 3
gsmctl all
.fi
.PP
The output could look like (lines edited to fit):
.RS 3
.PP
.PD 0
<ME0> Manufacturer: SIEMENS
.HP
<ME1> Model: S10
.HP
<ME2> Revision: 06
.HP
<ME3> Serial Number: 448058511817585
.HP
<OP0> Status: available Long name: 'D1-TELEKOM' Short name: '' Numeric name: 26201
.HP
<OP1> Status: forbidden Long name: 'D2 PRIVAT' Short name: '' Numeric name: 26202
.HP
<CURROP0> Long name: 'D1-TELEKOM' Short name: '' Numeric name: 26201 Mode: automatic
.HP
<FLSTAT0> 'CS'
.HP
<FLSTAT1> 'PS'
.HP
<FLSTAT2> 'SC' Voice Data Fax
.HP
<FLSTAT3> 'AO'
.HP
<FLSTAT4> 'OI'
.HP
<FLSTAT5> 'OX'
.HP
<FLSTAT6> 'AI'
.HP
<FLSTAT7> 'IR'
.HP
<FLCAP0> 'CS' 'PS' 'SC' 'AO' 'OI' 'OX' 'AI' 'IR' 'AB' 'AG' 'AC'
.HP
<PW0> 'PS' 8
.HP
<PW1> 'SC' 8
.HP
<PW2> 'AO' 4
.HP
<PW3> 'OI' 4
.HP
<PW4> 'OX' 4
.HP
<PW5> 'AI' 4
.HP
<PW6> 'IR' 4
.HP
<PW7> 'AB' 4
.HP
<PW8> 'AG' 4
.HP
<PW9> 'AC' 4
.HP
<CLIP0> on
.HP
<FORW0.0> UnconditionalReason Voice inactive number: subaddr: time: -1
.HP
<FORW0.1> UnconditionalReason Data inactive number: subaddr: time: -1
.HP
<FORW0.2> UnconditionalReason Fax inactive number: subaddr: time: -1
.HP
<FORW1.0> MobileBusyReason Voice active number: +494012345678 subaddr: time: -1
.HP
<FORW1.1> MobileBusyReason Data inactive number: subaddr: time: -1
.HP
<FORW1.2> MobileBusyReason Fax inactive number: subaddr: time: -1
.HP
<FORW2.0> NoReplyReason Voice active number: +494012345678 subaddr: time: 20
.HP
<FORW2.1> NoReplyReason Data inactive number: subaddr: time: -1
.HP
<FORW2.2> NoReplyReason Fax inactive number: subaddr: time: -1
.HP
<FORW3.0> NotReachableReason Voice active number: +494012345678 subaddr: time: -1
.HP
<FORW3.1> NotReachableReason Data inactive number: subaddr: time: -1
.HP
<FORW3.2> NotReachableReason Fax inactive number: subaddr: time: -1
.HP
<BATT0> 0 ME is powered by the battery
.HP
<BATT1> 100
.HP
<BITERR0> 0
.HP
<SIG0> 19
.RE
.PD
.PP
The following locks the keys on the mobile phone:
.nf
.IP "" 3
gsmctl -o lock cs
.fi
.PP
This changes the SIM card PIN from 1234 to 2345:
.nf
.IP "" 3
gsmctl -o setpw sc 1234 2345
.fi
.PP
Switch off all call forwarding (actually erase the numbers):
.nf
.IP "" 3
gsmctl -o forw erase all
.fi
.PP
Switch on call forwarding to German D1 voice box:
.nf
.IP "" 3
gsmctl -o forw register notreachable 3313
gsmctl -o forw enable notreachable
.fi
.PP
.SH FILES
.TP
.B /dev/mobilephone
Default mobile phone device.
.SH AUTHOR
Peter Hofmann <software@pxh.de>
.SH BUGS
Report bugs to software@pxh.de. Include a complete, self-ncontained
example that will allow the bug to be reproduced, and say which
version of \fIgsmctl\fP you are using.
.SH COPYRIGHT
Copyright \(co 1999 Peter Hofmann
.PP
.B gsmctl
is free software; you can redistribute it and/or modify it under the
terms of the GNU Library General Public License as published by the
Free Software Foundation; either version 2, or (at your option) any
later version.
.PP
.B gsmctl
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 Library General Public
License for more details.
.PP
You should have received a copy of the GNU Library General Public
License along with
.BR gsmctl ;
see the file COPYING. If not, write to the Free Software Foundation,
675 Mass Ave, Cambridge, MA 02139, USA.
.SH "SEE ALSO"
.BR gsminfo (7),
.BR gsmpb (1),
.BR gsmsendsms (1),
.BR gsmsmsd (8),
.BR gsmsmsstore (1).

View File

@ -0,0 +1,56 @@
.\" -*- eval: (nroff-mode) -*-
.de TQ
.br
.ns
.TP \\$1
..
.\" Like TP, but if specified indent is more than half
.\" the current line-length - indent, use the default indent.
.de Tp
.ie \\n(.$=0:((0\\$1)*2u>(\\n(.lu-\\n(.iu)) .TP
.el .TP "\\$1"
..
.TH GSMINFO 7 "##DATE##" "gsmctl v##VERSION##"
.PP
.SH NAME
gsminfo \- GSM general information
.PP
.SH DESCRIPTION
\fIgsmlib\fP is a library to access GSM mobile phones through GSM
modems or via IrDA devices. In the \fIgsmlib\fP documentation and error
messages the following abbreviations are used:
.TP .7i
\fBME\fP
Mobile Equipment. The mobile phone, usually.
.TP .7i
\fBSC\fP
Service Centre. In the context of this documentation, the center
responsible for sending and relaying SMs.
.TP .7i
\fBSM\fP
Short Message.
.TP .7i
\fBSME\fP
Short Message Equipment. Usually the mobile phone.
.TP .7i
\fBTA\fP
Terminal Adapter. This can be a GSM modem PC card or it can be
integrated into the ME.
.TP .7i
\fBTE\fP
Terminal Equipment. This is the device to which the TA is connected,
usually the computer.
.PP
.SH AUTHOR
Peter Hofmann <software@pxh.de>
.PP
.SH COPYRIGHT
Copyright \(co 1999 Peter Hofmann
.PP
.SH "SEE ALSO"
.BR gsmctl(1),
.BR gsmpb(1),
.BR gsmsendsms(1),
.BR gsmsmsd(8),
.BR gsmsmsstore(1).

View File

@ -0,0 +1,20 @@
Begin3
Title: gsmlib
Version: 1.0
Entered-date: 29JUL99
Description: This distribution contains a library to access
GSM mobile phones through GSM modems. Features include:
* modification of phonebooks stored in the
mobile phone or on the SIM card
* reading and writing of SMS messages stored in
the mobile phone
* sending and reception of SMS messages
Additionally, some simple command line programs are
provided to use these functionalities.
Keywords: gsm mobile phone modem sms
Author: Peter Hofmann <software@pxh.de>
Maintained-by: Peter Hofmann <software@pxh.de>
Primary-site: http://www.pxh.de/fs/gsmlib/
Platforms: Linux
Copying-policy: LGPL
End

View File

@ -0,0 +1,245 @@
.\" -*- eval: (nroff-mode) -*-
.de TQ
.br
.ns
.TP \\$1
..
.\" Like TP, but if specified indent is more than half
.\" the current line-length - indent, use the default indent.
.de Tp
.ie \\n(.$=0:((0\\$1)*2u>(\\n(.lu-\\n(.iu)) .TP
.el .TP "\\$1"
..
.TH GSMPB 8 "##DATE##" "gsmpb v##VERSION##"
.SH NAME
gsmpb \- GSM mobile phone phonebook manipulation program
.SH SYNOPSIS
.B gsmpb
[ \fB-b\fP \fIbaudrate\fP ]
[ \fB--baudrate\fP \fIbaudrate\fP ]
[ \fB-c\fP ]
[ \fB--copy\fP ]
[ \fB-d\fP \fIdestination device or file\fP ]
[ \fB--destination\fP \fIdestination device or file\fP ]
[ \fB-h\fP ]
[ \fB--help\fP ]
[ \fB-i\fP ]
[ \fB--index\fP ]
[ \fB-I\fP \fIinit string\fP ]
[ \fB--init\fP \fIinit string\fP ]
[ \fB-p\fP \fIphonebook name\fP ]
[ \fB--phonebook\fP \fIphonebook name\fP ]
[ \fB-s\fP \fIsource device or file\fP ]
[ \fB--source\fP \fIsource device or file\fP ]
[ \fB-t\fP \fIcharacter set\fP ]
[ \fB--charset\fP \fIcharacter set\fP ]
[ \fB-v\fP ]
[ \fB--version\fP ]
[ \fB-V\fP ]
[ \fB--verbose\fP ]
[ \fB-X\fP ]
[ \fB--xonxoff\fP ]
[ \fB-y\fP ]
[ \fB--synchronize\fP ]
.PP
.SH DESCRIPTION
\fIgsmpb\fP can store or retrieve phonebook entries residing in a GSM
mobile phone's phonebook to or from a file. A synchronization mode is
also available.
.PP
\fIgsmpb\fP reads entries from the source which can be a mobile phone
(if a serial device file is given) or a file (if a file name is
given). The source is never modified. \fIgsmpb\fP writes phonebook
entries to a destination file or device. Depending on the mode the
source is copied to the destination file, thus overwriting the
destination, or the destination is synchronized with regard to the
source which is the default (details see below).
.PP
If "-" is given as the parameter for the \fB--source\fP or
\fB--destination\fP options, the phonebook is read from standard input
and/or written to standard output, respectively.
.PP
Phonebook entries names are encoded using the GSM default alphabet in
the mobile phone, whereas they are stored using the Latin-1 encoding
in phonebook files. When reading phonebook entries from a mobile phone
entry names are converted from the GSM default to Latin-1. Characters
that can not be converted to Latin-1 are encoded as character code
172 (Latin-1 boolean "not"). When writing file-based phonebook entries
to a mobile phone a conversion to the GSM default alphabet takes
place. Characters that can not be converted are encoded as GSM delta
(code 16). If the default character set has been changed using the
\fB--charset\fP option no conversion takes place.
.PP
Error messages are printed to the standard error output. If the program
terminates on error the error code 1 is returned.
.PP
.SH OPTIONS
.TP .7i
\fB-b\fP \fIbaudrate\fP, \fB--baudrate\fP \fIbaudrate\fP
The baud rate to use. The default baudrate is 38400.
.TP .7i
\fB-c\fP, \fB--copy\fP
This causes the contents of the source to be copied to the
destination. After this operation the destination has exactly the same
contents as the source.
.TP .7i
\fB-d\fP \fIdestination\fP, \fB--destination\fP \fIdestination\fP
The destination device or file.
.TP .7i
\fB-h\fP, \fB--help\fP
Prints an option summary.
.TP .7i
\fB-I\fP \fIinit string\fP, \fB--init\fP \fIinit string\fP
Initialization string to send to the TA (default: "E0"). Note that the
sequence "ATZ" is sent first.
.TP .7i
\fB-i\fP, \fB--index\fP
If the index position is given, \fIgsmpb\fP preserves the assignment
of entries to memory slots in the mobile phone's phonebook. This can
be used to backup phonebook entries with their position into a
phonebook file or to change the position of entries by editing a
phonebook file and writing them back to the mobile phone.
If this option is given the phonebook file used as the source
must contain indices for every entry. Additionally, these indices must
be unique, ie. it is not allowed to assign one entry twice to a
specific position in the mobile phone's phonebook.
.TP .7i
\fB-p\fP \fIphonebook\fP, \fB--phonebook\fP \fIphonebook\fP
The name of the phonebook to read from or write to. This is only used
for device sources and destinations. Commonly available phonebooks
are:
.TP .3i
.po +0.7i
.ll 5.8i
\fIFD\fP
SIM fixdialling-phonebook
.TP .3i
\fILD\fP
SIM last-dialling-phonebook
.TP .3i
\fIME\fP
ME phonebook
.TP .3i
\fIMT\fP
combined ME and SIM phonebook
.TP .3i
\fISM\fP
SIM phonebook
.TP .3i
\fITA\fP
TA phonebook
.TP .7i
.po -0.7i
.ll 6.5i
\fB-s\fP \fIsource\fP, \fB--source\fP \fIsource\fP
The source device or file.
.TP
\fB-t\fP \fIcharacter set\fP, \fB--charset\fP \fIcharacter set\fP
Set the character set to use for phonebook operations (default is the
GSM default alphabet).
.TP
\fB-v\fP, \fB--version\fP
Prints the program version.
.TP .7i
\fB-V\fP, \fB--verbose\fP
Prints out a detailed progress report.
.TP .7i
\fB-X\fP, \fB--xonxoff\fP
Uses software handshaking (XON/XOFF) for accessing the device.
.TP .7i
\fB-y\fP, \fB--synchronize\fP
This causes the contents of the source to be synchronized with the
destination (default). Synchronization in this context means:
.TP .2i
.po +0.7i
.ll 5.8i
\-
If the source contains an entry with a name that does not exist in the
destination this entry is added to the destination.
.TP .2i
\-
If the source contains an entry with a name that can also be found in
the destination, the entry in the destination is overwritten (ie. the
telephone number is updated). Exception: More then one entry with the
name exists in the destination. In this case the new entry ist just added.
.TP .2i
\-
Entries in the destination that do not exist in the source are
deleted.
.PP
Note that synchronization has the following properties that differ
from copying: This algorithm does not change the location of unchanged
entries in the destination phonebook. The synchronization function
is not case-sensitive when comparing names.
.PP
.po -0.7i
.ll 6.5i
.SH PHONEBOOK FILE FORMAT
Phonebook entries are stored in phonebook files that are meant to be
human-readable and -editable. There is one phonebook entry per line,
and each line has the format:
.PP
.nf
index|text|phone number
.fi
.PP
The fields have the following meanings:
.TP .7i
\fIindex\fP
The index of the entry which must be a positive number. The index may
also be empty. Indices can be used in conjunction with the
\fB--index\fP option to store the entry into a specific position in
the mobile phone.
.TP .7i
\fItext\fP
Descriptive text for the entry. The text may contain the special
characters '\\', '|', carriage return (ASCII code 13), or line feed
(ASCII code 10). These must be written "\\\\", "\\|", "\\r", "\\n",
respectively. The text should only contain characters that can be
encoded using the GSM default alphabet (see comments above).
.TP .7i
\fIphone number\fP
Phone numbers can only contains the digits 0-9 and the '+' sign. A '+'
sign denotes an international number.
.PP
.SH EXAMPLES
The following invocation of \fIgsmpb\fP synchronizes the mobile phone's
SIM phonebook with the file $HOME/.phonebook:
.PP
.nf
gsmpb --synchronize -b 19200 -d /dev/mobilephone \\
-s $HOME/.phonebook -p "SM"
.fi
.PP
.SH AUTHOR
Peter Hofmann <software@pxh.de>
.PP
.SH BUGS
Report bugs to software@pxh.de. Include a complete, self-contained
example that will allow the bug to be reproduced, and say which
version of \fIgsmpb\fP you are using.
.PP
.SH COPYRIGHT
Copyright \(co 1999 Peter Hofmann
.LP
\fIgsmpb\fP is free software; you can redistribute it and/or modify it under
the terms of the GNU Library General Public License as published by the Free
Software Foundation; either version 2, or (at your option) any later
version.
.LP
\fIgsmpb\fP 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 Library General Public License
for more details.
.LP
You should have received a copy of the GNU Library General Public License along
with \fIgsmpb\fP; see the file COPYING. If not, write to the Free Software
Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
.PP
.SH "SEE ALSO"
.BR gsminfo(7),
.BR gsmctl(1),
.BR gsmsendsms(1),
.BR gsmsmsd(8),
.BR gsmsmsstore(1).

View File

@ -0,0 +1,154 @@
.\" -*- eval: (nroff-mode) -*-
.de TQ
.br
.ns
.TP \\$1
..
.\" Like TP, but if specified indent is more than half
.\" the current line-length - indent, use the default indent.
.de Tp
.ie \\n(.$=0:((0\\$1)*2u>(\\n(.lu-\\n(.iu)) .TP
.el .TP "\\$1"
..
.TH GSMSENDSMS 8 "##DATE##" "gsmsendsms v##VERSION##"
.PP
.SH NAME
gsmsendsms \- SMS message sender utility
.PP
.SH SYNOPSIS
.B gsmsendsms
[ \fB-b\fP \fIbaudrate\fP ]
[ \fB--baudrate\fP \fIbaudrate\fP ]
[ \fB-c\fP \fIconcatenatedID\fP ]
[ \fB--concatenate\fP \fIconcatenatedID\fP ]
[ \fB-C\fP \fIservice centre address\fP ]
[ \fB--sca\fP \fIservice centre address\fP ]
[ \fB-d\fP \fIdevice\fP ]
[ \fB--device\fP \fIdevice\fP ]
[ \fB-h\fP ]
[ \fB--help\fP ]
[ \fB-I\fP \fIinit string\fP ]
[ \fB--init\fP \fIinit string\fP ]
[ \fB-r\fP ]
[ \fB--requeststat\fP ]
[ \fB-t\fP ]
[ \fB--test\fP ]
[ \fB-v\fP ]
[ \fB--version\fP ]
[ \fB-X\fP ]
[ \fB--xonxoff\fP ]
\fIphonenumber\fP
[ \fItext\fP ]
.PP
.SH DESCRIPTION
\fIgsmsendsms\fP sends SMS short messages using an GSM mobile phone.
.PP
\fIgsmsendsms\fP attaches itself to the \fIdevice\fP given on the command
line (usually an GSM modem) using the specified \fIbaudrate\fP. If no
\fIdevice\fP is given, the device \fI/dev/mobilephone\fP is used. If
no \fIbaudrate\fP is given, a default baud rate of 38400 is used.
.PP
\fIgsmsendsms\fP accepts a phone number (recipient address) and the
short message text as parameters. The text may have a maximum length
of 160 characters which is the maximum SMS message length. The GSM
default alphabet is used for encoding. ASCII and Latin-1 characters
that can not be encoded using the GSM default alphabet are converted
to the GSM delta character (GSM code 16).
.PP
Error messages are printed to the standard error output. If the program
terminates on error the error code 1 is returned.
.PP
.SH OPTIONS
.TP
\fB-b\fP \fIbaudrate\fP, \fB--baudrate\fP \fIbaudrate\fP
The baud rate to use.
.TP
\fB-c\fP \fIconcatenatedID\fP, \fB--concatenate\fP \fIconcatenatedID\fP
If an ID is given, large SMSs are split into several, concatenated
SMSs. All SMSs have the same ID and are numbered consecutively so that
the receiving phone can assemble them in the correct order. IDs must
be in the range 0..255. Not all receiving phones will support
concatenated SMSs (and display them as separate SMSs),
since all the numbering and ID information is
carried in the user data header element at the beginning of the SMS
user data. This information may show up as garbage in such phones.
.TP
\fB-C\fP \fIservice centre address\fP, \fB--sca\fP \fIservice centre address\fP
Sets the service centre address to use for all SUBMIT SMSs (may not
work with some phones).
.TP
\fB-d\fP \fIdevice\fP, \fB--device\fP \fIdevice\fP
The device to which the GSM modem is connected. The default is
\fI/dev/mobilephone\fP.
.TP
\fB-h\fP, \fB--help\fP
Prints an option summary.
.TP
\fB-I\fP \fIinit string\fP, \fB--init\fP \fIinit string\fP
Initialization string to send to the TA (default: "E0"). Note that the
sequence "ATZ" is sent first.
.TP
\fB-r\fP, \fB--requeststat\fP
Request status reports for sent SMS.
.TP
\fB-t\fP, \fB--test\fP
If this option is given the text is converted
to the GSM default alphabet and back to Latin-1. This option can be
used to find out how ASCII or Latin-1 texts are converted to the GSM
default alphabet. Characters that can not be converted to the GSM default
alphabet are reported as ASCII code 172 (Latin-1 boolean "not")
after this double conversion. No SMS messages are sent, a connection
to a mobile phone is not established.
.TP
\fB-v\fP, \fB--version\fP
Prints the program version.
.TP
\fB-X\fP, \fB--xonxoff\fP
Uses software handshaking (XON/XOFF) for accessing the device.
.PP
.SH EXAMPLES
The following two invocations of \fIgsmsendsms\fP each send the same
SMS message to the number "1234":
.PP
.nf
gsmsendsms -d /dev/ttyS2 -b 19200 1234 "This is a test."
echo "This is a test." | gsmsendsms -d /dev/ttyS2 -b 19200 1234
.fi
.PP
.SH FILES
.TP 1.4i
.B /dev/mobilephone
Default mobile phone device.
.PP
.SH AUTHOR
Peter Hofmann <software@pxh.de>
.PP
.SH BUGS
Report bugs to software@pxh.de. Include a complete, self-contained
example that will allow the bug to be reproduced, and say which
version of \fIgsmsendsms\fP you are using.
.PP
.SH COPYRIGHT
Copyright \(co 1999 Peter Hofmann
.LP
\fIgsmsendsms\fP is free software; you can redistribute it and/or modify it under
the terms of the GNU Library General Public License as published by the Free
Software Foundation; either version 2, or (at your option) any later
version.
.LP
\fIgsmsendsms\fP 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
Library General Public License for more details.
.LP
You should have received a copy of the GNU Library General Public License along
with \fIgsmsendsms\fP; see the file COPYING. If not, write to the Free Software
Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
.PP
.SH "SEE ALSO"
.BR gsminfo(7),
.BR gsmpb(1),
.BR gsmctl(1),
.BR gsmsmsd(8),
.BR gsmsmsstore(1).

View File

@ -0,0 +1,269 @@
.\" -*- eval: (nroff-mode) -*-
.de TQ
.br
.ns
.TP \\$1
..
.\" Like TP, but if specified indent is more than half
.\" the current line-length - indent, use the default indent.
.de Tp
.ie \\n(.$=0:((0\\$1)*2u>(\\n(.lu-\\n(.iu)) .TP
.el .TP "\\$1"
..
.TH GSMSMSD 8 "##DATE##" "gsmsmsd v##VERSION##"
.PP
.SH NAME
gsmsmsd \- SMS message reception daemon
.PP
.SH SYNOPSIS
.B gsmsmsd
[ \fB-a\fP \fIaction\fP ]
[ \fB--action\fP \fIaction\fP ]
[ \fB-b\fP \fIbaudrate\fP ]
[ \fB--baudrate\fP \fIbaudrate\fP ]
[ \fB-c\fP \fIconcatenatedID\fP ]
[ \fB--concatenate\fP \fIconcatenatedID\fP ]
[ \fB-C\fP \fIservice centre address\fP ]
[ \fB--sca\fP \fIservice centre address\fP ]
[ \fB-d\fP \fIdevice\fP ]
[ \fB--device\fP \fIdevice\fP ]
[ \fB-D\fP ]
[ \fB--direct\fP ]
[ \fB-f\fP ]
[ \fB--flush\fP ]
[ \fB-h\fP ]
[ \fB--help\fP ]
[ \fB-I\fP \fIinit string\fP ]
[ \fB--init\fP \fIinit string\fP ]
[ \fB-r\fP ]
[ \fB--requeststat\fP ]
[ \fB-s\fP \fIspool directory\fP ]
[ \fB--spool\fP \fIspool directory\fP ]
[ \fB-t\fP \fISMS store name\fP ]
[ \fB--store\fP \fISMS store name\fP ]
[ \fB-v\fP ]
[ \fB--version\fP ]
[ \fB-X\fP ]
[ \fB--xonxoff\fP ]
{ \fIsms_type\fP }
.PP
.SH DESCRIPTION
\fIgsmsmsd\fP reads new incoming SMS from the mobile phone and
dispatches them to a user-defined action. Additionally it can send SMS
message that it reads from a spooldir.
.PP
\fIgsmsmsd\fP attaches itself to the \fIdevice\fP given on the command
line (usually an GSM modem) using the specified \fIbaudrate\fP and
waits for incoming SMS messages. If no \fIdevice\fP is given, the
device \fI/dev/mobilephone\fP is used. If no \fIbaudrate\fP is given, a
default baud rate of 38400 is used.
.PP
If no action is given, the SMS message is printed to the standard
output. If an \fIaction\fP is specified the \fIaction\fP is excecuted using the
shell and the SMS message is written to the standard input of the action.
.PP
\fIgsmsmsd\fP needs one empty storage slot for SMS messages in the
mobile phone, otherwise SMS reception will not work. The SMS store to
use for temporary storage of incoming SMS can be selected using the
\fB--store\fP option, otherwise the ME default store is used.
.PP
To terminate \fIgsmsmsd\fP cleanly (without losing SMS messages) one
should send either SIGINT (CTRL-C on the command line) or SIGTERM to
the process.
.PP
Error messages are printed to the standard error output. If the program
terminates on error the error code 1 is returned.
.PP
\fIsms_type\fP may be any combination of:
.TP
\fIsms\fP, \fIno_sms\fP
Controls reception of normal SMS messages.
.TP
\fIcb\fP, \fIno_cb\fP
Controls reception of cell broadcast messages.
.TP
\fIstat\fP, \fIno_stat\fP
Controls reception of status reports.
.PP
The default is \fIsms\fP, \fIcb\fP, and \fIstat\fP.
.PP
.SH OPTIONS
.TP
\fB-a\fP \fIaction\fP, \fB--action\fP \fIaction\fP
The action to execute for each incoming SMS message. If no action
is given the SMS is written to the standard output.
.TP
\fB-b\fP \fIbaudrate\fP, \fB--baudrate\fP \fIbaudrate\fP
The baud rate to use.
.TP
\fB-c\fP \fIconcatenatedID\fP, \fB--concatenate\fP \fIconcatenatedID\fP
If an ID is given, large SMSs are split into several, concatenated
SMSs. All SMSs have the same ID and are numbered consecutively so that
the receiving phone can assemble them in the correct order. IDs must
be in the range 0..255. This number is increased by one for every
outgoing concatenated SMS and wraps around after 255.
Not all receiving phones will support
concatenated SMSs (and display them as separate SMSs),
since all the numbering and ID information is
carried in the user data header element at the beginning of the SMS
user data. This information may show up as garbage in such phones.
.TP
\fB-C\fP \fIservice centre address\fP, \fB--sca\fP \fIservice centre address\fP
Sets the service centre address to use for all SUBMIT SMSs (may not
work with some phones).
.TP
\fB-d\fP \fIdevice\fP, \fB--device\fP \fIdevice\fP
The device to which the GSM modem is connected. The default is
\fI/dev/mobilephone\fP.
.TP
\fB-D\fP, \fB--direct\fP
Enables direct routing of incoming SMS messages to the TE. This is not
supported by many mobile phone/GSM modem combinations. Therefore, the
default is to store incoming SMS temporarily before processing them in
the indicated store.
.TP
\fB-f\fP, \fB--flush\fP
This option causes \fIgsmsmsd\fP to flush (ie. read and erase)
existing SMS messages from
the SMS store selected by the \fB--store\fP option. The action given
by the \fB--action\fP option is executed on each of the flushed
SMS. This option should be used to ensure that enough space is
available in the SMS store for temporary storage of incoming SMS,
otherwise incoming SMS might be ignored silently by the ME.
.TP
\fB-h\fP, \fB--help\fP
Prints an option summary.
.TP
\fB-I\fP \fIinit string\fP, \fB--init\fP \fIinit string\fP
Initialization string to send to the TA (default: "E0"). Note that the
sequence "ATZ" is sent first.
.TP
\fB-r\fP, \fB--requeststat\fP
Request status reports for sent SMS. Note: This option only makes
sense if the phone supports routing of status reports to the
TE. Otherwise the status reports might show on the phone's display or
get lost.
.TP
\fB-s\fP \fIspool directory\fP, \fB--spool\fP \fIspool directory\fP
This option sets the spool directory where \fIgsmsmsd\fP expects SMS
messages to send. The format of SMS files is very simple: The first
line contains the phone number of the recipient. Everything else after
the first line is interpreted as the SMS text. Please refer to
.BR gsmsendsms(1)
for details on the SMS text character set and maximum length.
\fIgsmsmsd\fP polls the spool directory every 5 seconds. Sent
SMS message files are removed.
.TP
\fB-t\fP \fISMS store name\fP, \fB--store\fP \fISMS store name\fP
The name of the SMS store to read from (for the \fB--flush\fP option)
or write to (for temporary SMS storage). This option must
be must be used in conjunction with the \fB--flush\fP option. If this
option is omitted the ME uses it's default SMS store for temporary
storage of incoming SMS. A commonly available message
store is "SM" (SIM card).
.TP
\fB-v\fP, \fB--version\fP
Prints the program version.
.TP
\fB-X\fP, \fB--xonxoff\fP
Uses software handshaking (XON/XOFF) for accessing the device.
.PP
.SH EXAMPLES
The following invocation of \fIgsmsmsd\fP sends each incoming SMS message
as a mail to the user "smsadmin":
.PP
.nf
gsmsmsd -d /dev/ttyS2 -b 19200 -a "mail smsadmin"
.fi
.PP
This is the format of SMS deliver messages as output from \fIgsmsmsd\fP:
.PP
.nf
----------------------------------------------------------------
Message type: SMS-DELIVER
SC address: '491710762100'
More messages to send: 1
Reply path: 0
User data header indicator: 0
Status report indication: 0
Originating address: '01805000102'
Protocol identifier: 0x39
Data coding scheme: default alphabet
SC timestamp: 17.12.98 14:10:55(+0100)
User data length: 159
User data header: 0x
User data: 'Nicht vergessen! Die XtraWeihnachtsverlosung lauft
noch bis zum 24.12. Nutzen Sie jetzt Ihre Gewinnchance und faxen
Sie Ihren Teiln.-Gutschein an 0180/5000 056'
----------------------------------------------------------------
.fi
.PP
This is the format of SMS status report messages as output from \fIgsmsmsd\fP:
.PP
.nf
----------------------------------------------------------------
Message type: SMS-STATUS-REPORT
SC address: ''
More messages to send: 0
Status report qualifier: 0
Message reference: 0
Recipient address: ''
SC timestamp: 00.00.00 00:00:00(+0000)
Discharge time: 00.00.00 00:00:00(+0000)
Status: 0x0 'Short message received by the SME'
----------------------------------------------------------------
.fi
.PP
The following invocation of \fIgsmsmsd\fP flushes all existing
messages from the "SM" SMS store and looks in the "/tmp/spooldir"
directory for SMS to send:
.PP
.nf
gsmsmsd -d /dev/ttyS2 --spool /tmp/spooldir -f --store sm \\
--action 'mail smsadmin'
.fi
.PP
.SH FILES
.TP 1.4i
.B /dev/mobilephone
Default mobile phone device.
.PP
.SH AUTHOR
Peter Hofmann <software@pxh.de>
.PP
.SH BUGS
Cell broadcast SMS message reception has not been tested, but it has
been enabled in the \fIgsmsmsd\fP daemon.
.PP
The mobile phone device is blocked when the \fIgsmsmsd\fP daemon is
running, ie. it cannot be used for data transfer or from the other
programs of this suite (\fIgsmpb\fP, \fIgsmsms\fP).
.PP
Report bugs to software@pxh.de. Include a complete, self-contained
example that will allow the bug to be reproduced, and say which
version of \fIgsmsmsd\fP you are using.
.PP
.SH COPYRIGHT
Copyright \(co 1999 Peter Hofmann
.LP
\fIgsmsmsd\fP is free software; you can redistribute it and/or modify it under
the terms of the GNU Library General Public License as published by the Free
Software Foundation; either version 2, or (at your option) any later
version.
.LP
\fIgsmsmsd\fP 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
Library General Public License for more details.
.LP
You should have received a copy of the GNU Library General Public License along
with \fIgsmsmsd\fP; see the file COPYING. If not, write to the Free Software
Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
.PP
.SH "SEE ALSO"
.BR gsminfo(7),
.BR gsmpb(1),
.BR gsmctl(1),
.BR gsmsendsms(1),
.BR gsmsmsstore(1).

View File

@ -0,0 +1,185 @@
.\" -*- eval: (nroff-mode) -*-
.de TQ
.br
.ns
.TP \\$1
..
.\" Like TP, but if specified indent is more than half
.\" the current line-length - indent, use the default indent.
.de Tp
.ie \\n(.$=0:((0\\$1)*2u>(\\n(.lu-\\n(.iu)) .TP
.el .TP "\\$1"
..
.TH GSMSMSSTORE 8 "##DATE##" "gsmsmsstore v##VERSION##"
.SH NAME
gsmsmsstore \- SMS store manipulation program
.SH SYNOPSIS
.B gsmsmsstore
[ \fB-a\fP ]
[ \fB--add\fP ]
[ \fB-b\fP \fIbaudrate\fP ]
[ \fB--baudrate\fP \fIbaudrate\fP ]
[ \fB-c\fP ]
[ \fB--copy\fP ]
[ \fB-C\fP \fIservice centre address\fP ]
[ \fB--sca\fP \fIservice centre address\fP ]
[ \fB-d\fP \fIdestination device or file\fP ]
[ \fB--destination\fP \fIdestination device or file\fP ]
[ \fB-h\fP ]
[ \fB--help\fP ]
[ \fB-I\fP \fIinit string\fP ]
[ \fB--init\fP \fIinit string\fP ]
[ \fB-k\fP ]
[ \fB--backup\fP ]
[ \fB-l\fP ]
[ \fB--list\fP ]
[ \fB-s\fP \fIsource device or file\fP ]
[ \fB--source\fP \fIsource device or file\fP ]
[ \fB-t\fP \fISMS store name\fP ]
[ \fB--store\fP \fISMS store name\fP ]
[ \fB-v\fP ]
[ \fB--version\fP ]
[ \fB-V\fP ]
[ \fB--verbose\fP ]
[ \fB-x\fP ]
[ \fB--delete\fP ]
[ \fB-X\fP ]
[ \fB--xonxoff\fP ]
{ \fIindices\fP }
[ \fIphonenumber\fP \fItext\fP ]
.PP
.SH DESCRIPTION
\fIgsmsmsstore\fP can store or retrieve SMS messages entries residing
in a GSM mobile phone's SMS store to or from a file, add SMS messages
to a store, or list the store's contents. Additionally, it is possible
to add SMS submit messages to a store.
.PP
\fIgsmsmsstore\fP reads entries from the source which can be a mobile
phone (if a serial device file is given) or a file (if a file name is
given). The source is never modified. \fIgsmsmsstore\fP writes SMS
messages to a destination file or device in the case of \fB--copy\fP,
\fB--backup\fP, and \fB--add\fP.
.PP
The \fB--list\fP option does not change any file but just lists the
contents to standard output.
.PP
The \fB--backup\fP and \fB--copy\fP options require both source and
destination files or devices. The \fB--list\fP option requires a
source. The \fB--add\fP and \fB--delete\fP options require a
destination file or device.
.PP
If "-" is given as the parameter for the \fB--source\fP or
\fB--destination\fP options, the SMS store is read from standard input
and/or written to standard output, respectively.
.PP
SMS message files are not human-readable.
.PP
Error messages are printed to the standard error output. If the program
terminates on error the error code 1 is returned.
.PP
.SH OPTIONS
.TP
\fB-a\fP, \fB--add\fP
Adds an SMS submit message with recipient address \fIphonenumber\fP and
text \fItext\fP to the destination.
.TP
\fB-b\fP \fIbaudrate\fP, \fB--baudrate\fP \fIbaudrate\fP
The baud rate to use. The default baudrate is 38400.
.TP
\fB-c\fP, \fB--copy\fP
This causes the contents of the source to be copied to the
destination. After this operation the destination has exactly the same
contents as the source. If \fIindices\fP are given on the command
line only those SMS messages denoted by the indices are copied to the
destination.
.TP
\fB-C\fP \fIservice centre address\fP, \fB--sca\fP \fIservice centre address\fP
Sets the service centre address to use for all SUBMIT SMSs (may not
work with some phones).
.TP
\fB-d\fP \fIdestination\fP, \fB--destination\fP \fIdestination\fP
The destination device or file.
.TP
\fB-h\fP, \fB--help\fP
Prints an option summary.
.TP
\fB-I\fP \fIinit string\fP, \fB--init\fP \fIinit string\fP
Initialization string to send to the TA (default: "E0"). Note that the
sequence "ATZ" is sent first.
.TP
\fB-k\fP, \fB--backup\fP
This causes those entries to be added from the source to the
destination that are not already present in the destination. If
\fIindices\fP are given on the command line only those SMS messages
denoted by the indices are backed up (ie. added) to the destination.
.TP
\fB-l\fP, \fB--list\fP
Prints out the entire contents of the source in human-readable form.
.TP
\fB-s\fP \fIsource\fP, \fB--source\fP \fIsource\fP
The source device or file.
.TP
\fB-t\fP \fISMS store name\fP, \fB--store\fP \fISMS store name\fP
The name of the SMS store to read from or write to. This information is
only used for device sources and destinations. A commonly available message
store is "SM" (SIM card).
.TP
\fB-v\fP, \fB--version\fP
Prints the program version.
.TP
\fB-V\fP, \fB--verbose\fP
Prints out a detailed progress report.
.TP
\fB-x\fP, \fB--delete\fP
Delete the SMS messages as denoted by the \fIindices\fP from the destination.
.TP
\fB-X\fP, \fB--xonxoff\fP
Uses software handshaking (XON/XOFF) for accessing the device.
.PP
.SH EXAMPLES
The following command lists all entries in the mobile phone connected
to \fI/dev/mobilephone\fP to the standard output:
.PP
.nf
gsmsmsstore -b 19200 -s /dev/mobilephone -t SM -l
.fi
.PP
The following adds entries 4, 7, and 10 from the device
\fI/dev/mobilephone\fP to the file \fIsmsstore\fP:
.PP
.nf
gsmsmsstore -s /dev/mobilephone -d /home/fred/smsstore
-t SM -b 4 7 10
.fi
.PP
.SH AUTHOR
Peter Hofmann <software@pxh.de>
.PP
.SH BUGS
Report bugs to software@pxh.de. Include a complete, self-contained
example that will allow the bug to be reproduced, and say which
version of \fIgsmsmsstore\fP you are using.
.PP
.SH COPYRIGHT
Copyright \(co 1999 Peter Hofmann
.LP
\fIgsmsmsstore\fP is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public License as
published by the Free Software Foundation; either version 2, or (at
your option) any later version.
.LP
\fIgsmsmsstore\fP 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
Library General Public License for more details.
.LP
You should have received a copy of the GNU Library General Public License
along with \fIgsmsmsstore\fP; see the file COPYING. If not, write to
the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
.PP
.SH "SEE ALSO"
.BR gsminfo(7),
.BR gsmctl(1),
.BR gsmpb(1),
.BR gsmsendsms(1),
.BR gsmsmsd(8).

View File

@ -0,0 +1,40 @@
## Process this file with automake to produce Makefile.in
# *************************************************************************
# * GSM TA/ME library
# *
# * File: Makefile.am
# *
# * Purpose: Makefile for phone-specific extensions
# *
# * Author: Peter Hofmann (software@pxh.de)
# *
# * Created: 16.12.2001
# *************************************************************************
INCLUDES = -I..
EXTRA_DIST = README.sieme
# build addon library
lib_LTLIBRARIES = libgsmext.la
libgsmext_la_SOURCES = gsm_sie_me.cc
libgsmext_la_LDFLAGS = -version-info $(GSM_VERSION)
gsmincludedir = $(includedir)/gsmlib
gsminclude_HEADERS = gsm_sie_me.h
# build programs
bin_PROGRAMS = gsmsiectl gsmsiexfer
# build gsmsiectl from gsmsiectl.cc and libgsmme.la
gsmsiectl_SOURCES = gsmsiectl.cc
gsmsiectl_LDADD = ../gsmlib/libgsmme.la libgsmext.la $(INTLLIBS)
# build gsmsiexfer from gsmsiexfer.cc and libgsmme.la
gsmsiexfer_SOURCES = gsmsiexfer.cc
gsmsiexfer_LDADD = ../gsmlib/libgsmme.la libgsmext.la $(INTLLIBS)

View File

@ -0,0 +1,480 @@
# Makefile.in generated by automake 1.6.3 from Makefile.am.
# @configure_input@
# Copyright 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002
# Free Software Foundation, Inc.
# This Makefile.in is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
# with or without modifications, as long as this notice is preserved.
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
# PARTICULAR PURPOSE.
@SET_MAKE@
# *************************************************************************
# * GSM TA/ME library
# *
# * File: Makefile.am
# *
# * Purpose: Makefile for phone-specific extensions
# *
# * Author: Peter Hofmann (software@pxh.de)
# *
# * Created: 16.12.2001
# *************************************************************************
SHELL = @SHELL@
srcdir = @srcdir@
top_srcdir = @top_srcdir@
VPATH = @srcdir@
prefix = @prefix@
exec_prefix = @exec_prefix@
bindir = @bindir@
sbindir = @sbindir@
libexecdir = @libexecdir@
datadir = @datadir@
sysconfdir = @sysconfdir@
sharedstatedir = @sharedstatedir@
localstatedir = @localstatedir@
libdir = @libdir@
infodir = @infodir@
mandir = @mandir@
includedir = @includedir@
oldincludedir = /usr/include
pkgdatadir = $(datadir)/@PACKAGE@
pkglibdir = $(libdir)/@PACKAGE@
pkgincludedir = $(includedir)/@PACKAGE@
top_builddir = ..
ACLOCAL = @ACLOCAL@
AUTOCONF = @AUTOCONF@
AUTOMAKE = @AUTOMAKE@
AUTOHEADER = @AUTOHEADER@
am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
INSTALL = @INSTALL@
INSTALL_PROGRAM = @INSTALL_PROGRAM@
INSTALL_DATA = @INSTALL_DATA@
install_sh_DATA = $(install_sh) -c -m 644
install_sh_PROGRAM = $(install_sh) -c
install_sh_SCRIPT = $(install_sh) -c
INSTALL_SCRIPT = @INSTALL_SCRIPT@
INSTALL_HEADER = $(INSTALL_DATA)
transform = @program_transform_name@
NORMAL_INSTALL = :
PRE_INSTALL = :
POST_INSTALL = :
NORMAL_UNINSTALL = :
PRE_UNINSTALL = :
POST_UNINSTALL = :
host_alias = @host_alias@
host_triplet = @host@
EXEEXT = @EXEEXT@
OBJEXT = @OBJEXT@
PATH_SEPARATOR = @PATH_SEPARATOR@
AMTAR = @AMTAR@
AS = @AS@
AWK = @AWK@
BUILD_INCLUDED_LIBINTL = @BUILD_INCLUDED_LIBINTL@
CATOBJEXT = @CATOBJEXT@
CC = @CC@
CPP = @CPP@
CXX = @CXX@
DATADIRNAME = @DATADIRNAME@
DEPDIR = @DEPDIR@
DLLTOOL = @DLLTOOL@
ECHO = @ECHO@
GENCAT = @GENCAT@
GLIBC21 = @GLIBC21@
GMSGFMT = @GMSGFMT@
GSM_VERSION = @GSM_VERSION@
HAVE_LIB = @HAVE_LIB@
INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
INSTOBJEXT = @INSTOBJEXT@
INTLBISON = @INTLBISON@
INTLLIBS = @INTLLIBS@
INTLOBJS = @INTLOBJS@
INTL_LIBTOOL_SUFFIX_PREFIX = @INTL_LIBTOOL_SUFFIX_PREFIX@
LIB = @LIB@
LIBICONV = @LIBICONV@
LIBINTL = @LIBINTL@
LIBTOOL = @LIBTOOL@
LN_S = @LN_S@
LTLIB = @LTLIB@
LTLIBICONV = @LTLIBICONV@
LTLIBINTL = @LTLIBINTL@
MKINSTALLDIRS = @MKINSTALLDIRS@
OBJDUMP = @OBJDUMP@
PACKAGE = @PACKAGE@
POSUB = @POSUB@
RANLIB = @RANLIB@
STRIP = @STRIP@
USE_INCLUDED_LIBINTL = @USE_INCLUDED_LIBINTL@
USE_NLS = @USE_NLS@
VERSION = @VERSION@
am__include = @am__include@
am__quote = @am__quote@
install_sh = @install_sh@
INCLUDES = -I..
EXTRA_DIST = README.sieme
# build addon library
lib_LTLIBRARIES = libgsmext.la
libgsmext_la_SOURCES = gsm_sie_me.cc
libgsmext_la_LDFLAGS = -version-info $(GSM_VERSION)
gsmincludedir = $(includedir)/gsmlib
gsminclude_HEADERS = gsm_sie_me.h
# build programs
bin_PROGRAMS = gsmsiectl gsmsiexfer
# build gsmsiectl from gsmsiectl.cc and libgsmme.la
gsmsiectl_SOURCES = gsmsiectl.cc
gsmsiectl_LDADD = ../gsmlib/libgsmme.la libgsmext.la $(INTLLIBS)
# build gsmsiexfer from gsmsiexfer.cc and libgsmme.la
gsmsiexfer_SOURCES = gsmsiexfer.cc
gsmsiexfer_LDADD = ../gsmlib/libgsmme.la libgsmext.la $(INTLLIBS)
subdir = ext
mkinstalldirs = $(SHELL) $(top_srcdir)/scripts/mkinstalldirs
CONFIG_HEADER = $(top_builddir)/gsm_config.h
CONFIG_CLEAN_FILES =
LTLIBRARIES = $(lib_LTLIBRARIES)
libgsmext_la_LIBADD =
am_libgsmext_la_OBJECTS = gsm_sie_me.lo
libgsmext_la_OBJECTS = $(am_libgsmext_la_OBJECTS)
bin_PROGRAMS = gsmsiectl$(EXEEXT) gsmsiexfer$(EXEEXT)
PROGRAMS = $(bin_PROGRAMS)
am_gsmsiectl_OBJECTS = gsmsiectl.$(OBJEXT)
gsmsiectl_OBJECTS = $(am_gsmsiectl_OBJECTS)
gsmsiectl_DEPENDENCIES = ../gsmlib/libgsmme.la libgsmext.la
gsmsiectl_LDFLAGS =
am_gsmsiexfer_OBJECTS = gsmsiexfer.$(OBJEXT)
gsmsiexfer_OBJECTS = $(am_gsmsiexfer_OBJECTS)
gsmsiexfer_DEPENDENCIES = ../gsmlib/libgsmme.la libgsmext.la
gsmsiexfer_LDFLAGS =
DEFS = @DEFS@
DEFAULT_INCLUDES = -I. -I$(srcdir) -I$(top_builddir)
CPPFLAGS = @CPPFLAGS@
LDFLAGS = @LDFLAGS@
LIBS = @LIBS@
depcomp = $(SHELL) $(top_srcdir)/scripts/depcomp
am__depfiles_maybe = depfiles
@AMDEP_TRUE@DEP_FILES = ./$(DEPDIR)/gsm_sie_me.Plo \
@AMDEP_TRUE@ ./$(DEPDIR)/gsmsiectl.Po ./$(DEPDIR)/gsmsiexfer.Po
CXXCOMPILE = $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \
$(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS)
LTCXXCOMPILE = $(LIBTOOL) --mode=compile $(CXX) $(DEFS) \
$(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \
$(AM_CXXFLAGS) $(CXXFLAGS)
CXXLD = $(CXX)
CXXLINK = $(LIBTOOL) --mode=link $(CXXLD) $(AM_CXXFLAGS) $(CXXFLAGS) \
$(AM_LDFLAGS) $(LDFLAGS) -o $@
CXXFLAGS = @CXXFLAGS@
DIST_SOURCES = $(libgsmext_la_SOURCES) $(gsmsiectl_SOURCES) \
$(gsmsiexfer_SOURCES)
HEADERS = $(gsminclude_HEADERS)
DIST_COMMON = $(gsminclude_HEADERS) Makefile.am Makefile.in
SOURCES = $(libgsmext_la_SOURCES) $(gsmsiectl_SOURCES) $(gsmsiexfer_SOURCES)
all: all-am
.SUFFIXES:
.SUFFIXES: .cc .lo .o .obj
$(srcdir)/Makefile.in: Makefile.am $(top_srcdir)/configure.in $(ACLOCAL_M4)
cd $(top_srcdir) && \
$(AUTOMAKE) --gnu ext/Makefile
Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)
libLTLIBRARIES_INSTALL = $(INSTALL)
install-libLTLIBRARIES: $(lib_LTLIBRARIES)
@$(NORMAL_INSTALL)
$(mkinstalldirs) $(DESTDIR)$(libdir)
@list='$(lib_LTLIBRARIES)'; for p in $$list; do \
if test -f $$p; then \
f="`echo $$p | sed -e 's|^.*/||'`"; \
echo " $(LIBTOOL) --mode=install $(libLTLIBRARIES_INSTALL) $(INSTALL_STRIP_FLAG) $$p $(DESTDIR)$(libdir)/$$f"; \
$(LIBTOOL) --mode=install $(libLTLIBRARIES_INSTALL) $(INSTALL_STRIP_FLAG) $$p $(DESTDIR)$(libdir)/$$f; \
else :; fi; \
done
uninstall-libLTLIBRARIES:
@$(NORMAL_UNINSTALL)
@list='$(lib_LTLIBRARIES)'; for p in $$list; do \
p="`echo $$p | sed -e 's|^.*/||'`"; \
echo " $(LIBTOOL) --mode=uninstall rm -f $(DESTDIR)$(libdir)/$$p"; \
$(LIBTOOL) --mode=uninstall rm -f $(DESTDIR)$(libdir)/$$p; \
done
clean-libLTLIBRARIES:
-test -z "$(lib_LTLIBRARIES)" || rm -f $(lib_LTLIBRARIES)
@list='$(lib_LTLIBRARIES)'; for p in $$list; do \
dir="`echo $$p | sed -e 's|/[^/]*$$||'`"; \
test -z "$dir" && dir=.; \
echo "rm -f \"$${dir}/so_locations\""; \
rm -f "$${dir}/so_locations"; \
done
libgsmext.la: $(libgsmext_la_OBJECTS) $(libgsmext_la_DEPENDENCIES)
$(CXXLINK) -rpath $(libdir) $(libgsmext_la_LDFLAGS) $(libgsmext_la_OBJECTS) $(libgsmext_la_LIBADD) $(LIBS)
binPROGRAMS_INSTALL = $(INSTALL_PROGRAM)
install-binPROGRAMS: $(bin_PROGRAMS)
@$(NORMAL_INSTALL)
$(mkinstalldirs) $(DESTDIR)$(bindir)
@list='$(bin_PROGRAMS)'; for p in $$list; do \
p1=`echo $$p|sed 's/$(EXEEXT)$$//'`; \
if test -f $$p \
|| test -f $$p1 \
; then \
f=`echo "$$p1" | sed 's,^.*/,,;$(transform);s/$$/$(EXEEXT)/'`; \
echo " $(INSTALL_PROGRAM_ENV) $(LIBTOOL) --mode=install $(binPROGRAMS_INSTALL) $$p $(DESTDIR)$(bindir)/$$f"; \
$(INSTALL_PROGRAM_ENV) $(LIBTOOL) --mode=install $(binPROGRAMS_INSTALL) $$p $(DESTDIR)$(bindir)/$$f; \
else :; fi; \
done
uninstall-binPROGRAMS:
@$(NORMAL_UNINSTALL)
@list='$(bin_PROGRAMS)'; for p in $$list; do \
f=`echo "$$p" | sed 's,^.*/,,;s/$(EXEEXT)$$//;$(transform);s/$$/$(EXEEXT)/'`; \
echo " rm -f $(DESTDIR)$(bindir)/$$f"; \
rm -f $(DESTDIR)$(bindir)/$$f; \
done
clean-binPROGRAMS:
@list='$(bin_PROGRAMS)'; for p in $$list; do \
f=`echo $$p|sed 's/$(EXEEXT)$$//'`; \
echo " rm -f $$p $$f"; \
rm -f $$p $$f ; \
done
gsmsiectl$(EXEEXT): $(gsmsiectl_OBJECTS) $(gsmsiectl_DEPENDENCIES)
@rm -f gsmsiectl$(EXEEXT)
$(CXXLINK) $(gsmsiectl_LDFLAGS) $(gsmsiectl_OBJECTS) $(gsmsiectl_LDADD) $(LIBS)
gsmsiexfer$(EXEEXT): $(gsmsiexfer_OBJECTS) $(gsmsiexfer_DEPENDENCIES)
@rm -f gsmsiexfer$(EXEEXT)
$(CXXLINK) $(gsmsiexfer_LDFLAGS) $(gsmsiexfer_OBJECTS) $(gsmsiexfer_LDADD) $(LIBS)
mostlyclean-compile:
-rm -f *.$(OBJEXT) core *.core
distclean-compile:
-rm -f *.tab.c
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gsm_sie_me.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gsmsiectl.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gsmsiexfer.Po@am__quote@
distclean-depend:
-rm -rf ./$(DEPDIR)
.cc.o:
@AMDEP_TRUE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@ depfile='$(DEPDIR)/$*.Po' tmpdepfile='$(DEPDIR)/$*.TPo' @AMDEPBACKSLASH@
@AMDEP_TRUE@ $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
$(CXXCOMPILE) -c -o $@ `test -f '$<' || echo '$(srcdir)/'`$<
.cc.obj:
@AMDEP_TRUE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@ depfile='$(DEPDIR)/$*.Po' tmpdepfile='$(DEPDIR)/$*.TPo' @AMDEPBACKSLASH@
@AMDEP_TRUE@ $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
$(CXXCOMPILE) -c -o $@ `cygpath -w $<`
.cc.lo:
@AMDEP_TRUE@ source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@
@AMDEP_TRUE@ depfile='$(DEPDIR)/$*.Plo' tmpdepfile='$(DEPDIR)/$*.TPlo' @AMDEPBACKSLASH@
@AMDEP_TRUE@ $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
$(LTCXXCOMPILE) -c -o $@ `test -f '$<' || echo '$(srcdir)/'`$<
CXXDEPMODE = @CXXDEPMODE@
mostlyclean-libtool:
-rm -f *.lo
clean-libtool:
-rm -rf .libs _libs
distclean-libtool:
-rm -f libtool
uninstall-info-am:
gsmincludeHEADERS_INSTALL = $(INSTALL_HEADER)
install-gsmincludeHEADERS: $(gsminclude_HEADERS)
@$(NORMAL_INSTALL)
$(mkinstalldirs) $(DESTDIR)$(gsmincludedir)
@list='$(gsminclude_HEADERS)'; for p in $$list; do \
if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
f="`echo $$p | sed -e 's|^.*/||'`"; \
echo " $(gsmincludeHEADERS_INSTALL) $$d$$p $(DESTDIR)$(gsmincludedir)/$$f"; \
$(gsmincludeHEADERS_INSTALL) $$d$$p $(DESTDIR)$(gsmincludedir)/$$f; \
done
uninstall-gsmincludeHEADERS:
@$(NORMAL_UNINSTALL)
@list='$(gsminclude_HEADERS)'; for p in $$list; do \
f="`echo $$p | sed -e 's|^.*/||'`"; \
echo " rm -f $(DESTDIR)$(gsmincludedir)/$$f"; \
rm -f $(DESTDIR)$(gsmincludedir)/$$f; \
done
ETAGS = etags
ETAGSFLAGS =
tags: TAGS
ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
unique=`for i in $$list; do \
if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
done | \
$(AWK) ' { files[$$0] = 1; } \
END { for (i in files) print i; }'`; \
mkid -fID $$unique
TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
$(TAGS_FILES) $(LISP)
tags=; \
here=`pwd`; \
list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
unique=`for i in $$list; do \
if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
done | \
$(AWK) ' { files[$$0] = 1; } \
END { for (i in files) print i; }'`; \
test -z "$(ETAGS_ARGS)$$tags$$unique" \
|| $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
$$tags $$unique
GTAGS:
here=`$(am__cd) $(top_builddir) && pwd` \
&& cd $(top_srcdir) \
&& gtags -i $(GTAGS_ARGS) $$here
distclean-tags:
-rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH
DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
top_distdir = ..
distdir = $(top_distdir)/$(PACKAGE)-$(VERSION)
distdir: $(DISTFILES)
@list='$(DISTFILES)'; for file in $$list; do \
if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
dir=`echo "$$file" | sed -e 's,/[^/]*$$,,'`; \
if test "$$dir" != "$$file" && test "$$dir" != "."; then \
dir="/$$dir"; \
$(mkinstalldirs) "$(distdir)$$dir"; \
else \
dir=''; \
fi; \
if test -d $$d/$$file; then \
if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \
fi; \
cp -pR $$d/$$file $(distdir)$$dir || exit 1; \
else \
test -f $(distdir)/$$file \
|| cp -p $$d/$$file $(distdir)/$$file \
|| exit 1; \
fi; \
done
check-am: all-am
check: check-am
all-am: Makefile $(LTLIBRARIES) $(PROGRAMS) $(HEADERS)
install-binPROGRAMS: install-libLTLIBRARIES
installdirs:
$(mkinstalldirs) $(DESTDIR)$(libdir) $(DESTDIR)$(bindir) $(DESTDIR)$(gsmincludedir)
install: install-am
install-exec: install-exec-am
install-data: install-data-am
uninstall: uninstall-am
install-am: all-am
@$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
installcheck: installcheck-am
install-strip:
$(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
INSTALL_STRIP_FLAG=-s \
`test -z '$(STRIP)' || \
echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install
mostlyclean-generic:
clean-generic:
distclean-generic:
-rm -f Makefile $(CONFIG_CLEAN_FILES)
maintainer-clean-generic:
@echo "This command is intended for maintainers to use"
@echo "it deletes files that may require special tools to rebuild."
clean: clean-am
clean-am: clean-binPROGRAMS clean-generic clean-libLTLIBRARIES \
clean-libtool mostlyclean-am
distclean: distclean-am
distclean-am: clean-am distclean-compile distclean-depend \
distclean-generic distclean-libtool distclean-tags
dvi: dvi-am
dvi-am:
info: info-am
info-am:
install-data-am: install-gsmincludeHEADERS
install-exec-am: install-binPROGRAMS install-libLTLIBRARIES
install-info: install-info-am
install-man:
installcheck-am:
maintainer-clean: maintainer-clean-am
maintainer-clean-am: distclean-am maintainer-clean-generic
mostlyclean: mostlyclean-am
mostlyclean-am: mostlyclean-compile mostlyclean-generic \
mostlyclean-libtool
uninstall-am: uninstall-binPROGRAMS uninstall-gsmincludeHEADERS \
uninstall-info-am uninstall-libLTLIBRARIES
.PHONY: GTAGS all all-am check check-am clean clean-binPROGRAMS \
clean-generic clean-libLTLIBRARIES clean-libtool distclean \
distclean-compile distclean-depend distclean-generic \
distclean-libtool distclean-tags distdir dvi dvi-am info \
info-am install install-am install-binPROGRAMS install-data \
install-data-am install-exec install-exec-am \
install-gsmincludeHEADERS install-info install-info-am \
install-libLTLIBRARIES install-man install-strip installcheck \
installcheck-am installdirs maintainer-clean \
maintainer-clean-generic mostlyclean mostlyclean-compile \
mostlyclean-generic mostlyclean-libtool tags uninstall \
uninstall-am uninstall-binPROGRAMS uninstall-gsmincludeHEADERS \
uninstall-info-am uninstall-libLTLIBRARIES
# Tell versions [3.59,3.63) of GNU make to not export all variables.
# Otherwise a system limit (for SysV at least) may be exceeded.
.NOEXPORT:

View File

@ -0,0 +1,75 @@
Extended support for Siemens mobile phones via gsmlib
-----------------------------------------------------
* Hardware:
Supported phones: S25, S35, S45, ME45, SL45
Tested phones: S45, ME45
* Feature list:
- ACM: Output ACM (accumulated call meter) and ACMmax => maybe not
- BNR/BNW: Binary read and write => yes, xfer
- CID: Output card ID => maybe
- CKS: Output SIM card status => maybe
- CNI: Output call number information => maybe
- DBR: Database Read => yes, phonebook
- DLD: Delete the "last number redial" memory => maybe dangerous?
- GAUTH: Select Type of Authentication for PPP => no
- ICO: Icon control => no
- LCK: Switch locks on and off => yes, lock/unlock
- LNG: Language settings => maybe
- MGL: List SMS => no
- MGO: SMS overflow indicator => no
- MGR: Read SMS (same as AT+CMGR) => no
- MSO: Switch device off => maybe not
- NFS: Select NF hardware => maybe
- NFV: Set the volume => maybe
- PBC: Seek in telephone book => no
- PBG: Sorted telephone book => yes
- PBS: Select a telephone book => yes
- PIC: Output PIN counter => maybe
- PLM: Read the PLMN list => yes
- PLR/PLW: read/write preferred-operator list => yes
- PST: Play Signal Tone => yes
- PWD: Change password to a lock => maybe
- RTC: Set the ringing tone => yes
- STK: SIM toolkit => no
* Additional References
http://www.s45-world.net/vissie.htm
* Author and contact
Christian W. Zuckschwerdt <zany@triq.net>
http://triq.net/gsm.html

View File

@ -0,0 +1,258 @@
// *************************************************************************
// * GSM TA/ME library
// *
// * File: gsm_sie_me.cc
// *
// * Purpose: Mobile Equipment/Terminal Adapter and SMS functions
// * (According to "AT command set for S45 Siemens mobile phones"
// * v1.8, 26. July 2001 - Common AT prefix is "^S")
// *
// * Author: Christian W. Zuckschwerdt <zany@triq.net>
// *
// * Created: 2001-12-15
// *************************************************************************
#ifdef HAVE_CONFIG_H
#include <gsm_config.h>
#endif
#include <gsmlib/gsm_nls.h>
#include <gsmlib/gsm_me_ta.h>
#include <gsmlib/gsm_parser.h>
#include <gsmlib/gsm_util.h>
#include <gsm_sie_me.h>
#include <iostream>
using namespace std;
using namespace gsmlib;
// SieMe members
void SieMe::init() throw(GsmException)
{
}
SieMe::SieMe(Ref<Port> port) throw(GsmException) : MeTa::MeTa(port)
{
// initialize Siemens ME
init();
}
vector<string> SieMe::getSupportedPhonebooks() throw(GsmException)
{
Parser p(_at->chat("^SPBS=?", "^SPBS:"));
return p.parseStringList();
}
string SieMe::getCurrentPhonebook() throw(GsmException)
{
if (_lastPhonebookName == "")
{
Parser p(_at->chat("^SPBS?", "^SPBS:"));
// answer is e.g. ^SPBS: "SM",41,250
_lastPhonebookName = p.parseString();
p.parseComma();
int _currentNumberOfEntries = p.parseInt();
p.parseComma();
int _maxNumberOfEntries = p.parseInt();
}
return _lastPhonebookName;
}
void SieMe::setPhonebook(string phonebookName) throw(GsmException)
{
if (phonebookName != _lastPhonebookName)
{
_at->chat("^SPBS=\"" + phonebookName + "\"");
_lastPhonebookName = phonebookName;
}
}
IntRange SieMe:: getSupportedSignalTones() throw(GsmException)
{
Parser p(_at->chat("^SPST=?", "^SPST:"));
// ^SPST: (0-4),(0,1)
IntRange typeRange = p.parseRange();
p.parseComma();
vector<bool> volumeList = p.parseIntList();
return typeRange;
}
void SieMe:: playSignalTone(int tone) throw(GsmException)
{
_at->chat("^SPST=" + intToStr(tone) + ",1");
}
void SieMe:: stopSignalTone(int tone) throw(GsmException)
{
_at->chat("^SPST=" + intToStr(tone) + ",0");
}
IntRange SieMe::getSupportedRingingTones() throw(GsmException) // (AT^SRTC=?)
{
Parser p(_at->chat("^SRTC=?", "^SRTC:"));
// ^SRTC: (0-42),(1-5)
IntRange typeRange = p.parseRange();
p.parseComma();
IntRange volumeRange = p.parseRange();
return typeRange;
}
int SieMe::getCurrentRingingTone() throw(GsmException) // (AT^SRTC?)
{
Parser p(_at->chat("^SRTC?", "^SRTC:"));
// ^SRTC: 41,2,0
int type = p.parseInt();
p.parseComma();
int volume = p.parseInt();
p.parseComma();
int ringing = p.parseInt();
return type;
}
void SieMe::setRingingTone(int tone, int volume) throw(GsmException)
{
_at->chat("^SRTC=" + intToStr(tone) + "," + intToStr(volume));
}
void SieMe:: playRingingTone() throw(GsmException)
{
// get ringing bool
Parser p(_at->chat("^SRTC?", "^SRTC:"));
// ^SRTC: 41,2,0
int type = p.parseInt();
p.parseComma();
int volume = p.parseInt();
p.parseComma();
int ringing = p.parseInt();
if (ringing == 0)
toggleRingingTone();
}
void SieMe::stopRingingTone() throw(GsmException)
{
// get ringing bool
Parser p(_at->chat("^SRTC?", "^SRTC:"));
// ^SRTC: 41,2,0
int type = p.parseInt();
p.parseComma();
int volume = p.parseInt();
p.parseComma();
int ringing = p.parseInt();
if (ringing == 1)
toggleRingingTone();
}
void SieMe::toggleRingingTone() throw(GsmException) // (AT^SRTC)
{
_at->chat("^SRTC");
}
// Siemens get supported binary read
vector<ParameterRange> SieMe::getSupportedBinaryReads() throw(GsmException)
{
Parser p(_at->chat("^SBNR=?", "^SBNR:"));
// ^SBNR: ("bmp",(0-3)),("mid",(0-4)),("vcf",(0-500)),("vcs",(0-50))
return p.parseParameterRangeList();
}
// Siemens get supported binary write
vector<ParameterRange> SieMe::getSupportedBinaryWrites() throw(GsmException)
{
Parser p(_at->chat("^SBNW=?", "^SBNW:"));
// ^SBNW: ("bmp",(0-3)),("mid",(0-4)),("vcf",(0-500)),("vcs",(0-50)),("t9d",(0))
return p.parseParameterRangeList();
}
// Siemens Binary Read
BinaryObject SieMe::getBinary(string type, int subtype) throw(GsmException)
{
// expect several response lines
vector<string> result;
result = _at->chatv("^SBNR=\"" + type + "\"," + intToStr(subtype), "^SBNR:");
// "bmp",0,1,5 <CR><LF> pdu <CR><LF> "bmp",0,2,5 <CR><LF> ...
// most likely to be PDUs of 382 chars (191 * 2)
string pdu;
int fragmentCount = 0;
for (vector<string>::iterator i = result.begin(); i != result.end(); ++i)
{
++fragmentCount;
// parse header
Parser p(*i);
string fragmentType = p.parseString();
if (fragmentType != type)
throw GsmException(_("bad PDU type"), ChatError);
p.parseComma();
int fragmentSubtype = p.parseInt();
if (fragmentSubtype != subtype)
throw GsmException(_("bad PDU subtype"), ChatError);
p.parseComma();
int fragmentNumber = p.parseInt();
if (fragmentNumber != fragmentCount)
throw GsmException(_("bad PDU number"), ChatError);
p.parseComma();
int numberOfFragments = p.parseInt();
if (fragmentNumber > numberOfFragments)
throw GsmException(_("bad PDU number"), ChatError);
// concat pdu fragment
++i;
pdu += *i;
}
BinaryObject bnr;
bnr._type = type;
bnr._subtype = subtype;
bnr._size = pdu.length() / 2;
bnr._data = new unsigned char[pdu.length() / 2];
if (! hexToBuf(pdu, bnr._data))
throw GsmException(_("bad hexadecimal PDU format"), ChatError);
return bnr;
}
// Siemens Binary Write
void SieMe::setBinary(string type, int subtype, BinaryObject obj)
throw(GsmException)
{
if (obj._size <= 0)
throw GsmException(_("bad object"), ParameterError);
// Limitation: The maximum pdu size is 176 bytes (or 352 characters)
// this should be a configurable field
int maxPDUsize = 176;
int numberOfPDUs = (obj._size + maxPDUsize - 1) / maxPDUsize;
unsigned char *p = obj._data;
for (int i = 1; i <= numberOfPDUs; ++i)
{
// construct pdu
int size = maxPDUsize;
if (i == numberOfPDUs)
size = obj._size - (numberOfPDUs - 1) * maxPDUsize;
string pdu = bufToHex(p, size);
p += size;
cout << "processing " << i << " of " << numberOfPDUs
<< " of " << size << " bytes." << endl;
cout << "^SBNW=\"" + type + "\"," + intToStr(subtype) + ","
+ intToStr(i) + "," + intToStr(numberOfPDUs) << endl;
cout << pdu << endl;
_at->sendPdu("^SBNW=\"" + type + "\"," + intToStr(subtype) + ","
+ intToStr(i) + "," + intToStr(numberOfPDUs), "",
pdu, true);
cout << "OK" << endl;
}
}

View File

@ -0,0 +1,99 @@
// *************************************************************************
// * GSM TA/ME library
// *
// * File: gsm_sie_me.h
// *
// * Purpose: Mobile Equipment/Terminal Adapter and SMS functions
// * (According to "AT command set for S45 Siemens mobile phones"
// * v1.8, 26. July 2001 - Common AT prefix is "^S")
// *
// * Author: Christian W. Zuckschwerdt <zany@triq.net>
// *
// * Created: 2001-12-15
// *************************************************************************
#ifndef GSM_SIE_ME_H
#define GSM_SIE_ME_H
#include <gsmlib/gsm_error.h>
#include <gsmlib/gsm_at.h>
#include <string>
#include <vector>
using namespace std;
namespace gsmlib
{
// *** Siemens mobile phone binary objects (bitmap, midi, vcal, vcard)
struct BinaryObject
{
string _type; // Object type
int _subtype; // Object subtype (storage number)
unsigned char *_data; // Object binary data
int _size; // Object data size
};
// *** this class allows extended access to Siemens moblie phones
class SieMe : public MeTa
{
private:
// init ME/TA to sensible defaults
void init() throw(GsmException);
public:
// initialize a new MeTa object given the port
SieMe(Ref<Port> port) throw(GsmException);
// get the current phonebook in the Siemens ME
vector<string> getSupportedPhonebooks() throw(GsmException);// (AT^SPBS=?)
// get the current phonebook in the Siemens ME
string getCurrentPhonebook() throw(GsmException); // (AT^SPBS?)
// set the current phonebook in the Siemens ME
// remember the last phonebook set for optimisation
void setPhonebook(string phonebookName) throw(GsmException); // (AT^SPBS=)
// Siemens get supported signal tones
IntRange getSupportedSignalTones() throw(GsmException); // (AT^SPST=?)
// Siemens set ringing tone
void playSignalTone(int tone) throw(GsmException); // (AT^SRTC=x,1)
// Siemens set ringing tone
void stopSignalTone(int tone) throw(GsmException); // (AT^SRTC=x,0)
// Siemens get ringing tone
IntRange getSupportedRingingTones() throw(GsmException); // (AT^SRTC=?)
// Siemens get ringing tone
int getCurrentRingingTone() throw(GsmException); // (AT^SRTC?)
// Siemens set ringing tone
void setRingingTone(int tone, int volume) throw(GsmException);// (AT^SRTC=)
// Siemens set ringing tone on
void playRingingTone() throw(GsmException);
// Siemens set ringing tone of
void stopRingingTone() throw(GsmException);
// Siemens toggle ringing tone
void toggleRingingTone() throw(GsmException); // (AT^SRTC)
// Siemens get supported binary read
vector<ParameterRange> getSupportedBinaryReads() throw(GsmException);
// Siemens get supported binary write
vector<ParameterRange> getSupportedBinaryWrites() throw(GsmException);
// Siemens Binary Read
BinaryObject getBinary(string type, int subtype) throw(GsmException);
// Siemens Binary Write
void setBinary(string type, int subtype, BinaryObject obj)
throw(GsmException);
};
};
#endif // GSM_ME_TA_H

View File

@ -0,0 +1,698 @@
// *************************************************************************
// * GSM TA/ME library
// *
// * File: gsmsiectl.cc
// *
// * Purpose: GSM Siemens mobile phone control program
// *
// * Author: Christian W. Zuckschwerdt <zany@triq.net>
// *
// * Created: 2001-12-15
// *************************************************************************
#ifdef HAVE_CONFIG_H
#include <gsm_config.h>
#endif
#include <gsmlib/gsm_nls.h>
#include <string>
#if defined(HAVE_GETOPT_LONG) || defined(WIN32)
#include <getopt.h>
#endif
#include <strstream>
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <gsmlib/gsm_me_ta.h>
#include <gsm_sie_me.h>
#include <gsmlib/gsm_util.h>
#include <gsmlib/gsm_sysdep.h>
#ifdef WIN32
#include <gsmlib/gsm_win32_serial.h>
#else
#include <gsmlib/gsm_unix_serial.h>
#include <unistd.h>
#endif
#include <iostream>
using namespace std;
using namespace gsmlib;
// my ME
static SieMe *m;
// information parameters
enum InfoParameter {AllInfo, // print all info
MeInfo, // MeInfo must be first!
OperatorInfo,
CurrentOperatorInfo,
FacilityLockStateInfo,
FacilityLockCapabilityInfo,
PasswordInfo,
CLIPInfo,
CallForwardingInfo,
BatteryInfo,
BitErrorInfo,
SCAInfo,
CharSetInfo,
PhonebookInfo, // extended Siemens info
SignalToneInfo,
RingingToneInfo,
BinaryInfo,
SignalInfo}; // SignalInfo must be last!
// operation parameters
// FIXME operations not implemented yet
// options
#ifdef HAVE_GETOPT_LONG
static struct option longOpts[] =
{
{"xonxoff", no_argument, (int*)NULL, 'X'},
{"operation", required_argument, (int*)NULL, 'o'},
{"device", required_argument, (int*)NULL, 'd'},
{"baudrate", required_argument, (int*)NULL, 'b'},
{"init", required_argument, (int*)NULL, 'I'},
{"help", no_argument, (int*)NULL, 'h'},
{"version", no_argument, (int*)NULL, 'v'},
{(char*)NULL, 0, (int*)NULL, 0}
};
#else
#define getopt_long(argc, argv, options, longopts, indexptr) \
getopt(argc, argv, options)
#endif
// helper function, prints forwarding info
void printForwardReason(string s, ForwardInfo &info)
{
cout << s << " "
<< (info._active ? _("active ") : _("inactive "))
<< _("number: ") << info._number
<< _(" subaddr: ") << info._subAddr
<< _(" time: ") << info._time << endl;
}
// helper function, prints integer range
void printIntRange(IntRange ir)
{
cout << "(" << ir._low;
if (ir._high != NOT_SET)
cout << "-" << ir._high;
cout << ")";
}
// helper function, prints parameter range
void printParameterRange(ParameterRange pr)
{
cout << "(\"" << pr._parameter << "\",";
printIntRange(pr._range);
cout << ")";
}
// print information
static void printInfo(InfoParameter ip)
{
switch (ip)
{
case MeInfo:
{
MEInfo mei = m->getMEInfo();
cout << _("<ME0> Manufacturer: ") << mei._manufacturer << endl
<< _("<ME1> Model: ") << mei._model << endl
<< _("<ME2> Revision: ") << mei._revision << endl
<< _("<ME3> Serial Number: ") << mei._serialNumber << endl;
break;
}
case OperatorInfo:
{
int count = 0;
vector<OPInfo> opis = m->getAvailableOPInfo();
for (vector<OPInfo>::iterator i = opis.begin(); i != opis.end(); ++i)
{
cout << "<OP" << count << _("> Status: ");
switch (i->_status)
{
case UnknownOPStatus: cout << _("unknown"); break;
case CurrentOPStatus: cout << _("current"); break;
case AvailableOPStatus: cout << _("available"); break;
case ForbiddenOPStatus: cout << _("forbidden"); break;
}
cout << _(" Long name: '") << i->_longName << "' "
<< _(" Short name: '") << i->_shortName << "' "
<< _(" Numeric name: ") << i->_numericName << endl;
++count;
}
break;
}
case CurrentOperatorInfo:
{
OPInfo opi = m->getCurrentOPInfo();
cout << "<CURROP0>"
<< _(" Long name: '") << opi._longName << "' "
<< _(" Short name: '") << opi._shortName << "' "
<< _(" Numeric name: ") << opi._numericName
<< _(" Mode: ");
switch (opi._mode)
{
case AutomaticOPMode: cout << _("automatic"); break;
case ManualOPMode: cout << _("manual"); break;
case DeregisterOPMode: cout << _("deregister"); break;
case ManualAutomaticOPMode: cout << _("manual/automatic"); break;
}
cout << endl;
break;
}
case FacilityLockStateInfo:
{
int count = 0;
vector<string> fclc = m->getFacilityLockCapabilities();
for (vector<string>::iterator i = fclc.begin(); i != fclc.end(); ++i)
if (*i != "AB" && *i != "AG" && *i != "AC")
{
cout << "<FLSTAT" << count << "> '" << *i << "'";
try
{
if (m->getFacilityLockStatus(*i, VoiceFacility))
cout << _(" Voice");
}
catch (GsmException &e)
{
cout << _(" unknown");
}
try
{
if (m->getFacilityLockStatus(*i, DataFacility))
cout << _(" Data");
}
catch (GsmException &e)
{
cout << _(" unknown");
}
try
{
if (m->getFacilityLockStatus(*i, FaxFacility))
cout << _(" Fax");
}
catch (GsmException &e)
{
cout << _(" unknown");
}
cout << endl;
++count;
}
break;
}
case FacilityLockCapabilityInfo:
{
cout << "<FLCAP0> ";
vector<string> fclc = m->getFacilityLockCapabilities();
for (vector<string>::iterator i = fclc.begin(); i != fclc.end(); ++i)
cout << "'" << *i << "' ";
cout << endl;
break;
}
case PasswordInfo:
{
vector<PWInfo> pwi = m->getPasswords();
int count = 0;
for (vector<PWInfo>::iterator i = pwi.begin(); i != pwi.end(); ++i)
{
cout << "<PW" << count << "> '"
<< i->_facility << "' " << i->_maxPasswdLen << endl;
++count;
}
break;
}
case CLIPInfo:
{
cout << "<CLIP0> " << (m->getNetworkCLIP() ? _("on") : _("off")) << endl;
break;
}
case CallForwardingInfo:
{
for (int r = 0; r < 4; ++r)
{
string text;
switch (r)
{
case 0: text = _("UnconditionalReason"); break;
case 1: text = _("MobileBusyReason"); break;
case 2: text = _("NoReplyReason"); break;
case 3: text = _("NotReachableReason"); break;
}
ForwardInfo voice, fax, data;
m->getCallForwardInfo((ForwardReason)r, voice, fax, data);
cout << "<FORW" << r << ".";
printForwardReason("0> " + text + _(" Voice"), voice);
cout << "<FORW" << r << ".";
printForwardReason("1> " + text + _(" Data"), data);
cout << "<FORW" << r << ".";
printForwardReason("2> " + text + _(" Fax"), fax);
}
break;
}
case BatteryInfo:
{
cout << "<BATT0> ";
int bcs = m->getBatteryChargeStatus();
switch (bcs)
{
case 0: cout << _("0 ME is powered by the battery") << endl; break;
case 1: cout << _("1 ME has a battery connected, but is not powered by it")
<< endl; break;
case 2: cout << _("2 ME does not have a battery connected") << endl; break;
case 3:
cout << _("3 Recognized power fault, calls inhibited") << endl;
break;
}
cout << "<BATT1> " << m->getBatteryCharge() << endl;
break;
}
case BitErrorInfo:
{
cout << "<BITERR0> " << m->getBitErrorRate() << endl;
break;
}
case SCAInfo:
{
cout << "<SCA0> " << m->getServiceCentreAddress() << endl;
break;
}
case CharSetInfo:
{
cout << "<CSET0> ";
vector<string> cs = m->getSupportedCharSets();
for (vector<string>::iterator i = cs.begin(); i != cs.end(); ++i)
cout << "'" << *i << "' ";
cout << endl;
cout << "<CSET1> '" << m->getCurrentCharSet() << "'" << endl;
break;
}
case SignalInfo:
{
cout << "<SIG0> " << m->getSignalStrength() << endl;
break;
}
case PhonebookInfo:
{
cout << "<PBOOK0> ";
vector<string> pb = m->getSupportedPhonebooks();
for (vector<string>::iterator i = pb.begin(); i != pb.end(); ++i)
cout << "'" << *i << "' ";
cout << endl;
cout << "<PBOOK1> '" << m->getCurrentPhonebook() << "'" << endl;
break;
}
case SignalToneInfo:
{
cout << "<SIGNAL0> ";
IntRange st = m->getSupportedSignalTones();
printIntRange(st);
cout << endl;
// cout << "<SIGT1> '" << m->getCurrentSignalTone() << "'" << endl;
break;
}
case RingingToneInfo:
{
cout << "<RING0> ";
IntRange rt = m->getSupportedRingingTones();
printIntRange(rt);
cout << endl;
cout << "<RING1> " << m->getCurrentRingingTone() << endl;
break;
}
case BinaryInfo:
{
cout << "<BIN0> ";
vector<ParameterRange> bnr = m->getSupportedBinaryReads();
for (vector<ParameterRange>::iterator i = bnr.begin(); i != bnr.end(); ++i)
{
printParameterRange(*i);
cout << " ";
}
cout << endl;
cout << "<BIN1> ";
vector<ParameterRange> bnw = m->getSupportedBinaryWrites();
for (vector<ParameterRange>::iterator i = bnw.begin(); i != bnw.end(); ++i)
{
printParameterRange(*i);
cout << " ";
}
cout << endl;
break;
}
default:
assert(0);
break;
}
}
// convert facility class string of the form "", "all", or any combination
// of "v" (voice), "d" (data), or "f" (fax) to numeric form
FacilityClass strToFacilityClass(string facilityClassS)
{
facilityClassS = lowercase(facilityClassS);
FacilityClass facilityClass = (FacilityClass)0;
if (facilityClassS == "all" || facilityClassS == "")
return (FacilityClass)ALL_FACILITIES;
// OR in facility class bits
for (unsigned int i = 0; i < facilityClassS.length(); ++i)
if (facilityClassS[i] == 'v')
facilityClass = (FacilityClass)(facilityClass | VoiceFacility);
else if (facilityClassS[i] == 'd')
facilityClass = (FacilityClass)(facilityClass | DataFacility);
else if (facilityClassS[i] == 'f')
facilityClass = (FacilityClass)(facilityClass | FaxFacility);
else
throw GsmException(
stringPrintf(_("unknown facility class parameter '%c'"),
facilityClassS[i]), ParameterError);
return facilityClass;
}
// check if argc - optind is in range min..max
// throw exception otherwise
void checkParamCount(int optind, int argc, int min, int max)
{
int paramCount = argc - optind;
if (paramCount < min)
throw GsmException(stringPrintf(_("not enough parameters, minimum number "
"of parameters is %d"), min),
ParameterError);
else if (paramCount > max)
throw GsmException(stringPrintf(_("too many parameters, maximum number "
"of parameters is %d"), max),
ParameterError);
}
// *** main program
int main(int argc, char *argv[])
{
try
{
// handle command line options
string device = "/dev/mobilephone";
string operation;
string baudrate;
string initString = DEFAULT_INIT_STRING;
bool swHandshake = false;
int opt;
int dummy;
while((opt = getopt_long(argc, argv, "I:o:d:b:hvX", longOpts, &dummy))
!= -1)
switch (opt)
{
case 'X':
swHandshake = true;
break;
case 'I':
initString = optarg;
break;
case 'd':
device = optarg;
break;
case 'o':
operation = optarg;
break;
case 'b':
baudrate = optarg;
break;
case 'v':
cerr << argv[0] << stringPrintf(_(": version %s [compiled %s]"),
VERSION, __DATE__) << endl;
exit(0);
break;
case 'h':
cerr << argv[0] << _(": [-b baudrate][-d device][-h]"
"[-I init string][-o operation]\n"
" [-v][-X]{parameters}") << endl
<< endl
<< _(" -b, --baudrate baudrate to use for device "
"(default: 38400)")
<< endl
<< _(" -d, --device sets the destination device to "
"connect to") << endl
<< _(" -h, --help prints this message") << endl
<< _(" -I, --init device AT init sequence") << endl
<< _(" -o, --operation operation to perform on the mobile \n"
" phone with the specified parameters")
<< endl
<< _(" -v, --version prints version and exits") << endl
<< _(" -X, --xonxoff switch on software handshake") << endl
<< endl
<< _(" parameters parameters to use for the operation\n"
" (if an operation is given) or\n"
" a specification which kind of\n"
" information to read from the mobile "
"phone")
<< endl << endl
<< _("Refer to gsmctl(1) for details on the available parameters"
" and operations.")
<< endl << endl;
exit(0);
break;
case '?':
throw GsmException(_("unknown option"), ParameterError);
break;
}
// open the port and ME/TA
m = new SieMe(new
#ifdef WIN32
Win32SerialPort
#else
UnixSerialPort
#endif
(device,
baudrate == "" ?
DEFAULT_BAUD_RATE :
baudRateStrToSpeed(baudrate),
initString, swHandshake));
if (operation == "")
{ // process info parameters
for (int i = optind; i < argc; ++i)
{
string param = lowercase(argv[i]);
if (param == "all")
for (int ip = MeInfo; ip <= SignalInfo; ++ip)
printInfo((InfoParameter)ip);
else if (param == "me")
printInfo(MeInfo);
else if (param == "op")
printInfo(OperatorInfo);
else if (param == "currop")
printInfo(CurrentOperatorInfo);
else if (param == "flstat")
printInfo(FacilityLockStateInfo);
else if (param == "flcap")
printInfo(FacilityLockCapabilityInfo);
else if (param == "pw")
printInfo(PasswordInfo);
else if (param == "clip")
printInfo(CLIPInfo);
else if (param == "forw")
printInfo(CallForwardingInfo);
else if (param == "batt")
printInfo(BatteryInfo);
else if (param == "biterr")
printInfo(BitErrorInfo);
else if (param == "sig")
printInfo(SignalInfo);
else if (param == "sca")
printInfo(SCAInfo);
else if (param == "cset")
printInfo(CharSetInfo);
else if (param == "pbook")
printInfo(PhonebookInfo);
else if (param == "signal")
printInfo(SignalToneInfo);
else if (param == "ring")
printInfo(RingingToneInfo);
else if (param == "binary")
printInfo(BinaryInfo);
else
throw GsmException(
stringPrintf(_("unknown information parameter '%s'"),
param.c_str()),
ParameterError);
}
}
else
{ // process operation
operation = lowercase(operation);
if (operation == "dial")
{
// dial: number
checkParamCount(optind, argc, 1, 1);
m->dial(argv[optind]);
// wait for keypress from stdin
char c;
read(1, &c, 1);
}
else if (operation == "setop")
{
// setop: opmode numeric FIXME allow long and numeric too
checkParamCount(optind, argc, 2, 2);
string opmodeS = lowercase(argv[optind]);
OPModes opmode;
if (opmodeS == "automatic")
opmode = AutomaticOPMode;
else if (opmodeS == "manual")
opmode = ManualOPMode;
else if (opmodeS == "deregister")
opmode = DeregisterOPMode;
else if (opmodeS == "manualautomatic")
opmode = ManualAutomaticOPMode;
else
throw GsmException(stringPrintf(_("unknown opmode parameter '%s'"),
opmodeS.c_str()), ParameterError);
m->setCurrentOPInfo(opmode, "" , "", checkNumber(argv[optind + 1]));
}
else if (operation == "lock")
{
// lock: facility [facilityclass] [passwd]
checkParamCount(optind, argc, 1, 3);
string passwd = (argc - optind == 3) ?
(string)argv[optind + 2] : (string)"";
m->lockFacility(argv[optind],
(argc - optind >= 2) ?
strToFacilityClass(argv[optind + 1]) :
(FacilityClass)ALL_FACILITIES,
passwd);
}
else if (operation == "unlock")
{
// unlock: facility [facilityclass] [passwd]
checkParamCount(optind, argc, 1, 3);
string passwd = argc - optind == 3 ? argv[optind + 2] : "";
m->unlockFacility(argv[optind],
(argc - optind >= 2) ?
strToFacilityClass(argv[optind + 1]) :
(FacilityClass)ALL_FACILITIES,
passwd);
}
else if (operation == "setpw")
{
// set password: facility oldpasswd newpasswd
checkParamCount(optind, argc, 1, 3);
string oldPasswd = argc - optind >= 2 ? argv[optind + 1] : "";
string newPasswd = argc - optind == 3 ? argv[optind + 2] : "";
m->setPassword(argv[optind], oldPasswd, newPasswd);
}
else if (operation == "forw")
{
// call forwarding: mode reason number [facilityclass] [forwardtime]
checkParamCount(optind, argc, 2, 5);
// get optional parameters facility class and forwardtime
int forwardTime = argc - optind == 5 ? checkNumber(argv[optind + 4]) :
NOT_SET;
FacilityClass facilityClass =
argc - optind >= 4 ? strToFacilityClass(argv[optind + 3]) :
(FacilityClass)ALL_FACILITIES;
// get forward reason
string reasonS = lowercase(argv[optind + 1]);
ForwardReason reason;
if (reasonS == "unconditional")
reason = UnconditionalReason;
else if (reasonS == "mobilebusy")
reason = MobileBusyReason;
else if (reasonS == "noreply")
reason = NoReplyReason;
else if (reasonS == "notreachable")
reason = NotReachableReason;
else if (reasonS == "all")
reason = AllReasons;
else if (reasonS == "allconditional")
reason = AllConditionalReasons;
else
throw GsmException(
stringPrintf(_("unknown forward reason parameter '%s'"),
reasonS.c_str()), ParameterError);
// get mode
string modeS = lowercase(argv[optind]);
ForwardMode mode;
if (modeS == "disable")
mode = DisableMode;
else if (modeS == "enable")
mode = EnableMode;
else if (modeS == "register")
mode = RegistrationMode;
else if (modeS == "erase")
mode = ErasureMode;
else
throw GsmException(
stringPrintf(_("unknown forward mode parameter '%s'"),
modeS.c_str()), ParameterError);
m->setCallForwarding(reason, mode,
(argc - optind >= 3) ? argv[optind + 2] : "",
"", // subaddr
facilityClass, forwardTime);
}
else if (operation == "setsca")
{
// set sca: number
checkParamCount(optind, argc, 1, 1);
m->setServiceCentreAddress(argv[optind]);
}
else if (operation == "cset")
{
// set charset: string
checkParamCount(optind, argc, 1, 1);
m->setCharSet(argv[optind]);
}
else if (operation == "signal")
{
// play signal tone: int
checkParamCount(optind, argc, 1, 1);
int tone = atoi(argv[optind]);
m->playSignalTone(tone);
}
else if (operation == "setrt")
{
// set ringing tone: int int
checkParamCount(optind, argc, 2, 2);
int tone = atoi(argv[optind]);
int volume = atoi(argv[optind + 1]);
m->setRingingTone(tone, volume);
}
else if (operation == "playrt")
{
// play/stop ringing tone
m->toggleRingingTone();
}
else
throw GsmException(stringPrintf(_("unknown operation '%s'"),
operation.c_str()), ParameterError);
}
}
catch (GsmException &ge)
{
cerr << argv[0] << _("[ERROR]: ") << ge.what() << endl;
return 1;
}
return 0;
}

View File

@ -0,0 +1,292 @@
// *************************************************************************
// * GSM TA/ME library
// *
// * File: gsmsiexfer.cc
// *
// * Purpose: Siemens ME file transfer program
// *
// * Author: Christian W. Zuckschwerdt <zany@triq.net>
// *
// * Created: 2001-12-16
// *************************************************************************
#ifdef HAVE_CONFIG_H
#include <gsm_config.h>
#endif
#include <gsmlib/gsm_nls.h>
#include <string>
#ifdef WIN32
#include <gsmlib/gsm_win32_serial.h>
#else
#include <gsmlib/gsm_unix_serial.h>
#include <unistd.h>
#endif
#if defined(HAVE_GETOPT_LONG) || defined(WIN32)
#include <getopt.h>
#endif
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <gsmlib/gsm_me_ta.h>
#include <gsm_sie_me.h>
#include <gsmlib/gsm_util.h>
#include <gsmlib/gsm_sorted_phonebook.h>
#include <iostream>
using namespace std;
using namespace gsmlib;
#ifdef HAVE_GETOPT_LONG
static struct option longOpts[] =
{
{"xonxoff", no_argument, (int*)NULL, 'X'},
{"init", required_argument, (int*)NULL, 'I'},
{"destination", required_argument, (int*)NULL, 'd'},
{"source", required_argument, (int*)NULL, 's'},
{"baudrate", required_argument, (int*)NULL, 'b'},
{"type", required_argument, (int*)NULL, 't'},
{"subtype", required_argument, (int*)NULL, 'i'},
{"help", no_argument, (int*)NULL, 'h'},
{"version", no_argument, (int*)NULL, 'v'},
{"verbose", no_argument, (int*)NULL, 'V'},
{(char*)NULL, 0, (int*)NULL, 0}
};
#else
#define getopt_long(argc, argv, options, longopts, indexptr) \
getopt(argc, argv, options)
#endif
// I f*ck up this file IO thing.
// read binary object from stdin
BinaryObject readBinaryFile(istream &ifs, string filename)
{
size_t size = 10000; // Bad coder, no biscuits!
BinaryObject bnr;
bnr._data = new unsigned char[size];
ifs.read((char*)bnr._data, size);
bnr._size = ifs.gcount();
return bnr;
}
// read binary object from file
BinaryObject readFile(string filename)
{
// open the file
ifstream ifs(filename.c_str());
if (ifs.bad())
throw GsmException(stringPrintf(_("cannot open file '%s'"),
filename.c_str()),
OSError);
// and read the file
return readBinaryFile(ifs, filename);
}
// read binary object from stdin
BinaryObject readFile(bool fromStdin)
{
// read from stdin
// if (fromStdin)
return readBinaryFile(cin, (string)_("<STDIN>"));
}
// write binary object to file
void writeBinaryFile(ostream &ofs, string filename, BinaryObject bnw)
{
// well just dump the data
ofs.write((char*)bnw._data, bnw._size);
}
// write binary object
void writeFile(string filename, BinaryObject obj)
{
// open the file
ofstream ofs(filename.c_str());
if (ofs.bad())
throw GsmException(stringPrintf(_("cannot open file '%s'"),
filename.c_str()),
OSError);
// and read the file
writeBinaryFile(ofs, filename, obj);
}
// write binary object to stdout
void writeFile(bool toStdout, BinaryObject obj)
{
// if (toStdout)
writeBinaryFile(cout, (string)_("<STDIN>"), obj);
}
// *** main program
int main(int argc, char *argv[])
{
try
{
// handle command line options
string destination;
string source;
string baudrate;
string type;
string subtype;
int subtypeN;
bool verbose = false;
string initString = DEFAULT_INIT_STRING;
bool swHandshake = false;
Ref<SieMe> sourceMeTa, destMeTa;
BinaryObject sourceObject;
int opt;
int dummy;
while((opt = getopt_long(argc, argv, "XI:s:d:b:hvVt:i:", longOpts,
&dummy))
!= -1)
switch (opt)
{
case 'X':
swHandshake = true;
break;
case 'I':
initString = optarg;
break;
case 'V':
verbose = true;
break;
case 't':
type = optarg;
break;
case 'i':
subtype = optarg;
subtypeN = atoi(optarg);
break;
case 'd':
destination = optarg;
break;
case 's':
source = optarg;
break;
case 'b':
baudrate = optarg;
break;
case 'v':
cerr << argv[0] << stringPrintf(_(": version %s [compiled %s]"),
VERSION, __DATE__) << endl;
exit(0);
break;
case 'h':
cerr << argv[0] << _(": [-b baudrate][-c][-d device or file][-h]"
"[-I init string]\n"
" [-p phonebook name][-s device or file]"
"[-t charset][-v]"
"[-V][-y][-X]") << endl
<< endl
<< _(" -b, --baudrate baudrate to use for device "
"(default: 38400)")
<< endl
<< _(" -c, --copy copy source entries to destination")
<< endl
<< _(" -d, --destination sets the destination device to "
"connect \n"
" to, or the file to write") << endl
<< _(" -D, --destination-backend sets the destination backend")
<< endl
<< _(" -h, --help prints this message") << endl
<< _(" -i, --index takes index positions into account")
<< endl
<< _(" -I, --init device AT init sequence") << endl
<< _(" -p, --phonebook name of phonebook to use") << endl
<< _(" -s, --source sets the source device to connect to,\n"
" or the file to read") << endl
<< _(" -t, --charset sets the character set to use for\n"
" phonebook entries") << endl
<< _(" -S, --source-backend sets the source backend")
<< endl
<< _(" -v, --version prints version and exits") << endl
<< _(" -V, --verbose print detailed progress messages")
<< endl
<< _(" -X, --xonxoff switch on software handshake") << endl
<< _(" -y, --synchronize synchronize destination with source\n"
" entries (destination is overwritten)\n"
" (see gsmpb(1) for details)")
<< endl << endl;
exit(0);
break;
case '?':
throw GsmException(_("unknown option"), ParameterError);
break;
}
// check if all parameters all present
if (destination == "" || source == "")
throw GsmException(_("both source and destination must be given"),
ParameterError);
// start accessing source mobile phone or file
if (source == "-")
sourceObject = readFile(true);
else if (isFile(source))
sourceObject = readFile(source);
else
{
if (type == "")
throw GsmException(_("type be given"), ParameterError);
if (subtype == "")
throw GsmException(_("subtype be given"), ParameterError);
sourceMeTa = new SieMe(new
#ifdef WIN32
Win32SerialPort
#else
UnixSerialPort
#endif
(source,
baudrate == "" ? DEFAULT_BAUD_RATE :
baudRateStrToSpeed(baudrate), initString,
swHandshake));
sourceObject = sourceMeTa->getBinary(type, subtypeN);
}
// make sure destination.c_str file exists
if (destination != "")
{
try
{
ofstream f(destination.c_str(), ios::out | ios::app);
}
catch (exception)
{
}
}
// start accessing destination mobile phone or file
if (destination == "-")
writeFile(true, sourceObject);
else if (isFile(destination))
writeFile(destination, sourceObject);
else
{
if (type == "")
throw GsmException(_("type must be given"), ParameterError);
if (subtype == "")
throw GsmException(_("subtype must be given"), ParameterError);
destMeTa = new SieMe(new
#ifdef WIN32
Win32SerialPort
#else
UnixSerialPort
#endif
(destination,
baudrate == "" ? DEFAULT_BAUD_RATE :
baudRateStrToSpeed(baudrate), initString,
swHandshake));
destMeTa->setBinary(type, subtypeN, sourceObject);
}
}
catch (GsmException &ge)
{
cerr << argv[0] << _("[ERROR]: ") << ge.what() << endl;
return 1;
}
return 0;
}

View File

@ -0,0 +1,29 @@
--- ./gsmlib/gsm_me_ta.h~ 2006-03-09 19:15:59.000000000 +0000
+++ ./gsmlib/gsm_me_ta.h 2006-03-09 19:16:31.000000000 +0000
@@ -291,8 +291,8 @@
// 3 disable phone receive RF circuits only
// 4 disable phone both transmit and receive RF circuits
// 5...127 implementation-defined
- int MeTa::getFunctionalityLevel() throw(GsmException);
- void MeTa::setFunctionalityLevel(int level) throw(GsmException);
+ int getFunctionalityLevel() throw(GsmException);
+ void setFunctionalityLevel(int level) throw(GsmException);
// return battery charge status (+CBC):
// 0 ME is powered by the battery
@@ -386,13 +386,13 @@
void setCallWaitingLockStatus(FacilityClass cl,
bool lock)throw(GsmException);
- void MeTa::setCLIRPresentation(bool enable) throw(GsmException);
+ void setCLIRPresentation(bool enable) throw(GsmException);
//(+CLIR)
// 0:according to the subscription of the CLIR service
// 1:CLIR invocation
// 2:CLIR suppression
- int MeTa::getCLIRPresentation() throw(GsmException);
+ int getCLIRPresentation() throw(GsmException);
friend class Phonebook;
friend class SMSStore;

View File

@ -0,0 +1,344 @@
/* gsm_config.h.in. Generated from configure.in by autoheader. */
/* used by libtool*/
#define PACKAGE 0
/* used by libtool*/
#define VERSION 0
/* Define if getopt_long() available */
#undef HAVE_GETOPT_LONG
/* Define if alarm() available */
#undef HAVE_ALARM
/* Define if netinet/in.h header available */
#undef HAVE_NETINET_IN_H
/* Define if string.h header available */
#undef HAVE_STRING_H
/* Define for NLS */
#undef ENABLE_NLS
#undef HAVE_CATGETS
#undef HAVE_GETTEXT
#undef HAVE_LC_MESSAGES
#undef HAVE_STPCPY
/* Define LOCALEDIR */
#define LOCALEDIR "/usr/share/locale"
/* Define if libintl.h header available */
#undef HAVE_LIBINTL_H
/* Define if vsnprintf() function available */
#undef HAVE_VSNPRINTF
/* Define to one of `_getb67', `GETB67', `getb67' for Cray-2 and Cray-YMP
systems. This function is required for `alloca.c' support on those systems.
*/
#undef CRAY_STACKSEG_END
/* Define to 1 if using `alloca.c'. */
#undef C_ALLOCA
/* Define to 1 if translation of program messages to the user's native
language is requested. */
#undef ENABLE_NLS
/* Define to 1 if you have `alloca', as a function or macro. */
#undef HAVE_ALLOCA
/* Define to 1 if you have <alloca.h> and it should be used (not on Ultrix).
*/
#undef HAVE_ALLOCA_H
/* Define to 1 if you have the <argz.h> header file. */
#undef HAVE_ARGZ_H
/* Define to 1 if you have the `asprintf' function. */
#undef HAVE_ASPRINTF
/* Define to 1 if you have the MacOS X function CFLocaleCopyCurrent in the
CoreFoundation framework. */
#undef HAVE_CFLOCALECOPYCURRENT
/* Define to 1 if you have the MacOS X function CFPreferencesCopyAppValue in
the CoreFoundation framework. */
#undef HAVE_CFPREFERENCESCOPYAPPVALUE
/* Define if the GNU dcgettext() function is already present or preinstalled.
*/
#undef HAVE_DCGETTEXT
/* Define to 1 if you have the declaration of `feof_unlocked', and to 0 if you
don't. */
#undef HAVE_DECL_FEOF_UNLOCKED
/* Define to 1 if you have the declaration of `fgets_unlocked', and to 0 if
you don't. */
#undef HAVE_DECL_FGETS_UNLOCKED
/* Define to 1 if you have the declaration of `getc_unlocked', and to 0 if you
don't. */
#undef HAVE_DECL_GETC_UNLOCKED
/* Define to 1 if you have the declaration of `_snprintf', and to 0 if you
don't. */
#undef HAVE_DECL__SNPRINTF
/* Define to 1 if you have the declaration of `_snwprintf', and to 0 if you
don't. */
#undef HAVE_DECL__SNWPRINTF
/* Define to 1 if you have the <dlfcn.h> header file. */
#undef HAVE_DLFCN_H
/* Define to 1 if you have the `fwprintf' function. */
#undef HAVE_FWPRINTF
/* Define to 1 if you have the `getcwd' function. */
#undef HAVE_GETCWD
/* Define to 1 if you have the `getegid' function. */
#undef HAVE_GETEGID
/* Define to 1 if you have the `geteuid' function. */
#undef HAVE_GETEUID
/* Define to 1 if you have the `getgid' function. */
#undef HAVE_GETGID
/* Define to 1 if you have the `getpagesize' function. */
#undef HAVE_GETPAGESIZE
/* Define if the GNU gettext() function is already present or preinstalled. */
#undef HAVE_GETTEXT
/* Define to 1 if you have the `getuid' function. */
#undef HAVE_GETUID
/* Define if you have the iconv() function. */
#undef HAVE_ICONV
/* Define if you have the 'intmax_t' type in <stdint.h> or <inttypes.h>. */
#undef HAVE_INTMAX_T
/* Define if <inttypes.h> exists and doesn't clash with <sys/types.h>. */
#undef HAVE_INTTYPES_H
/* Define if <inttypes.h> exists, doesn't clash with <sys/types.h>, and
declares uintmax_t. */
#undef HAVE_INTTYPES_H_WITH_UINTMAX
/* Define if you have <langinfo.h> and nl_langinfo(CODESET). */
#undef HAVE_LANGINFO_CODESET
/* Define if your <locale.h> file defines LC_MESSAGES. */
#undef HAVE_LC_MESSAGES
/* Define to 1 if you have the `intl' library (-lintl). */
#undef HAVE_LIBINTL
/* Define to 1 if you have the <libintl.h> header file. */
#undef HAVE_LIBINTL_H
/* Define to 1 if you have the <limits.h> header file. */
#undef HAVE_LIMITS_H
/* Define to 1 if you have the <locale.h> header file. */
#undef HAVE_LOCALE_H
/* Define if you have the 'long double' type. */
#undef HAVE_LONG_DOUBLE
/* Define if you have the 'long long' type. */
#undef HAVE_LONG_LONG
/* Define to 1 if you have the <malloc.h> header file. */
#undef HAVE_MALLOC_H
/* Define to 1 if you have the <memory.h> header file. */
#undef HAVE_MEMORY_H
/* Define to 1 if you have the `mempcpy' function. */
#undef HAVE_MEMPCPY
/* Define to 1 if you have a working `mmap' system call. */
#undef HAVE_MMAP
/* Define to 1 if you have the `munmap' function. */
#undef HAVE_MUNMAP
/* Define to 1 if you have the <netinet/in.h> header file. */
#undef HAVE_NETINET_IN_H
/* Define to 1 if you have the <nl_types.h> header file. */
#undef HAVE_NL_TYPES_H
/* Define if your printf() function supports format strings with positions. */
#undef HAVE_POSIX_PRINTF
/* Define to 1 if you have the `putenv' function. */
#undef HAVE_PUTENV
/* Define to 1 if you have the `setenv' function. */
#undef HAVE_SETENV
/* Define to 1 if you have the `setlocale' function. */
#undef HAVE_SETLOCALE
/* Define to 1 if you have the `snprintf' function. */
#undef HAVE_SNPRINTF
/* Define to 1 if you have the <stddef.h> header file. */
#undef HAVE_STDDEF_H
/* Define to 1 if you have the <stdint.h> header file. */
#undef HAVE_STDINT_H
/* Define if <stdint.h> exists, doesn't clash with <sys/types.h>, and declares
uintmax_t. */
#undef HAVE_STDINT_H_WITH_UINTMAX
/* Define to 1 if you have the <stdlib.h> header file. */
#undef HAVE_STDLIB_H
/* Define to 1 if you have the `stpcpy' function. */
#undef HAVE_STPCPY
/* Define to 1 if you have the `strcasecmp' function. */
#undef HAVE_STRCASECMP
/* Define to 1 if you have the `strdup' function. */
#undef HAVE_STRDUP
/* Define to 1 if you have the <strings.h> header file. */
#undef HAVE_STRINGS_H
/* Define to 1 if you have the <string.h> header file. */
#undef HAVE_STRING_H
/* Define to 1 if you have the `strtoul' function. */
#undef HAVE_STRTOUL
/* Define to 1 if you have the <sys/param.h> header file. */
#undef HAVE_SYS_PARAM_H
/* Define to 1 if you have the <sys/stat.h> header file. */
#undef HAVE_SYS_STAT_H
/* Define to 1 if you have the <sys/types.h> header file. */
#undef HAVE_SYS_TYPES_H
/* Define to 1 if you have the `tsearch' function. */
#undef HAVE_TSEARCH
/* Define if you have the 'uintmax_t' type in <stdint.h> or <inttypes.h>. */
#undef HAVE_UINTMAX_T
/* Define to 1 if you have the <unistd.h> header file. */
#undef HAVE_UNISTD_H
/* Define if you have the 'unsigned long long' type. */
#undef HAVE_UNSIGNED_LONG_LONG
/* Define if you have the 'wchar_t' type. */
#undef HAVE_WCHAR_T
/* Define to 1 if you have the `wcslen' function. */
#undef HAVE_WCSLEN
/* Define if you have the 'wint_t' type. */
#undef HAVE_WINT_T
/* Define to 1 if you have the `__argz_count' function. */
#undef HAVE___ARGZ_COUNT
/* Define to 1 if you have the `__argz_next' function. */
#undef HAVE___ARGZ_NEXT
/* Define to 1 if you have the `__argz_stringify' function. */
#undef HAVE___ARGZ_STRINGIFY
/* Define to 1 if you have the `__fsetlocking' function. */
#undef HAVE___FSETLOCKING
/* Define as const if the declaration of iconv() needs const. */
#undef ICONV_CONST
/* Define if integer division by zero raises signal SIGFPE. */
#undef INTDIV0_RAISES_SIGFPE
/* Name of package */
#undef PACKAGE
/* Define to the address where bug reports for this package should be sent. */
#undef PACKAGE_BUGREPORT
/* Define to the full name of this package. */
#undef PACKAGE_NAME
/* Define to the full name and version of this package. */
#undef PACKAGE_STRING
/* Define to the one symbol short name of this package. */
#undef PACKAGE_TARNAME
/* Define to the version of this package. */
#undef PACKAGE_VERSION
/* Define if <inttypes.h> exists and defines unusable PRI* macros. */
#undef PRI_MACROS_BROKEN
/* The size of a `unsigned int', as computed by sizeof. */
#undef SIZEOF_UNSIGNED_INT
/* The size of a `unsigned long int', as computed by sizeof. */
#undef SIZEOF_UNSIGNED_LONG_INT
/* The size of a `unsigned short int', as computed by sizeof. */
#undef SIZEOF_UNSIGNED_SHORT_INT
/* Define as the maximum value of type 'size_t', if the system doesn't define
it. */
#undef SIZE_MAX
/* If using the C implementation of alloca, define if you know the
direction of stack growth for your system; otherwise it will be
automatically deduced at run-time.
STACK_DIRECTION > 0 => grows toward higher addresses
STACK_DIRECTION < 0 => grows toward lower addresses
STACK_DIRECTION = 0 => direction of growth unknown */
#undef STACK_DIRECTION
/* Define to 1 if you have the ANSI C header files. */
#undef STDC_HEADERS
/* Version number of package */
#undef VERSION
/* Define to empty if `const' does not conform to ANSI C. */
#undef const
/* Define to `__inline__' or `__inline' if that's what the C compiler
calls it, or to nothing if 'inline' is not supported under any name. */
#ifndef __cplusplus
#undef inline
#endif
/* Define to `long' if <sys/types.h> does not define. */
#undef off_t
/* Define as the type of the result of subtracting two pointers, if the system
doesn't define it. */
#undef ptrdiff_t
/* Define to empty if the C compiler doesn't support this keyword. */
#undef signed
/* Define to `unsigned' if <sys/types.h> does not define. */
#undef size_t
/* Define to unsigned long or unsigned long long if <stdint.h> and
<inttypes.h> don't define. */
#undef uintmax_t

View File

@ -0,0 +1,11 @@
var/spool/sms/queue1
var/spool/sms/queue2
var/spool/sms/queue3
var/spool/sms/sent1
var/spool/sms/sent2
var/spool/sms/sent3
var/spool/sms/failed1
var/spool/sms/failed2
var/spool/sms/failed3
var/spool/sms/tmp
var/run/gsm-utils

View File

@ -0,0 +1,28 @@
#!/bin/sh -e
# create gsmsms group if necessary.
if ! grep -q ^gsmsms: /etc/group; then
# echo Adding system group: gsmsms.
addgroup gsmsms
fi
# create gsmsms user if necessary.
if ! grep -q ^gsmsms: /etc/passwd; then
# echo Adding system user: gsmsms.
adduser --system --ingroup gsmsms \
--no-create-home --home /var/spool/sms gsmsms
fi
# allow gsmsms to use serial lines
if ! groups gsmsms | grep -q dialout ; then
adduser gsmsms dialout
fi
# echo Updating spool directory structure: /var/spool/sms
chown -R gsmsms:gsmsms /var/spool/sms /var/run/gsm-utils
chmod 700 /var/spool/sms/*
chmod 750 /var/spool/sms
chmod 730 /var/spool/sms/queue* /var/spool/sms/tmp
# Add the rest automatically..
#DEBHELPER#

View File

@ -0,0 +1,7 @@
#!/bin/sh -e
deluser gsmsms || true
delgroup gsmsms || true
# Add the rest automatically..
#DEBHELPER#

View File

@ -0,0 +1,92 @@
%define LIBVER 1.0.4
Summary: Library to access GSM mobile phones through GSM modems
Name: gsmlib
Version: 1.10
Release: 1
Source: gsmlib-%{version}.tar.gz
Group: System Environment/Libraries
Copyright: GNU LIBRARY GENERAL PUBLIC LICENSE
URL: http://www.pxh.de/fs/gsmlib/
Vendor: Peter Hofmann <software@pxh.de>
Buildroot: /var/tmp/gsmlib-root
%package devel
Summary: Development tools for programs which will use the gsmlib library.
Group: Development/Libraries
Requires: gsmlib
%package ext
Summary: Extensions to gsmlib to support non-standard phone features.
Group: Development/Libraries
Requires: gsmlib
%description
This distribution contains a library to access
GSM mobile phones through GSM modems. Features include:
* modification of phonebooks stored in the
mobile phone or on the SIM card
* reading and writing of SMS messages stored in
the mobile phone
* sending and reception of SMS messages
Additionally, some simple command line programs are
provided to use these functionalities.
%description devel
The gsmlib-devel package includes the header files and static libraries
necessary for developing programs which use the gsmlib library.
%description ext
The extension package of gsmlib contains programs, libraries, and
documentation to support non-standard features of GSM phones. The
following phones/phone types are currently supported:
* Siemens GSM phones
%prep
%setup
%build
CXXFLAGS="$RPM_OPT_FLAGS" ./configure --prefix=/usr
make
%install
make DESTDIR="$RPM_BUILD_ROOT" install
%post -p /sbin/ldconfig
%postun -p /sbin/ldconfig
%clean
rm -rf $RPM_BUILD_ROOT
%files
%defattr(-,root,root)
/usr/lib/libgsmme.so
/usr/lib/libgsmme.so.%{LIBVER}
/usr/bin/gsmsmsstore
/usr/bin/gsmctl
/usr/bin/gsmsmsd
/usr/bin/gsmpb
/usr/bin/gsmsendsms
/usr/man/man1/gsmctl.1.gz
/usr/man/man7/gsminfo.7.gz
/usr/man/man1/gsmpb.1.gz
/usr/man/man1/gsmsendsms.1.gz
/usr/man/man8/gsmsmsd.8.gz
/usr/man/man1/gsmsmsstore.1.gz
/usr/share/locale/de/LC_MESSAGES/gsmlib.mo
%doc README INSTALL ABOUT-NLS AUTHORS COPYING NEWS TODO
%doc doc/README.NLS doc/README.developers doc/FAQ ChangeLog
%files devel
%defattr(-,root,root)
/usr/lib/libgsmme.a
/usr/include/gsmlib
%files ext
/usr/bin/gsmsiectl
/usr/bin/gsmsiexfer
/usr/lib/libgsmext.so
/usr/lib/libgsmext.so.%{LIBVER}
%doc ext/README.sieme

View File

@ -0,0 +1,38 @@
## Process this file with automake to produce Makefile.in
# *************************************************************************
# * GSM TA/ME library
# *
# * File: Makefile.am
# *
# * Purpose: GSM library Makefile
# *
# * Author: Peter Hofmann (software@pxh.de)
# *
# * Created: 5.5.1999
# *************************************************************************
INCLUDES = -I..
lib_LTLIBRARIES = libgsmme.la
libgsmme_la_SOURCES = gsm_phonebook.cc gsm_util.cc gsm_unix_serial.cc \
gsm_me_ta.cc gsm_at.cc gsm_error.cc gsm_parser.cc \
gsm_sms.cc gsm_sms_codec.cc gsm_sms_store.cc \
gsm_event.cc gsm_sorted_phonebook.cc \
gsm_sorted_sms_store.cc gsm_nls.cc \
gsm_sorted_phonebook_base.cc gsm_cb.cc
gsmincludedir = $(includedir)/gsmlib
gsminclude_HEADERS = gsm_at.h gsm_parser.h gsm_sms.h gsm_unix_serial.h \
gsm_error.h gsm_phonebook.h gsm_sms_codec.h \
gsm_util.h gsm_me_ta.h gsm_port.h gsm_sms_store.h \
gsm_event.h gsm_sorted_phonebook.h \
gsm_sorted_sms_store.h gsm_map_key.h \
gsm_sorted_phonebook_base.h gsm_cb.h
noinst_HEADERS = gsm_nls.h gsm_sysdep.h
libgsmme_la_LDFLAGS = -version-info $(GSM_VERSION)
EXTRA_DIST = gsm_win32_serial.h gsm_win32_serial.cc

View File

@ -0,0 +1,461 @@
# Makefile.in generated by automake 1.6.3 from Makefile.am.
# @configure_input@
# Copyright 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002
# Free Software Foundation, Inc.
# This Makefile.in is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
# with or without modifications, as long as this notice is preserved.
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
# PARTICULAR PURPOSE.
@SET_MAKE@
# *************************************************************************
# * GSM TA/ME library
# *
# * File: Makefile.am
# *
# * Purpose: GSM library Makefile
# *
# * Author: Peter Hofmann (software@pxh.de)
# *
# * Created: 5.5.1999
# *************************************************************************
SHELL = @SHELL@
srcdir = @srcdir@
top_srcdir = @top_srcdir@
VPATH = @srcdir@
prefix = @prefix@
exec_prefix = @exec_prefix@
bindir = @bindir@
sbindir = @sbindir@
libexecdir = @libexecdir@
datadir = @datadir@
sysconfdir = @sysconfdir@
sharedstatedir = @sharedstatedir@
localstatedir = @localstatedir@
libdir = @libdir@
infodir = @infodir@
mandir = @mandir@
includedir = @includedir@
oldincludedir = /usr/include
pkgdatadir = $(datadir)/@PACKAGE@
pkglibdir = $(libdir)/@PACKAGE@
pkgincludedir = $(includedir)/@PACKAGE@
top_builddir = ..
ACLOCAL = @ACLOCAL@
AUTOCONF = @AUTOCONF@
AUTOMAKE = @AUTOMAKE@
AUTOHEADER = @AUTOHEADER@
am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
INSTALL = @INSTALL@
INSTALL_PROGRAM = @INSTALL_PROGRAM@
INSTALL_DATA = @INSTALL_DATA@
install_sh_DATA = $(install_sh) -c -m 644
install_sh_PROGRAM = $(install_sh) -c
install_sh_SCRIPT = $(install_sh) -c
INSTALL_SCRIPT = @INSTALL_SCRIPT@
INSTALL_HEADER = $(INSTALL_DATA)
transform = @program_transform_name@
NORMAL_INSTALL = :
PRE_INSTALL = :
POST_INSTALL = :
NORMAL_UNINSTALL = :
PRE_UNINSTALL = :
POST_UNINSTALL = :
host_alias = @host_alias@
host_triplet = @host@
EXEEXT = @EXEEXT@
OBJEXT = @OBJEXT@
PATH_SEPARATOR = @PATH_SEPARATOR@
AMTAR = @AMTAR@
AS = @AS@
AWK = @AWK@
BUILD_INCLUDED_LIBINTL = @BUILD_INCLUDED_LIBINTL@
CATOBJEXT = @CATOBJEXT@
CC = @CC@
CPP = @CPP@
CXX = @CXX@
DATADIRNAME = @DATADIRNAME@
DEPDIR = @DEPDIR@
DLLTOOL = @DLLTOOL@
ECHO = @ECHO@
GENCAT = @GENCAT@
GLIBC21 = @GLIBC21@
GMSGFMT = @GMSGFMT@
GSM_VERSION = @GSM_VERSION@
HAVE_LIB = @HAVE_LIB@
INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
INSTOBJEXT = @INSTOBJEXT@
INTLBISON = @INTLBISON@
INTLLIBS = @INTLLIBS@
INTLOBJS = @INTLOBJS@
INTL_LIBTOOL_SUFFIX_PREFIX = @INTL_LIBTOOL_SUFFIX_PREFIX@
LIB = @LIB@
LIBICONV = @LIBICONV@
LIBINTL = @LIBINTL@
LIBTOOL = @LIBTOOL@
LN_S = @LN_S@
LTLIB = @LTLIB@
LTLIBICONV = @LTLIBICONV@
LTLIBINTL = @LTLIBINTL@
MKINSTALLDIRS = @MKINSTALLDIRS@
OBJDUMP = @OBJDUMP@
PACKAGE = @PACKAGE@
POSUB = @POSUB@
RANLIB = @RANLIB@
STRIP = @STRIP@
USE_INCLUDED_LIBINTL = @USE_INCLUDED_LIBINTL@
USE_NLS = @USE_NLS@
VERSION = @VERSION@
am__include = @am__include@
am__quote = @am__quote@
install_sh = @install_sh@
INCLUDES = -I..
lib_LTLIBRARIES = libgsmme.la
libgsmme_la_SOURCES = gsm_phonebook.cc gsm_util.cc gsm_unix_serial.cc \
gsm_me_ta.cc gsm_at.cc gsm_error.cc gsm_parser.cc \
gsm_sms.cc gsm_sms_codec.cc gsm_sms_store.cc \
gsm_event.cc gsm_sorted_phonebook.cc \
gsm_sorted_sms_store.cc gsm_nls.cc \
gsm_sorted_phonebook_base.cc gsm_cb.cc
gsmincludedir = $(includedir)/gsmlib
gsminclude_HEADERS = gsm_at.h gsm_parser.h gsm_sms.h gsm_unix_serial.h \
gsm_error.h gsm_phonebook.h gsm_sms_codec.h \
gsm_util.h gsm_me_ta.h gsm_port.h gsm_sms_store.h \
gsm_event.h gsm_sorted_phonebook.h \
gsm_sorted_sms_store.h gsm_map_key.h \
gsm_sorted_phonebook_base.h gsm_cb.h
noinst_HEADERS = gsm_nls.h gsm_sysdep.h
libgsmme_la_LDFLAGS = -version-info $(GSM_VERSION)
EXTRA_DIST = gsm_win32_serial.h gsm_win32_serial.cc
subdir = gsmlib
mkinstalldirs = $(SHELL) $(top_srcdir)/scripts/mkinstalldirs
CONFIG_HEADER = $(top_builddir)/gsm_config.h
CONFIG_CLEAN_FILES =
LTLIBRARIES = $(lib_LTLIBRARIES)
libgsmme_la_LIBADD =
am_libgsmme_la_OBJECTS = gsm_phonebook.lo gsm_util.lo gsm_unix_serial.lo \
gsm_me_ta.lo gsm_at.lo gsm_error.lo gsm_parser.lo gsm_sms.lo \
gsm_sms_codec.lo gsm_sms_store.lo gsm_event.lo \
gsm_sorted_phonebook.lo gsm_sorted_sms_store.lo gsm_nls.lo \
gsm_sorted_phonebook_base.lo gsm_cb.lo
libgsmme_la_OBJECTS = $(am_libgsmme_la_OBJECTS)
DEFS = @DEFS@
DEFAULT_INCLUDES = -I. -I$(srcdir) -I$(top_builddir)
CPPFLAGS = @CPPFLAGS@
LDFLAGS = @LDFLAGS@
LIBS = @LIBS@
depcomp = $(SHELL) $(top_srcdir)/scripts/depcomp
am__depfiles_maybe = depfiles
@AMDEP_TRUE@DEP_FILES = ./$(DEPDIR)/gsm_at.Plo ./$(DEPDIR)/gsm_cb.Plo \
@AMDEP_TRUE@ ./$(DEPDIR)/gsm_error.Plo ./$(DEPDIR)/gsm_event.Plo \
@AMDEP_TRUE@ ./$(DEPDIR)/gsm_me_ta.Plo ./$(DEPDIR)/gsm_nls.Plo \
@AMDEP_TRUE@ ./$(DEPDIR)/gsm_parser.Plo \
@AMDEP_TRUE@ ./$(DEPDIR)/gsm_phonebook.Plo \
@AMDEP_TRUE@ ./$(DEPDIR)/gsm_sms.Plo \
@AMDEP_TRUE@ ./$(DEPDIR)/gsm_sms_codec.Plo \
@AMDEP_TRUE@ ./$(DEPDIR)/gsm_sms_store.Plo \
@AMDEP_TRUE@ ./$(DEPDIR)/gsm_sorted_phonebook.Plo \
@AMDEP_TRUE@ ./$(DEPDIR)/gsm_sorted_phonebook_base.Plo \
@AMDEP_TRUE@ ./$(DEPDIR)/gsm_sorted_sms_store.Plo \
@AMDEP_TRUE@ ./$(DEPDIR)/gsm_unix_serial.Plo \
@AMDEP_TRUE@ ./$(DEPDIR)/gsm_util.Plo
CXXCOMPILE = $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \
$(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS)
LTCXXCOMPILE = $(LIBTOOL) --mode=compile $(CXX) $(DEFS) \
$(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \
$(AM_CXXFLAGS) $(CXXFLAGS)
CXXLD = $(CXX)
CXXLINK = $(LIBTOOL) --mode=link $(CXXLD) $(AM_CXXFLAGS) $(CXXFLAGS) \
$(AM_LDFLAGS) $(LDFLAGS) -o $@
CXXFLAGS = @CXXFLAGS@
DIST_SOURCES = $(libgsmme_la_SOURCES)
HEADERS = $(gsminclude_HEADERS) $(noinst_HEADERS)
DIST_COMMON = $(gsminclude_HEADERS) $(noinst_HEADERS) Makefile.am \
Makefile.in
SOURCES = $(libgsmme_la_SOURCES)
all: all-am
.SUFFIXES:
.SUFFIXES: .cc .lo .o .obj
$(srcdir)/Makefile.in: Makefile.am $(top_srcdir)/configure.in $(ACLOCAL_M4)
cd $(top_srcdir) && \
$(AUTOMAKE) --gnu gsmlib/Makefile
Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)
libLTLIBRARIES_INSTALL = $(INSTALL)
install-libLTLIBRARIES: $(lib_LTLIBRARIES)
@$(NORMAL_INSTALL)
$(mkinstalldirs) $(DESTDIR)$(libdir)
@list='$(lib_LTLIBRARIES)'; for p in $$list; do \
if test -f $$p; then \
f="`echo $$p | sed -e 's|^.*/||'`"; \
echo " $(LIBTOOL) --mode=install $(libLTLIBRARIES_INSTALL) $(INSTALL_STRIP_FLAG) $$p $(DESTDIR)$(libdir)/$$f"; \
$(LIBTOOL) --mode=install $(libLTLIBRARIES_INSTALL) $(INSTALL_STRIP_FLAG) $$p $(DESTDIR)$(libdir)/$$f; \
else :; fi; \
done
uninstall-libLTLIBRARIES:
@$(NORMAL_UNINSTALL)
@list='$(lib_LTLIBRARIES)'; for p in $$list; do \
p="`echo $$p | sed -e 's|^.*/||'`"; \
echo " $(LIBTOOL) --mode=uninstall rm -f $(DESTDIR)$(libdir)/$$p"; \
$(LIBTOOL) --mode=uninstall rm -f $(DESTDIR)$(libdir)/$$p; \
done
clean-libLTLIBRARIES:
-test -z "$(lib_LTLIBRARIES)" || rm -f $(lib_LTLIBRARIES)
@list='$(lib_LTLIBRARIES)'; for p in $$list; do \
dir="`echo $$p | sed -e 's|/[^/]*$$||'`"; \
test -z "$dir" && dir=.; \
echo "rm -f \"$${dir}/so_locations\""; \
rm -f "$${dir}/so_locations"; \
done
libgsmme.la: $(libgsmme_la_OBJECTS) $(libgsmme_la_DEPENDENCIES)
$(CXXLINK) -rpath $(libdir) $(libgsmme_la_LDFLAGS) $(libgsmme_la_OBJECTS) $(libgsmme_la_LIBADD) $(LIBS)
mostlyclean-compile:
-rm -f *.$(OBJEXT) core *.core
distclean-compile:
-rm -f *.tab.c
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gsm_at.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gsm_cb.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gsm_error.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gsm_event.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gsm_me_ta.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gsm_nls.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gsm_parser.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gsm_phonebook.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gsm_sms.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gsm_sms_codec.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gsm_sms_store.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gsm_sorted_phonebook.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gsm_sorted_phonebook_base.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gsm_sorted_sms_store.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gsm_unix_serial.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gsm_util.Plo@am__quote@
distclean-depend:
-rm -rf ./$(DEPDIR)
.cc.o:
@AMDEP_TRUE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@ depfile='$(DEPDIR)/$*.Po' tmpdepfile='$(DEPDIR)/$*.TPo' @AMDEPBACKSLASH@
@AMDEP_TRUE@ $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
$(CXXCOMPILE) -c -o $@ `test -f '$<' || echo '$(srcdir)/'`$<
.cc.obj:
@AMDEP_TRUE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@ depfile='$(DEPDIR)/$*.Po' tmpdepfile='$(DEPDIR)/$*.TPo' @AMDEPBACKSLASH@
@AMDEP_TRUE@ $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
$(CXXCOMPILE) -c -o $@ `cygpath -w $<`
.cc.lo:
@AMDEP_TRUE@ source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@
@AMDEP_TRUE@ depfile='$(DEPDIR)/$*.Plo' tmpdepfile='$(DEPDIR)/$*.TPlo' @AMDEPBACKSLASH@
@AMDEP_TRUE@ $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
$(LTCXXCOMPILE) -c -o $@ `test -f '$<' || echo '$(srcdir)/'`$<
CXXDEPMODE = @CXXDEPMODE@
mostlyclean-libtool:
-rm -f *.lo
clean-libtool:
-rm -rf .libs _libs
distclean-libtool:
-rm -f libtool
uninstall-info-am:
gsmincludeHEADERS_INSTALL = $(INSTALL_HEADER)
install-gsmincludeHEADERS: $(gsminclude_HEADERS)
@$(NORMAL_INSTALL)
$(mkinstalldirs) $(DESTDIR)$(gsmincludedir)
@list='$(gsminclude_HEADERS)'; for p in $$list; do \
if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
f="`echo $$p | sed -e 's|^.*/||'`"; \
echo " $(gsmincludeHEADERS_INSTALL) $$d$$p $(DESTDIR)$(gsmincludedir)/$$f"; \
$(gsmincludeHEADERS_INSTALL) $$d$$p $(DESTDIR)$(gsmincludedir)/$$f; \
done
uninstall-gsmincludeHEADERS:
@$(NORMAL_UNINSTALL)
@list='$(gsminclude_HEADERS)'; for p in $$list; do \
f="`echo $$p | sed -e 's|^.*/||'`"; \
echo " rm -f $(DESTDIR)$(gsmincludedir)/$$f"; \
rm -f $(DESTDIR)$(gsmincludedir)/$$f; \
done
ETAGS = etags
ETAGSFLAGS =
tags: TAGS
ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
unique=`for i in $$list; do \
if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
done | \
$(AWK) ' { files[$$0] = 1; } \
END { for (i in files) print i; }'`; \
mkid -fID $$unique
TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
$(TAGS_FILES) $(LISP)
tags=; \
here=`pwd`; \
list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
unique=`for i in $$list; do \
if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
done | \
$(AWK) ' { files[$$0] = 1; } \
END { for (i in files) print i; }'`; \
test -z "$(ETAGS_ARGS)$$tags$$unique" \
|| $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
$$tags $$unique
GTAGS:
here=`$(am__cd) $(top_builddir) && pwd` \
&& cd $(top_srcdir) \
&& gtags -i $(GTAGS_ARGS) $$here
distclean-tags:
-rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH
DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
top_distdir = ..
distdir = $(top_distdir)/$(PACKAGE)-$(VERSION)
distdir: $(DISTFILES)
@list='$(DISTFILES)'; for file in $$list; do \
if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
dir=`echo "$$file" | sed -e 's,/[^/]*$$,,'`; \
if test "$$dir" != "$$file" && test "$$dir" != "."; then \
dir="/$$dir"; \
$(mkinstalldirs) "$(distdir)$$dir"; \
else \
dir=''; \
fi; \
if test -d $$d/$$file; then \
if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \
fi; \
cp -pR $$d/$$file $(distdir)$$dir || exit 1; \
else \
test -f $(distdir)/$$file \
|| cp -p $$d/$$file $(distdir)/$$file \
|| exit 1; \
fi; \
done
check-am: all-am
check: check-am
all-am: Makefile $(LTLIBRARIES) $(HEADERS)
installdirs:
$(mkinstalldirs) $(DESTDIR)$(libdir) $(DESTDIR)$(gsmincludedir)
install: install-am
install-exec: install-exec-am
install-data: install-data-am
uninstall: uninstall-am
install-am: all-am
@$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
installcheck: installcheck-am
install-strip:
$(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
INSTALL_STRIP_FLAG=-s \
`test -z '$(STRIP)' || \
echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install
mostlyclean-generic:
clean-generic:
distclean-generic:
-rm -f Makefile $(CONFIG_CLEAN_FILES)
maintainer-clean-generic:
@echo "This command is intended for maintainers to use"
@echo "it deletes files that may require special tools to rebuild."
clean: clean-am
clean-am: clean-generic clean-libLTLIBRARIES clean-libtool \
mostlyclean-am
distclean: distclean-am
distclean-am: clean-am distclean-compile distclean-depend \
distclean-generic distclean-libtool distclean-tags
dvi: dvi-am
dvi-am:
info: info-am
info-am:
install-data-am: install-gsmincludeHEADERS
install-exec-am: install-libLTLIBRARIES
install-info: install-info-am
install-man:
installcheck-am:
maintainer-clean: maintainer-clean-am
maintainer-clean-am: distclean-am maintainer-clean-generic
mostlyclean: mostlyclean-am
mostlyclean-am: mostlyclean-compile mostlyclean-generic \
mostlyclean-libtool
uninstall-am: uninstall-gsmincludeHEADERS uninstall-info-am \
uninstall-libLTLIBRARIES
.PHONY: GTAGS all all-am check check-am clean clean-generic \
clean-libLTLIBRARIES clean-libtool distclean distclean-compile \
distclean-depend distclean-generic distclean-libtool \
distclean-tags distdir dvi dvi-am info info-am install \
install-am install-data install-data-am install-exec \
install-exec-am install-gsmincludeHEADERS install-info \
install-info-am install-libLTLIBRARIES install-man \
install-strip installcheck installcheck-am installdirs \
maintainer-clean maintainer-clean-generic mostlyclean \
mostlyclean-compile mostlyclean-generic mostlyclean-libtool \
tags uninstall uninstall-am uninstall-gsmincludeHEADERS \
uninstall-info-am uninstall-libLTLIBRARIES
# Tell versions [3.59,3.63) of GNU make to not export all variables.
# Otherwise a system limit (for SysV at least) may be exceeded.
.NOEXPORT:

View File

@ -0,0 +1,428 @@
// *************************************************************************
// * GSM TA/ME library
// *
// * File: gsm_at.cc
// *
// * Purpose: Utility classes for AT command sequence handling
// *
// * Author: Peter Hofmann (software@pxh.de)
// *
// * Created: 3.5.1999
// *************************************************************************
#ifdef HAVE_CONFIG_H
#include <gsm_config.h>
#endif
#include <gsmlib/gsm_at.h>
#include <gsmlib/gsm_nls.h>
#include <gsmlib/gsm_util.h>
#include <gsmlib/gsm_error.h>
#include <gsmlib/gsm_event.h>
#include <gsmlib/gsm_me_ta.h>
#include <ctype.h>
#include <strstream>
using namespace std;
using namespace gsmlib;
// GsmAt members
bool GsmAt::matchResponse(string answer, string responseToMatch)
{
if (answer.substr(0, responseToMatch.length()) == responseToMatch)
return true;
else
// some TAs omit the ':' at the end of the response
if (_meTa.getCapabilities()._omitsColon &&
responseToMatch[responseToMatch.length() - 1] == ':' &&
answer.substr(0, responseToMatch.length() - 1) ==
responseToMatch.substr(0, responseToMatch.length() - 1))
return true;
return false;
}
string GsmAt::cutResponse(string answer, string responseToMatch)
{
if (answer.substr(0, responseToMatch.length()) == responseToMatch)
return normalize(answer.substr(responseToMatch.length(),
answer.length() -
responseToMatch.length()));
else
// some TAs omit the ':' at the end of the response
if (_meTa.getCapabilities()._omitsColon &&
responseToMatch[responseToMatch.length() - 1] == ':' &&
answer.substr(0, responseToMatch.length() - 1) ==
responseToMatch.substr(0, responseToMatch.length() - 1))
return normalize(answer.substr(responseToMatch.length() - 1,
answer.length() -
responseToMatch.length() + 1));
assert(0);
return "";
}
void GsmAt::throwCmeException(string s) throw(GsmException)
{
if (matchResponse(s, "ERROR"))
throw GsmException(_("unspecified ME/TA error"), ChatError);
bool meError = matchResponse(s, "+CME ERROR:");
if (meError)
s = cutResponse(s, "+CME ERROR:");
else
s = cutResponse(s, "+CMS ERROR:");
istrstream is(s.c_str());
int error;
is >> error;
throw GsmException(_("ME/TA error '") +
(meError ? getMEErrorText(error) :
getSMSErrorText(error)) +
"' " +
stringPrintf(_("(code %s)"), s.c_str()),
ChatError, error);
}
GsmAt::GsmAt(MeTa &meTa) :
_meTa(meTa), _port(meTa.getPort()), _eventHandler(NULL)
{
}
string GsmAt::chat(string atCommand, string response,
bool ignoreErrors, bool acceptEmptyResponse)
throw(GsmException)
{
string dummy;
return chat(atCommand, response, dummy, ignoreErrors, false,
acceptEmptyResponse);
}
string GsmAt::chat(string atCommand, string response, string &pdu,
bool ignoreErrors, bool expectPdu,
bool acceptEmptyResponse) throw(GsmException)
{
string s;
bool gotOk = false; // special handling for empty SMS entries
// send AT command
putLine("AT" + atCommand);
// and gobble up CR/LF (and possibly echoed characters if echo can't be
// switched off)
do
{
s = normalize(getLine());
}
while (s.length() == 0 || s == "AT" + atCommand);
// handle errors
if (matchResponse(s, "+CME ERROR:") || matchResponse(s, "+CMS ERROR:"))
if (ignoreErrors)
return "";
else
throwCmeException(s);
if (matchResponse(s, "ERROR"))
if (ignoreErrors)
return "";
else
throw GsmException(_("ME/TA error '<unspecified>' (code not known)"),
ChatError, -1);
// return if response is "OK" and caller says this is OK
if (acceptEmptyResponse && s == "OK")
return "";
// handle PDU if one is expected
if (expectPdu)
{
string ps;
do
{
ps = normalize(getLine());
}
while (ps.length() == 0 && ps != "OK");
if (ps == "OK")
gotOk = true;
else
{
pdu = ps;
// remove trailing zero added by some devices (e.g. Falcom A2-1)
if (pdu.length() > 0 && pdu[pdu.length() - 1] == 0)
pdu.erase(pdu.length() - 1);
}
}
// handle expected response
if (response.length() == 0) // no response expected
{
if (s == "OK") return "";
// else fall through to error
}
else
{
string result;
// some TA/TEs don't prefix their response with the response string
// as proscribed by the standard: just handle either case
if (matchResponse(s, response))
result = cutResponse(s, response);
else
result = s;
if (gotOk)
return result;
else
{
// get the final "OK"
do
{
s = normalize(getLine());
}
while (s.length() == 0);
if (s == "OK") return result;
// else fall through to error
}
}
throw GsmException(
stringPrintf(_("unexpected response '%s' when sending 'AT%s'"),
s.c_str(), atCommand.c_str()),
ChatError);
}
vector<string> GsmAt::chatv(string atCommand, string response,
bool ignoreErrors) throw(GsmException)
{
string s;
vector<string> result;
// send AT command
putLine("AT" + atCommand);
// and gobble up CR/LF (and possibly echoed characters if echo can't be
// switched off)
do
{
s = normalize(getLine());
}
while (s.length() == 0 || s == "AT" + atCommand);
// handle errors
if (matchResponse(s, "+CME ERROR:") || matchResponse(s, "+CMS ERROR:"))
if (ignoreErrors)
return result;
else
throwCmeException(s);
if (matchResponse(s, "ERROR"))
if (ignoreErrors)
return result;
else
throw GsmException(_("ME/TA error '<unspecified>' (code not known)"),
ChatError, -1);
// push all lines that are not empty
// cut response prefix if it is there
// stop when an OK line is read
while (1)
{
if (s == "OK")
return result;
// some TA/TEs don't prefix their response with the response string
// as proscribed by the standard: just handle either case
if (response.length() != 0 && matchResponse(s, response))
result.push_back(cutResponse(s, response));
else
result.push_back(s);
// get next line
do
{
s = normalize(getLine());
}
while (s.length() == 0);
reportProgress();
}
// never reached
assert(0);
return result;
}
string GsmAt::normalize(string s)
{
size_t start = 0, end = s.length();
bool changed = true;
while (start < end && changed)
{
changed = false;
if (isspace(s[start]))
{
++start;
changed = true;
}
else
if (isspace(s[end - 1]))
{
--end;
changed = true;
}
}
return s.substr(start, end - start);
}
string GsmAt::sendPdu(string atCommand, string response, string pdu,
bool acceptEmptyResponse) throw(GsmException)
{
string s;
bool errorCondition;
bool retry = false;
int tries = 5; // How many error conditions do we accept
int c;
do
{
errorCondition = false;
putLine("AT" + atCommand);
do
{
retry = false;
try
{
do
{
// read first of two bytes "> "
c = readByte();
}
// there have been reports that some phones give spurious CRs
// LF separates CDSI messages if there are more than one
while (c == CR || c == LF);
}
catch (GsmException &e)
{
c = '-';
errorCondition = true; // TA does not expect PDU anymore, retry
}
if (c == '+' || c == 'E') // error or unsolicited result code
{
_port->putBack(c);
s = normalize(getLine());
errorCondition = (s != "");
retry = ! errorCondition;
}
}
while (retry);
}
while (errorCondition && tries--);
if (! errorCondition)
{
if (c != '>' || readByte() != ' ')
throw GsmException(_("unexpected character in PDU handshake"),
ChatError);
putLine(pdu + "\032", false); // write pdu followed by CTRL-Z
// some phones (Ericcson T68, T39) send spurious zero characters after
// accepting the PDU
c = readByte();
if (c != 0)
_port->putBack(c);
// loop while empty lines (maybe with a zero, Ericsson T39m)
// or an echo of the pdu (with or without CTRL-Z)
// is read
do
{
s = normalize(getLine());
}
while (s.length() == 0 || s == pdu || s == (pdu + "\032") ||
(s.length() == 1 && s[0] == 0));
}
// handle errors
if (matchResponse(s, "+CME ERROR:") || matchResponse(s, "+CMS ERROR:"))
throwCmeException(s);
if (matchResponse(s, "ERROR"))
throw GsmException(_("ME/TA error '<unspecified>' (code not known)"),
ChatError, -1);
// return if response is "OK" and caller says this is OK
if (acceptEmptyResponse && s == "OK")
return "";
if (matchResponse(s, response))
{
string result = cutResponse(s, response);
// get the final "OK"
do
{
s = normalize(getLine());
}
while (s.length() == 0);
if (s == "OK") return result;
// else fall through to error
}
throw GsmException(
stringPrintf(_("unexpected response '%s' when sending 'AT%s'"),
s.c_str(), atCommand.c_str()),
ChatError);
}
string GsmAt::getLine() throw(GsmException)
{
if (_eventHandler == (GsmEvent*)NULL)
return _port->getLine();
else
{
bool eventOccurred;
string result;
do
{
eventOccurred = false;
result = _port->getLine();
string s = normalize(result);
if (matchResponse(s, "+CMT:") ||
matchResponse(s, "+CBM:") ||
matchResponse(s, "+CDS:") ||
matchResponse(s, "+CMTI:") ||
matchResponse(s, "+CBMI:") ||
matchResponse(s, "+CDSI:") ||
matchResponse(s, "RING") ||
matchResponse(s, "NO CARRIER") ||
// hack: the +CLIP? sequence returns +CLIP: n,m
// which is NOT an unsolicited result code
(matchResponse(s, "+CLIP:") && s.length() > 10))
{
_eventHandler->dispatch(s, *this);
eventOccurred = true;
}
}
while (eventOccurred);
return result;
}
}
void GsmAt::putLine(string line,
bool carriageReturn) throw(GsmException)
{
_port->putLine(line, carriageReturn);
// remove empty echo line
if (carriageReturn)
getLine();
}
bool GsmAt::wait(GsmTime timeout) throw(GsmException)
{
return _port->wait(timeout);
}
int GsmAt::readByte() throw(GsmException)
{
return _port->readByte();
}
GsmEvent *GsmAt::setEventHandler(GsmEvent *newHandler)
{
GsmEvent *result = _eventHandler;
_eventHandler = newHandler;
return result;
}

View File

@ -0,0 +1,104 @@
// *************************************************************************
// * GSM TA/ME library
// *
// * File: gsm_at.h
// *
// * Purpose: Utility classes for AT command sequence handling
// *
// * Author: Peter Hofmann (software@pxh.de)
// *
// * Created: 3.5.1999
// *************************************************************************
#ifndef GSM_AT_H
#define GSM_AT_H
#include <gsmlib/gsm_port.h>
#include <string>
#include <vector>
using namespace std;
namespace gsmlib
{
// forward declarations
class GsmEvent;
class MeTa;
// utiliy class to handle AT sequences
class GsmAt : public RefBase
{
protected:
MeTa &_meTa;
Ref<Port> _port;
GsmEvent *_eventHandler;
// return true if response matches
bool matchResponse(string answer, string responseToMatch);
// cut response and normalize
string cutResponse(string answer, string responseToMatch);
// parse CME error contained in string and throw MeTaException
void throwCmeException(string s) throw(GsmException);
public:
GsmAt(MeTa &meTa);
// return MeTa object for this AT object
MeTa &getMeTa() {return _meTa;}
// the following sequence functions recognize asynchronous messages
// from the TA and return the appropriate event
// send AT command, wait for response response, returns response line
// without response match
// if response == "" only an OK is expected
// white space at beginning or end are removed
// +CME ERROR or ERROR raises exception (if ignoreErrors == true)
// additionally, accept empty responses (just an OK)
// if acceptEmptyResponse == true
// in this case an empty string is returned
string chat(string atCommand = "",
string response = "",
bool ignoreErrors = false,
bool acceptEmptyResponse = false) throw(GsmException);
// same as chat() above but also get pdu if expectPdu == true
string chat(string atCommand,
string response,
string &pdu,
bool ignoreErrors = false,
bool expectPdu = true,
bool acceptEmptyResponse = false) throw(GsmException);
// same as above, but expect several response lines
vector<string> chatv(string atCommand = "",
string response = "",
bool ignoreErrors = false)
throw(GsmException);
// removes whitespace at beginning and end of string
string normalize(string s);
// send pdu (wait for <CR><LF><greater_than><space> and send <CTRL-Z>
// at the end
// return text after response
string sendPdu(string atCommand, string response, string pdu,
bool acceptEmptyResponse = false) throw(GsmException);
// functions from class Port
string getLine() throw(GsmException);
void putLine(string line,
bool carriageReturn = true) throw(GsmException);
bool wait(GsmTime timeout) throw(GsmException);
int readByte() throw(GsmException);
// set event handler class, return old one
GsmEvent *setEventHandler(GsmEvent *newHandler);
};
};
#endif // GSM_AT_H

View File

@ -0,0 +1,176 @@
// *************************************************************************
// * GSM TA/ME library
// *
// * File: gsm_cb.cc
// *
// * Purpose: Cell Broadcast Message Implementation
// *
// * Author: Peter Hofmann (software@pxh.de)
// *
// * Created: 4.8.2001
// *************************************************************************
#ifdef HAVE_CONFIG_H
#include <gsm_config.h>
#endif
#include <gsmlib/gsm_sysdep.h>
#include <gsmlib/gsm_cb.h>
#include <gsmlib/gsm_nls.h>
#include <strstream>
using namespace std;
using namespace gsmlib;
// local constants
static const string dashes =
"---------------------------------------------------------------------------";
// CBDataCodingScheme members
CBDataCodingScheme::CBDataCodingScheme(unsigned char dcs) : _dcs(dcs)
{
if ((_dcs & 0xf0) <= 0x30) // bits 7..4 in the range 0000..0011
if ((_dcs & 0x30) == 0)
_language = (Language)_dcs;
else
_language = Unknown;
}
string CBDataCodingScheme::toString() const
{
string result;
if (compressed()) result += _("compressed ");
switch (getLanguage())
{
case German:
result += _("German");
break;
case English:
result += _("English");
break;
case Italian:
result += _("Italian");
break;
case French:
result += _("French");
break;
case Spanish:
result += _("Spanish");
break;
case Dutch:
result += _("Dutch");
break;
case Swedish:
result += _("Swedish");
break;
case Danish:
result += _("Danish");
break;
case Portuguese:
result += _("Portuguese");
break;
case Finnish:
result += _("Finnish");
break;
case Norwegian:
result += _("Norwegian");
break;
case Greek:
result += _("Greek");
break;
case Turkish:
result += _("Turkish");
break;
}
result += " ";
switch (getAlphabet())
{
case DCS_DEFAULT_ALPHABET:
result += _("default alphabet");
break;
case DCS_EIGHT_BIT_ALPHABET:
result += _("8-bit alphabet");
break;
case DCS_SIXTEEN_BIT_ALPHABET:
result += _("16-bit alphabet");
break;
case DCS_RESERVED_ALPHABET:
result += _("reserved alphabet");
break;
}
return result;
}
// CBMessage members
CBMessage::CBMessage(string pdu) throw(GsmException)
{
SMSDecoder d(pdu);
_messageCode = d.getInteger(6) << 4;
_geographicalScope = (GeographicalScope)d.get2Bits();
_updateNumber = d.getInteger(4);
_messageCode |= d.getInteger(4);
_messageIdentifier = d.getInteger(8) << 8;
_messageIdentifier |= d.getInteger(8);
_dataCodingScheme = CBDataCodingScheme(d.getOctet());
_totalPageNumber = d.getInteger(4);
_currentPageNumber = d.getInteger(4);
// the values 82 and 93 come from ETSI GSM 03.41, section 9.3
d.markSeptet();
if (_dataCodingScheme.getAlphabet() == DCS_DEFAULT_ALPHABET)
{
_data = d.getString(93);
_data = gsmToLatin1(_data);
}
else
{
unsigned char *s =
(unsigned char*)alloca(sizeof(unsigned char) * 82);
d.getOctets(s, 82);
_data.assign((char*)s, (unsigned int)82);
}
}
string CBMessage::toString() const
{
ostrstream os;
os << dashes << endl
<< _("Message type: CB") << endl
<< _("Geographical scope: ");
switch (_geographicalScope)
{
case CellWide:
os << "Cell wide" << endl;
break;
case PLMNWide:
os << "PLMN wide" << endl;
break;
case LocationAreaWide:
os << "Location area wide" << endl;
break;
case CellWide2:
os << "Cell wide (2)" << endl;
break;
}
// remove trailing \r characters for output
string data = _data;
string::iterator i;
for (i = data.end(); i > data.begin() && *(i - 1) == '\r';
--i);
data.erase(i, data.end());
os << _("Message Code: ") << _messageCode << endl
<< _("Update Number: ") << _updateNumber << endl
<< _("Message Identifer: ") << _messageIdentifier << endl
<< _("Data coding scheme: ") << _dataCodingScheme.toString() << endl
<< _("Total page number: ") << _totalPageNumber << endl
<< _("Current page number: ") << _currentPageNumber << endl
<< _("Data: '") << data << "'" << endl
<< dashes << endl << endl << ends;
char *ss = os.str();
string result(ss);
delete[] ss;
return result;
}

View File

@ -0,0 +1,106 @@
// *************************************************************************
// * GSM TA/ME library
// *
// * File: gsm_cb.h
// *
// * Purpose: Cell Broadcast Message Implementation
// *
// * Author: Peter Hofmann (software@pxh.de)
// *
// * Created: 4.8.2001
// *************************************************************************
#ifndef GSM_CB_H
#define GSM_CB_H
#include <gsmlib/gsm_sms_codec.h>
#include <gsmlib/gsm_util.h>
#include <string>
using namespace std;
namespace gsmlib
{
// representation of DataCodingScheme
// The data coding scheme is described in detail in ETSI GSM 03.38, section 5
// This class reuses the DCS_* constants from DataCodingScheme in
// gsm_sms_codec
class CBDataCodingScheme
{
public:
enum Language {German = 0, English = 1, Italian = 2, French = 3,
Spanish = 4, Dutch = 5, Swedish = 6, Danish = 7,
Portuguese = 8, Finnish = 9, Norwegian = 10, Greek = 11,
Turkish = 12, Unknown = 1000};
private:
unsigned char _dcs;
Language _language;
public:
// initialize with data coding scheme octet
CBDataCodingScheme(unsigned char dcs);
// default constructor
CBDataCodingScheme() : _dcs(DCS_DEFAULT_ALPHABET), _language(English) {}
// return language of CBM
Language getLanguage() const {return _language;}
// return compression level (if language == Unknown)
bool compressed() const {return (_dcs & DCS_COMPRESSED) == DCS_COMPRESSED;}
// return type of alphabet used
// (DCS_DEFAULT_ALPHABET, DCS_EIGHT_BIT_ALPHABET, DCS_SIXTEEN_BIT_ALPHABET,
// DCS_RESERVED_ALPHABET)
unsigned char getAlphabet() const
{return _language == Unknown ? _dcs & (3 << 2) : DCS_DEFAULT_ALPHABET;}
// create textual representation of CB data coding scheme
string toString() const;
};
// representation of Cell Broadcast message (CBM)
// The CBM format is described in detail in ETSI GSM 03.41, section 9.3
class CBMessage : public RefBase
{
public:
enum GeographicalScope {CellWide, PLMNWide, LocationAreaWide,
CellWide2};
private:
// fields parsed from the CB TPDU
GeographicalScope _geographicalScope;
int _messageCode;
int _updateNumber;
int _messageIdentifier;
CBDataCodingScheme _dataCodingScheme;
int _totalPageNumber;
int _currentPageNumber;
string _data;
public:
// constructor with given pdu
CBMessage(string pdu) throw(GsmException);
// accessor functions
GeographicalScope getGeographicalScope() const {return _geographicalScope;}
int getMessageCode() const {return _messageCode;}
int getUpdateNumber() const {return _updateNumber;}
int getMessageIdentifier() const {return _messageIdentifier;}
CBDataCodingScheme getDataCodingScheme() const {return _dataCodingScheme;}
int getTotalPageNumber() const {return _totalPageNumber;}
int getCurrentPageNumber() const {return _currentPageNumber;}
string getData() const {return _data;}
// create textual representation of CBM
string toString() const;
};
// some useful typdefs
typedef Ref<CBMessage> CBMessageRef;
};
#endif // GSM_CB_H

Some files were not shown because too many files have changed in this diff Show More