diff options
author | Marcin Juszkiewicz <hrw@openembedded.org> | 2007-08-09 08:41:19 +0000 |
---|---|---|
committer | Marcin Juszkiewicz <hrw@openembedded.org> | 2007-08-09 08:41:19 +0000 |
commit | 9d829ed05c295df608b4fc108eb1c628fd06fd39 (patch) | |
tree | c1b27cfe4498f8abef1a61325922906f3e6a32ff /packages/gsm | |
parent | 1434b204e16e87b7f59f074f3036d5dcbcf0116f (diff) | |
parent | 6ccac10beeaaa02a86081bd6179fd57c208ad6b1 (diff) |
merge of '76e1e69496801009ea0aa69c84f76e858978ab99'
and 'db976a98427dd6a195e2cf167e225de2d0206aea'
Diffstat (limited to 'packages/gsm')
-rw-r--r-- | packages/gsm/files/.mtn2git_empty | 0 | ||||
-rw-r--r-- | packages/gsm/files/default | 9 | ||||
-rw-r--r-- | packages/gsm/files/extreplychars.patch | 70 | ||||
-rw-r--r-- | packages/gsm/files/fic-gta01/.mtn2git_empty | 0 | ||||
-rw-r--r-- | packages/gsm/files/fic-gta01/default | 9 | ||||
-rw-r--r-- | packages/gsm/files/getopt-wait-interpreter-ready.patch | 57 | ||||
-rw-r--r-- | packages/gsm/files/gsmd | 106 | ||||
-rw-r--r-- | packages/gsm/files/htcuniversal/.mtn2git_empty | 0 | ||||
-rw-r--r-- | packages/gsm/files/htcuniversal/default | 10 | ||||
-rw-r--r-- | packages/gsm/files/libgsmd-tool-fix.patch | 19 | ||||
-rw-r--r-- | packages/gsm/files/magician/.mtn2git_empty | 0 | ||||
-rw-r--r-- | packages/gsm/files/magician/default | 10 | ||||
-rw-r--r-- | packages/gsm/files/mlbuf-in-gsmd-struct.patch | 102 | ||||
-rw-r--r-- | packages/gsm/files/sms-hacks.patch | 820 | ||||
-rw-r--r-- | packages/gsm/files/tihtc-csq-fix.patch | 27 | ||||
-rw-r--r-- | packages/gsm/files/universal-wcdma.patch | 29 | ||||
-rw-r--r-- | packages/gsm/libgsmd_svn.bb | 36 |
17 files changed, 1296 insertions, 8 deletions
diff --git a/packages/gsm/files/.mtn2git_empty b/packages/gsm/files/.mtn2git_empty new file mode 100644 index 0000000000..e69de29bb2 --- /dev/null +++ b/packages/gsm/files/.mtn2git_empty diff --git a/packages/gsm/files/default b/packages/gsm/files/default new file mode 100644 index 0000000000..161c97f5fb --- /dev/null +++ b/packages/gsm/files/default @@ -0,0 +1,9 @@ +# gsmd This shell script configures for the gsmd init script. + +# If you must specify special options, uncomment and modify the next line +#GSMD_OPTS="-s 115200 -F" + +# If your GSM device needs to be powered up, uncomment and modify the next line +#GSM_POW="/sys/bus/platform/devices/gta01-pm-gsm.0/power_on" + +#GSM_DEV="/dev/ttyS1" diff --git a/packages/gsm/files/extreplychars.patch b/packages/gsm/files/extreplychars.patch new file mode 100644 index 0000000000..8ebc343e27 --- /dev/null +++ b/packages/gsm/files/extreplychars.patch @@ -0,0 +1,70 @@ +Index: gsm/src/gsmd/atcmd.c +=================================================================== +--- gsm.orig/src/gsmd/atcmd.c 2007-06-03 10:46:19.000000000 +0200 ++++ gsm/src/gsmd/atcmd.c 2007-06-03 15:54:53.000000000 +0200 +@@ -208,7 +208,7 @@ + * TBD + */ + +- if (buf[0] == '+' || buf[0] == '%') { ++ if (buf[0] == '+' || strchr(g->vendorpl->ext_chars, buf[0])) { + /* an extended response */ + const char *colon = strchr(buf, ':'); + if (!colon) { +@@ -255,7 +255,7 @@ + } + + if (cmd) { +- if (cmd->buf[2] != '+' && cmd->buf[2] != '%') { ++ if (cmd->buf[2] != '+' && strchr(g->vendorpl->ext_chars, cmd->buf[2]) == NULL) { + gsmd_log(GSMD_ERROR, "extd reply to non-extd command?\n"); + return -EINVAL; + } +Index: gsm/src/gsmd/vendor_qc.c +=================================================================== +--- gsm.orig/src/gsmd/vendor_qc.c 2007-06-03 10:46:19.000000000 +0200 ++++ gsm/src/gsmd/vendor_qc.c 2007-06-03 11:45:58.000000000 +0200 +@@ -97,6 +97,7 @@ + + struct gsmd_vendor_plugin gsmd_vendor_plugin = { + .name = "Qualcomm msm6250", ++ .ext_chars = "@", + .num_unsolicit = ARRAY_SIZE(qc_unsolicit), + .unsolicit = qc_unsolicit, + .detect = &qc_detect, +Index: gsm/src/gsmd/vendor_ti.c +=================================================================== +--- gsm.orig/src/gsmd/vendor_ti.c 2007-06-03 10:46:19.000000000 +0200 ++++ gsm/src/gsmd/vendor_ti.c 2007-06-03 11:45:58.000000000 +0200 +@@ -303,6 +303,7 @@ + + struct gsmd_vendor_plugin gsmd_vendor_plugin = { + .name = "TI Calypso", ++ .ext_chars = "%@", + .num_unsolicit = ARRAY_SIZE(ticalypso_unsolicit), + .unsolicit = ticalypso_unsolicit, + .detect = &ticalypso_detect, +Index: gsm/include/gsmd/vendorplugin.h +=================================================================== +--- gsm.orig/include/gsmd/vendorplugin.h 2007-02-16 15:12:40.000000000 +0100 ++++ gsm/include/gsmd/vendorplugin.h 2007-06-03 11:45:58.000000000 +0200 +@@ -12,6 +12,7 @@ + struct gsmd_vendor_plugin { + struct llist_head list; + unsigned char *name; ++ unsigned char *ext_chars; + unsigned int num_unsolicit; + const struct gsmd_unsolicit *unsolicit; + int (*detect)(struct gsmd *g); +Index: gsm/src/gsmd/vendor_tihtc.c +=================================================================== +--- gsm.orig/src/gsmd/vendor_tihtc.c 2007-06-03 15:55:31.000000000 +0200 ++++ gsm/src/gsmd/vendor_tihtc.c 2007-06-03 15:55:43.000000000 +0200 +@@ -298,6 +298,7 @@ + + struct gsmd_vendor_plugin gsmd_vendor_plugin = { + .name = "TI Calypso / HTC firmware", ++ .ext_chars = "%", + .num_unsolicit = ARRAY_SIZE(tihtc_unsolicit), + .unsolicit = tihtc_unsolicit, + .detect = &tihtc_detect, diff --git a/packages/gsm/files/fic-gta01/.mtn2git_empty b/packages/gsm/files/fic-gta01/.mtn2git_empty new file mode 100644 index 0000000000..e69de29bb2 --- /dev/null +++ b/packages/gsm/files/fic-gta01/.mtn2git_empty diff --git a/packages/gsm/files/fic-gta01/default b/packages/gsm/files/fic-gta01/default new file mode 100644 index 0000000000..1511376a6c --- /dev/null +++ b/packages/gsm/files/fic-gta01/default @@ -0,0 +1,9 @@ +# gsmd This shell script configures for the gsmd init script. + +# If you must specify special options, uncomment and modify the next line +GSMD_OPTS="-s 115200 -F" + +# If your GSM device needs to be powered up, uncomment and modify the next line +GSM_POW="/sys/bus/platform/devices/gta01-pm-gsm.0/power_on" + +GSM_DEV="/dev/ttySAC0" diff --git a/packages/gsm/files/getopt-wait-interpreter-ready.patch b/packages/gsm/files/getopt-wait-interpreter-ready.patch new file mode 100644 index 0000000000..52b0da1183 --- /dev/null +++ b/packages/gsm/files/getopt-wait-interpreter-ready.patch @@ -0,0 +1,57 @@ +Index: gsm/src/gsmd/gsmd.c +=================================================================== +--- gsm.orig/src/gsmd/gsmd.c 2007-06-03 11:57:43.000000000 +0200 ++++ gsm/src/gsmd/gsmd.c 2007-06-03 11:57:45.000000000 +0200 +@@ -311,6 +311,7 @@ + { "leak-report", 0, NULL, 'L' }, + { "vendor", 1, NULL, 'v' }, + { "machine", 1, NULL, 'm' }, ++ { "wait", 1, NULL, 'w' }, + { 0, 0, 0, 0 } + }; + +@@ -333,6 +334,7 @@ + "\t-l file\t--logfile file\tSpecify a logfile to log to\n" + "\t-v\t--vendor v\tSpecify GSM modem vendor plugin\n" + "\t-m\t--machine m\tSpecify GSM modem machine plugin\n" ++ "\t-w\t--wait m\tWait for the AT Interpreter Ready message\n" + ); + } + +@@ -362,6 +364,7 @@ + char *logfile = "syslog"; + char *vendor_name = NULL; + char *machine_name = NULL; ++ int wait = -1; + + signal(SIGTERM, sig_handler); + signal(SIGINT, sig_handler); +@@ -374,7 +377,7 @@ + print_header(); + + /*FIXME: parse commandline, set daemonize, device, ... */ +- while ((argch = getopt_long(argc, argv, "FVLdhp:s:l:v:m:", opts, NULL)) != -1) { ++ while ((argch = getopt_long(argc, argv, "FVLdhp:s:l:v:m:w:", opts, NULL)) != -1) { + switch (argch) { + case 'V': + /* FIXME */ +@@ -411,6 +414,9 @@ + case 'm': + machine_name = optarg; + break; ++ case 'w': ++ wait = atoi(optarg); ++ break; + } + } + +@@ -455,6 +461,9 @@ + exit(1); + } + ++ if (wait >= 0) ++ g.interpreter_ready = !wait; ++ + if (atcmd_init(&g, fd) < 0) { + fprintf(stderr, "can't initialize UART device\n"); + exit(1); diff --git a/packages/gsm/files/gsmd b/packages/gsm/files/gsmd new file mode 100644 index 0000000000..5c78e8178a --- /dev/null +++ b/packages/gsm/files/gsmd @@ -0,0 +1,106 @@ +#!/bin/sh +# +# gsmd This shell script starts and stops gsmd. +# +# chkconfig: 345 90 40 +# description: Gsmd manages access to a serial- or USB-connected GSM +# processname: gsmd + +# Source configuration +. /etc/default/gsmd + +# Source function library. +#. /etc/rc.d/init.d/functions + +RETVAL=0 +prog="gsmd" + +start() { + # Hack for broken uboot and/or kernel on the neo1973 + dmesg -n1 + + if [ -n "${GSM_POW}" ] + then + if [ -e "${GSM_POW}" ] + then + echo -n "Powering up GSM device..." + echo "1" > ${GSM_POW} + sleep 1 + echo "done" + else + echo "GSM device not found. Aborting startup" + return false + fi + fi + # Start daemons. + echo -n "Starting $prog: " + # We don't use the daemon function here because of a known bug + # in initlog -- it spuriously returns a nonzero status when + # starting daemons that fork themselves. See + # http://bugzilla.redhat.com/bugzilla/show_bug.cgi?id=130629 + # for discussion. Fortunately: + # + # 1. gsmd startup can't fail, or at least not in the absence of + # much larger resource-exhaustion problems that would be very obvious. + # + # 2. We don't need all the logging crud that daemon/initlog sets + # up -- gsmd does its own syslog calls. + # + if [ -e "${GSM_DEV}" ] + then + gsmd -p ${GSM_DEV} ${GSMD_OPTS} >/tmp/gsm.log 2>&1 & + echo "success" + else + # User needs to symlink ${GPS_DEV} to the right thing + echo "No ${GSM_DEV} device, aborting gsmd startup." + fi + RETVAL=$? + echo + [ $RETVAL -eq 0 ] && touch /var/lock/subsys/gsmd + return $RETVAL +} + +stop() { + # Stop daemons. + echo -n "Shutting down $prog: " + killall gsmd +# killproc gsmd + RETVAL=$? + echo + if [ $RETVAL -eq 0 ] + then + rm -f /var/lock/subsys/gsmd; + fi + return $RETVAL +} + +# See how we were called. +case "$1" in + start) + start + ;; + stop) + stop + ;; + restart|reload) + stop + start + RETVAL=$? + ;; + condrestart) + if [ -f /var/lock/subsys/gsmd ]; then + stop + start + RETVAL=$? + fi + ;; + status) +# status gsmd +# RETVAL=$? + ;; + *) + echo "Usage: $0 {start|stop|restart|condrestart|status}" + exit 1 +esac + +exit $RETVAL diff --git a/packages/gsm/files/htcuniversal/.mtn2git_empty b/packages/gsm/files/htcuniversal/.mtn2git_empty new file mode 100644 index 0000000000..e69de29bb2 --- /dev/null +++ b/packages/gsm/files/htcuniversal/.mtn2git_empty diff --git a/packages/gsm/files/htcuniversal/default b/packages/gsm/files/htcuniversal/default new file mode 100644 index 0000000000..b09d433d1e --- /dev/null +++ b/packages/gsm/files/htcuniversal/default @@ -0,0 +1,10 @@ +# gsmd This shell script configures for the gsmd init script. + +GSMD_OPTS="-s 115200 -F -w 1" + +# If your GSM device needs to be powered up, uncomment and modify the next line +#GSM_POW="/sys/bus/platform/devices/gta01-pm-gsm.0/power_on" + +# this should be in a common /etc/default/serial, together +# with BT_DEV, and IR_DEV +GSM_DEV="/dev/ttyS0" diff --git a/packages/gsm/files/libgsmd-tool-fix.patch b/packages/gsm/files/libgsmd-tool-fix.patch new file mode 100644 index 0000000000..8938f5a682 --- /dev/null +++ b/packages/gsm/files/libgsmd-tool-fix.patch @@ -0,0 +1,19 @@ +Index: gsm/src/util/atcmd.c +=================================================================== +--- gsm.orig/src/util/atcmd.c 2007-07-31 11:44:32.000000000 +0200 ++++ gsm/src/util/atcmd.c 2007-07-31 11:46:44.000000000 +0200 +@@ -91,9 +91,11 @@ + continue; + } + printf("STR=`%s'\n", buf); ++ ++ /* this is a synchronous call for a passthrough ++ * command */ ++ lgsm_passthrough(lgsmh, buf, rbuf, &rlen); ++ printf("RSTR=`%s'\n", rbuf); + } +- /* this is a synchronous call for a passthrough command */ +- lgsm_passthrough(lgsmh, buf, rbuf, &rlen); +- printf("RSTR=`%s'\n", rbuf); + } + } diff --git a/packages/gsm/files/magician/.mtn2git_empty b/packages/gsm/files/magician/.mtn2git_empty new file mode 100644 index 0000000000..e69de29bb2 --- /dev/null +++ b/packages/gsm/files/magician/.mtn2git_empty diff --git a/packages/gsm/files/magician/default b/packages/gsm/files/magician/default new file mode 100644 index 0000000000..523d0b9479 --- /dev/null +++ b/packages/gsm/files/magician/default @@ -0,0 +1,10 @@ +# gsmd This shell script configures for the gsmd init script. + +GSMD_OPTS="-s 115200 -F" + +# If your GSM device needs to be powered up, uncomment and modify the next line +#GSM_POW="/sys/bus/platform/devices/gta01-pm-gsm.0/power_on" + +# this should be in a common /etc/default/serial, together +# with BT_DEV, and IR_DEV +GSM_DEV="/dev/ttyS1" diff --git a/packages/gsm/files/mlbuf-in-gsmd-struct.patch b/packages/gsm/files/mlbuf-in-gsmd-struct.patch new file mode 100644 index 0000000000..d46eae8bb3 --- /dev/null +++ b/packages/gsm/files/mlbuf-in-gsmd-struct.patch @@ -0,0 +1,102 @@ +Index: gsm/include/gsmd/gsmd.h +=================================================================== +--- gsm.orig/include/gsmd/gsmd.h 2007-07-31 14:07:47.000000000 +0200 ++++ gsm/include/gsmd/gsmd.h 2007-07-31 14:09:02.000000000 +0200 +@@ -74,6 +74,8 @@ + struct gsmd_device_state dev_state; + + struct llist_head operators; /* cached list of operator names */ ++ unsigned int mlbuf_len; ++ unsigned char *mlbuf; /* ml_parse buffer */ + }; + + struct gsmd_user { +Index: gsm/src/gsmd/atcmd.c +=================================================================== +--- gsm.orig/src/gsmd/atcmd.c 2007-07-31 14:06:49.000000000 +0200 ++++ gsm/src/gsmd/atcmd.c 2007-07-31 14:12:33.000000000 +0200 +@@ -175,9 +175,7 @@ + { + struct gsmd *g = ctx; + struct gsmd_atcmd *cmd = NULL; +- static char mlbuf[MLPARSE_BUF_SIZE]; + int rc = 0, final = 0; +- int mlbuf_len; + + DEBUGP("buf=`%s'(%d)\n", buf, len); + +@@ -273,15 +271,15 @@ + + /* it might be a multiline response, so if there's a previous + response, send out mlbuf and start afresh with an empty buffer */ +- if (mlbuf[0] != 0) { ++ if (g->mlbuf[0] != 0) { + if (!cmd->cb) { + gsmd_log(GSMD_NOTICE, "command without cb!!!\n"); + } else { + DEBUGP("Calling cmd->cb()\n"); +- cmd->resp = mlbuf; ++ cmd->resp = g->mlbuf; + rc = cmd->cb(cmd, cmd->ctx, cmd->resp); + DEBUGP("Clearing mlbuf\n"); +- mlbuf[0] = 0; ++ g->mlbuf[0] = 0; + } + } + +@@ -334,16 +332,16 @@ + /* we reach here, if we are at an information response that needs to be + * passed on */ + +- if (mlbuf[0] == 0) { ++ if (g->mlbuf[0] == 0) { + DEBUGP("Filling mlbuf\n"); +- strncat(mlbuf, buf, sizeof(mlbuf)-1); ++ strncat(g->mlbuf, buf, MLPARSE_BUF_SIZE-1); + } else { + DEBUGP("Appending buf to mlbuf\n"); +- mlbuf_len = strlen(mlbuf); +- if (mlbuf_len+1 < sizeof(mlbuf)) { +- mlbuf[mlbuf_len] = '\n'; +- mlbuf[mlbuf_len+1] = '\0'; +- strncat(mlbuf, buf, sizeof(mlbuf)-mlbuf_len-2); ++ g->mlbuf_len = strlen(g->mlbuf); ++ if (g->mlbuf_len+1 < MLPARSE_BUF_SIZE) { ++ g->mlbuf[g->mlbuf_len] = '\n'; ++ g->mlbuf[g->mlbuf_len+1] = '\0'; ++ strncat(g->mlbuf, buf, MLPARSE_BUF_SIZE-g->mlbuf_len-2); + } else { + DEBUGP("response too big for mlbuf!!!\n"); + return -EFBIG; +@@ -365,13 +363,13 @@ + } else { + DEBUGP("Calling final cmd->cb()\n"); + /* send final result code if there is no information response in mlbuf */ +- if (mlbuf[0] == 0) ++ if (g->mlbuf[0] == 0) + cmd->resp = buf; + else +- cmd->resp = mlbuf; ++ cmd->resp = g->mlbuf; + rc = cmd->cb(cmd, cmd->ctx, cmd->resp); + DEBUGP("Clearing mlbuf\n"); +- mlbuf[0] = 0; ++ g->mlbuf[0] = 0; + } + + /* remove from list of currently executing cmds */ +Index: gsm/src/gsmd/gsmd.c +=================================================================== +--- gsm.orig/src/gsmd/gsmd.c 2007-07-31 14:06:47.000000000 +0200 ++++ gsm/src/gsmd/gsmd.c 2007-07-31 14:06:50.000000000 +0200 +@@ -300,6 +300,10 @@ + { + INIT_LLIST_HEAD(&g->users); + ++ g->mlbuf = talloc_array(gsmd_tallocs, unsigned char, MLPARSE_BUF_SIZE); ++ if (!g->mlbuf) ++ return -ENOMEM; ++ + return 0; + } + diff --git a/packages/gsm/files/sms-hacks.patch b/packages/gsm/files/sms-hacks.patch new file mode 100644 index 0000000000..ba248449af --- /dev/null +++ b/packages/gsm/files/sms-hacks.patch @@ -0,0 +1,820 @@ +From 3e5832569d3b29a90b29b5d5ac0ffad4765bcff3 Mon Sep 17 00:00:00 2001 +From: Andrzej Zaborowski <balrog@zabor.org> +Date: Fri, 6 Jul 2007 06:55:12 +0200 +Subject: [PATCH] SMS hacks 2 + +--- + include/gsmd/gsmd.h | 8 ++- + include/gsmd/usock.h | 35 ++++++++- + include/gsmd/vendorplugin.h | 2 +- + include/libgsmd/sms.h | 2 +- + src/gsmd/atcmd.c | 130 +++++++++++++++++++------------- + src/gsmd/sms_cb.c | 19 ++++- + src/gsmd/usock.c | 175 +++++++++++++++++++++++++++++++++++++----- + src/gsmd/vendor_ti.c | 2 +- + src/libgsmd/libgsmd_sms.c | 26 +++++-- + 11 files changed, 320 insertions(+), 91 deletions(-) + +Index: gsm/include/gsmd/gsmd.h +=================================================================== +--- gsm.orig/include/gsmd/gsmd.h 2007-07-31 14:09:02.000000000 +0200 ++++ gsm/include/gsmd/gsmd.h 2007-07-31 14:23:32.000000000 +0200 +@@ -27,6 +27,7 @@ + u_int32_t buflen; + u_int16_t id; + u_int8_t flags; ++ char *cur; + char buf[]; + }; + +@@ -36,6 +37,8 @@ + LLPARSE_STATE_IDLE_LF, /* LF before response (V1) */ + LLPARSE_STATE_RESULT, /* within result payload */ + LLPARSE_STATE_RESULT_CR, /* CR after result */ ++ LLPARSE_STATE_PROMPT, /* within a "> " prompt */ ++ LLPARSE_STATE_PROMPT_SPC, /* a complete "> " prompt */ + LLPARSE_STATE_ERROR, /* something went wrong */ + /* ... idle again */ + }; +@@ -52,6 +55,7 @@ + unsigned int flags; + void *ctx; + int (*cb)(const char *buf, int len, void *ctx); ++ int (*prompt_cb)(void *ctx); + char *cur; + char buf[LLPARSE_BUF_SIZE]; + }; +@@ -59,6 +63,7 @@ + struct gsmd; + + #define GSMD_FLAG_V0 0x0001 /* V0 responses to be expected from TA */ ++#define GSMD_FLAG_SMS_FMT 0x0002 /* Use TEXT rather than PDU mode */ + + struct gsmd { + unsigned int flags; +@@ -94,7 +99,8 @@ + + extern int gsmdlog_init(const char *path); + /* write a message to the daemons' logfile */ +-void __gsmd_log(int level, const char *file, int line, const char *function, const char *message, ...); ++void __gsmd_log(int level, const char *file, int line, const char *function, const char *message, ...) ++ __attribute__ ((__format__ (__printf__, 5, 6))); + /* macro for logging including filename and line number */ + #define gsmd_log(level, format, args ...) \ + __gsmd_log(level, __FILE__, __LINE__, __FUNCTION__, format, ## args) +Index: gsm/include/gsmd/usock.h +=================================================================== +--- gsm.orig/include/gsmd/usock.h 2007-07-31 13:58:37.000000000 +0200 ++++ gsm/include/gsmd/usock.h 2007-07-31 14:23:32.000000000 +0200 +@@ -139,7 +139,7 @@ + /* for SMS-SUBMIT, SMS-DELIVER */ + enum gsmd_sms_tp_udhi { + GSMD_SMS_TP_UDHI_NO_HEADER = (0<<6), +- GSMD_SMS_TP_UDHI_WTIH_HEADER = (1<<6), ++ GSMD_SMS_TP_UDHI_WITH_HEADER = (1<<6), + }; + + /* SMS delflg from 3GPP TS 07.05, Clause 3.5.4 */ +@@ -160,6 +160,34 @@ + GSMD_PHONEBOOK_GET_SUPPORT = 6, + }; + ++/* Type-of-Address, Numbering Plan Identification field */ ++enum gsmd_toa_npi { ++ GSMD_TOA_NPI_UNKNOWN = 0x0, ++ GSMD_TOA_NPI_ISDN = 0x1, ++ GSMD_TOA_NPI_DATA = 0x3, ++ GSMD_TOA_NPI_TELEX = 0x4, ++ GSMD_TOA_NPI_NATIONAL = 0x8, ++ GSMD_TOA_NPI_PRIVATE = 0x9, ++ GSMD_TOA_NPI_ERMES = 0xa, ++ GSMD_TOA_NPI_RESERVED = 0xf, ++}; ++ ++/* Type-of-Address, Type-of-Number field */ ++enum gsmd_toa_ton { ++ GSMD_TOA_TON_UNKNOWN = (0<<4), ++ GSMD_TOA_TON_INTERNATIONAL = (1<<4), ++ GSMD_TOA_TON_NATIONAL = (2<<4), ++ GSMD_TOA_TON_NETWORK = (3<<4), ++ GSMD_TOA_TON_SUBSCRIBER = (4<<4), ++ GSMD_TOA_TON_ALPHANUMERIC = (5<<4), ++ GSMD_TOA_TON_ABBREVIATED = (6<<4), ++}; ++ ++/* Type-of-Address, bit 7 always 1 */ ++enum gsmd_toa_reserved { ++ GSMD_TOA_RESERVED = (1<<7), ++}; ++ + /* Length from 3GPP TS 04.08, Clause 10.5.4.7 */ + + #define GSMD_ADDR_MAXLEN 32 +@@ -269,6 +297,11 @@ + char user_data[140]; + } __attribute__ ((packed)); + ++struct gsmd_sms_send { ++ struct gsmd_addr addr; ++ struct gsmd_sms payload; ++}; ++ + /* Refer to GSM 07.07 subclause 8.12 */ + struct gsmd_phonebook_readrg { + u_int8_t index1; +Index: gsm/include/gsmd/vendorplugin.h +=================================================================== +--- gsm.orig/include/gsmd/vendorplugin.h 2007-07-31 13:58:38.000000000 +0200 ++++ gsm/include/gsmd/vendorplugin.h 2007-07-31 14:23:32.000000000 +0200 +@@ -12,7 +12,7 @@ + struct gsmd_vendor_plugin { + struct llist_head list; + unsigned char *name; +- unsigned char *ext_chars; ++ char *ext_chars; + unsigned int num_unsolicit; + const struct gsmd_unsolicit *unsolicit; + int (*detect)(struct gsmd *g); +Index: gsm/include/libgsmd/sms.h +=================================================================== +--- gsm.orig/include/libgsmd/sms.h 2007-07-31 13:58:38.000000000 +0200 ++++ gsm/include/libgsmd/sms.h 2007-07-31 14:23:32.000000000 +0200 +@@ -83,7 +83,7 @@ + extern int lgsmd_sms_send(struct lgsm_handle *lh, const struct lgsm_sms *sms); + + /* Write Message to Memory */ +-extern int lgsmd_sms_write(struct lgsm_handle *lh, ++extern int lgsmd_sms_write(struct lgsm_handle *lh, + const struct lgsm_sms_write *sms_write); + + /* Packing of 7-bit characters, refer to GSM 03.38 subclause 6.1.2.1.1 */ +Index: gsm/src/gsmd/atcmd.c +=================================================================== +--- gsm.orig/src/gsmd/atcmd.c 2007-07-31 14:13:00.000000000 +0200 ++++ gsm/src/gsmd/atcmd.c 2007-07-31 14:23:32.000000000 +0200 +@@ -82,9 +82,12 @@ + + switch (llp->state) { + case LLPARSE_STATE_IDLE: ++ case LLPARSE_STATE_PROMPT_SPC: + if (llp->flags & LGSM_ATCMD_F_EXTENDED) { + if (byte == '\r') + llp->state = LLPARSE_STATE_IDLE_CR; ++ else if (byte == '>') ++ llp->state = LLPARSE_STATE_PROMPT; + else { + #ifdef STRICT + llp->state = LLPARSE_STATE_ERROR; +@@ -108,6 +111,8 @@ + /* can we really go directly into result_cr ? */ + if (byte == '\r') + llp->state = LLPARSE_STATE_RESULT_CR; ++ else if (byte == '>') ++ llp->state = LLPARSE_STATE_PROMPT; + else { + llp->state = LLPARSE_STATE_RESULT; + ret = llparse_append(llp, byte); +@@ -127,6 +132,16 @@ + memset(llp->buf, 0, LLPARSE_BUF_SIZE); + } + break; ++ case LLPARSE_STATE_PROMPT: ++ if (byte == ' ') ++ llp->state = LLPARSE_STATE_PROMPT_SPC; ++ else { ++ /* this was not a real "> " prompt */ ++ llparse_append(llp, '>'); ++ ret = llparse_append(llp, byte); ++ llp->state = LLPARSE_STATE_RESULT; ++ } ++ break; + case LLPARSE_STATE_ERROR: + break; + } +@@ -147,6 +162,10 @@ + /* FIXME: what to do with return value ? */ + llp->cb(llp->buf, llp->cur - llp->buf, llp->ctx); + } ++ ++ /* if a full SMS-style prompt was received, poke the select */ ++ if (llp->state == LLPARSE_STATE_PROMPT_SPC) ++ llp->prompt_cb(llp->ctx); + } + + return 0; +@@ -175,7 +194,7 @@ + { + struct gsmd *g = ctx; + struct gsmd_atcmd *cmd = NULL; +- int rc = 0, final = 0; ++ int rc = 0; + + DEBUGP("buf=`%s'(%d)\n", buf, len); + +@@ -229,7 +248,6 @@ + DEBUGP("error number %lu\n", err_nr); + if (cmd) + cmd->ret = err_nr; +- final = 1; + goto final_cb; + } + if (!strncmp(buf+1, "CMS ERROR", 9)) { +@@ -239,7 +257,6 @@ + DEBUGP("error number %lu\n", err_nr); + if (cmd) + cmd->ret = err_nr; +- final = 1; + goto final_cb; + } + +@@ -271,7 +288,7 @@ + + /* it might be a multiline response, so if there's a previous + response, send out mlbuf and start afresh with an empty buffer */ +- if (g->mlbuf[0] != 0) { ++ if (g->mlbuf_len) { + if (!cmd->cb) { + gsmd_log(GSMD_NOTICE, "command without cb!!!\n"); + } else { +@@ -279,8 +296,8 @@ + cmd->resp = g->mlbuf; + rc = cmd->cb(cmd, cmd->ctx, cmd->resp); + DEBUGP("Clearing mlbuf\n"); +- g->mlbuf[0] = 0; + } ++ g->mlbuf_len = 0; + } + + /* the current buf will be appended to mlbuf below */ +@@ -299,7 +316,6 @@ + DEBUGP("unspecified error\n"); + if (cmd) + cmd->ret = 4; +- final = 1; + goto final_cb; + } + +@@ -308,7 +324,6 @@ + /* Part of Case 'C' */ + if (cmd) + cmd->ret = 0; +- final = 1; + goto final_cb; + } + +@@ -317,14 +332,12 @@ + if (!strncmp(buf, "NO CARRIER", 11) || + ((g->flags & GSMD_FLAG_V0) && buf[0] == '3')) { + /* Part of Case 'D' */ +- final = 1; + goto final_cb; + } + + if (!strncmp(buf, "BUSY", 4) || + ((g->flags & GSMD_FLAG_V0) && buf[0] == '7')) { + /* Part of Case 'D' */ +- final = 1; + goto final_cb; + } + } +@@ -332,21 +345,13 @@ + /* we reach here, if we are at an information response that needs to be + * passed on */ + +- if (g->mlbuf[0] == 0) { +- DEBUGP("Filling mlbuf\n"); +- strncat(g->mlbuf, buf, MLPARSE_BUF_SIZE-1); +- } else { +- DEBUGP("Appending buf to mlbuf\n"); +- g->mlbuf_len = strlen(g->mlbuf); +- if (g->mlbuf_len+1 < MLPARSE_BUF_SIZE) { +- g->mlbuf[g->mlbuf_len] = '\n'; +- g->mlbuf[g->mlbuf_len+1] = '\0'; +- strncat(g->mlbuf, buf, MLPARSE_BUF_SIZE-g->mlbuf_len-2); +- } else { +- DEBUGP("response too big for mlbuf!!!\n"); +- return -EFBIG; +- } +- } ++ if (g->mlbuf_len) ++ g->mlbuf[g->mlbuf_len ++] = '\n'; ++ DEBUGP("Appending buf to mlbuf\n"); ++ if (len > MLPARSE_BUF_SIZE - g->mlbuf_len) ++ len = MLPARSE_BUF_SIZE - g->mlbuf_len; ++ memcpy(g->mlbuf + g->mlbuf_len, buf, len); ++ g->mlbuf_len += len; + return 0; + + final_cb: +@@ -363,13 +368,16 @@ + } else { + DEBUGP("Calling final cmd->cb()\n"); + /* send final result code if there is no information response in mlbuf */ +- if (g->mlbuf[0] == 0) +- cmd->resp = buf; +- else ++ if (g->mlbuf_len) { + cmd->resp = g->mlbuf; ++ g->mlbuf[g->mlbuf_len] = 0; ++ gsmd_log(GSMD_NOTICE, ++ "the text discarded is %s\n", buf); ++ } else ++ cmd->resp = buf; + rc = cmd->cb(cmd, cmd->ctx, cmd->resp); + DEBUGP("Clearing mlbuf\n"); +- g->mlbuf[0] = 0; ++ g->mlbuf_len = 0; + } + + /* remove from list of currently executing cmds */ +@@ -382,7 +390,15 @@ + g->gfd_uart.when |= GSMD_FD_WRITE; + + return rc; +-} ++} ++ ++/* called when the modem asked for a new line of a multiline atcmd */ ++static int atcmd_prompt(void *data) ++{ ++ struct gsmd *g = data; ++ ++ g->gfd_uart.when |= GSMD_FD_WRITE; ++} + + /* callback to be called if [virtual] UART has some data for us */ + static int atcmd_select_cb(int fd, unsigned int what, void *data) +@@ -390,6 +406,7 @@ + int len, rc; + static char rxbuf[1024]; + struct gsmd *g = data; ++ char *cr; + + if (what & GSMD_FD_READ) { + memset(rxbuf, 0, sizeof(rxbuf)); +@@ -413,8 +430,12 @@ + if ((what & GSMD_FD_WRITE) && g->interpreter_ready) { + struct gsmd_atcmd *pos, *pos2; + llist_for_each_entry_safe(pos, pos2, &g->pending_atcmds, list) { +- len = strlen(pos->buf); +- rc = write(fd, pos->buf, strlen(pos->buf)); ++ cr = strchr(pos->cur, '\n'); ++ if (cr) ++ len = cr - pos->cur; ++ else ++ len = pos->buflen; ++ rc = write(fd, pos->cur, len); + if (rc == 0) { + gsmd_log(GSMD_ERROR, "write returns 0, aborting\n"); + break; +@@ -423,27 +444,32 @@ + fd, rc); + return rc; + } +- if (rc < len) { +- gsmd_log(GSMD_FATAL, "short write!!! FIXME!\n"); +- exit(3); +- } ++ if (cr && rc == len) ++ rc ++; /* Skip the \n */ ++ pos->buflen -= rc; ++ pos->cur += rc; + write(fd, "\r", 1); +- /* success: remove from global list of to-be-sent atcmds */ +- llist_del(&pos->list); +- /* append to global list of executing atcmds */ +- llist_add_tail(&pos->list, &g->busy_atcmds); ++ ++ if (!pos->buflen) { ++ /* success: remove from global list of ++ * to-be-sent atcmds */ ++ llist_del(&pos->list); ++ /* append to global list of executing atcmds */ ++ llist_add_tail(&pos->list, &g->busy_atcmds); + + /* we only send one cmd at the moment */ +- g->gfd_uart.when &= ~GSMD_FD_WRITE; + break; ++ } else { ++ /* The write was short or the atcmd has more ++ * lines to send after a "> ". */ ++ if (!(rc < len)) ++ break; ++ } + } +- } + +-#if 0 +- if (llist_empty(&g->pending_atcmds)) ++ /* Either pending_atcmds is empty or a command has to wait */ + g->gfd_uart.when &= ~GSMD_FD_WRITE; +-#endif +- ++ } + + return 0; + } +@@ -454,10 +480,10 @@ + { + int buflen = strlen(cmd); + struct gsmd_atcmd *atcmd; +- ++ + if (rlen > buflen) + buflen = rlen; +- ++ + atcmd = talloc_size(__atcmd_ctx, sizeof(*atcmd)+ buflen); + if (!atcmd) + return NULL; +@@ -468,6 +494,7 @@ + atcmd->ret = -255; + atcmd->buflen = buflen; + atcmd->buf[buflen-1] = '\0'; ++ atcmd->cur = atcmd->buf; + atcmd->cb = cb; + atcmd->resp = NULL; + strncpy(atcmd->buf, cmd, buflen-1); +@@ -480,8 +507,9 @@ + { + DEBUGP("submitting command `%s'\n", cmd->buf); + ++ if (llist_empty(&g->pending_atcmds)) ++ g->gfd_uart.when |= GSMD_FD_WRITE; + llist_add_tail(&cmd->list, &g->pending_atcmds); +- g->gfd_uart.when |= GSMD_FD_WRITE; + + return 0; + } +@@ -517,9 +545,9 @@ + g->llp.cur = g->llp.buf; + g->llp.len = sizeof(g->llp.buf); + g->llp.cb = &ml_parse; ++ g->llp.prompt_cb = &atcmd_prompt; + g->llp.ctx = g; + g->llp.flags = LGSM_ATCMD_F_EXTENDED; + + return gsmd_register_fd(&g->gfd_uart); +-} +- ++} +Index: gsm/src/gsmd/sms_cb.c +=================================================================== +--- gsm.orig/src/gsmd/sms_cb.c 2007-07-31 13:58:37.000000000 +0200 ++++ gsm/src/gsmd/sms_cb.c 2007-07-31 14:23:32.000000000 +0200 +@@ -91,9 +91,6 @@ + if (!ucmd) + return -ENOMEM; + +- +- +- + ucmd->hdr.version = GSMD_PROTO_VERSION; + ucmd->hdr.msg_type = GSMD_MSG_SMS; + ucmd->hdr.msg_subtype = GSMD_SMS_GETMSG_STORAGE; +@@ -188,14 +185,26 @@ + int sms_cb_init(struct gsmd *gsmd) + { + struct gsmd_atcmd *atcmd; ++ char buffer[10]; + + atcmd = atcmd_fill("AT+CSMS=0", NULL, gu, 0); + if (!atcmd) + return -ENOMEM; + atcmd_submit(gsmd, atcmd); + +- /* Switch into "text mode" (Section 3.2.3) */ +- atcdm = atcmd_fill("AT+CMGF=1", 9, &sms_cb_init_cb, gu, 0); ++ /* If text mode, set the encoding */ ++ if (gu->gsmd->flags & GSMD_FLAG_SMS_FMT) { ++ atcmd = atcmd_fill("AT+CSCS=\"IRA\"", 13, NULL, gu, 0); ++ if (!atcmd) ++ return -ENOMEM; ++ atcmd_submit(gsmd, atcmd); ++ } ++ ++ /* Switch into desired mode (Section 3.2.3) */ ++ snprintf(buffer, sizeof(buffer), "AT+CMGF=%i", ++ (gu->gsmd->flags & GSMD_FLAG_SMS_FMT) ? ++ GSMD_SMS_FMT_TEXT : GSMD_SMS_FMT_PDU); ++ atcmd = atcmd_fill(buffer, strlen(buffer), &sms_cb_init_cb, gu, 0); + if (!atcmd) + return -ENOMEM; + +Index: gsm/src/gsmd/usock.c +=================================================================== +--- gsm.orig/src/gsmd/usock.c 2007-07-31 13:58:37.000000000 +0200 ++++ gsm/src/gsmd/usock.c 2007-07-31 14:23:32.000000000 +0200 +@@ -75,7 +75,7 @@ + ucmd->hdr.version = GSMD_PROTO_VERSION; + ucmd->hdr.msg_type = GSMD_MSG_PASSTHROUGH; + ucmd->hdr.msg_subtype = GSMD_PASSTHROUGH_RESP; +- ucmd->hdr.len = strlen(resp)+1; ++ ucmd->hdr.len = rlen; + ucmd->hdr.id = cmd->id; + memcpy(ucmd->buf, resp, ucmd->hdr.len); + +@@ -100,7 +100,7 @@ + + static int usock_rcv_event(struct gsmd_user *gu, struct gsmd_msg_hdr *gph, int len) + { +- u_int32_t *evtmask = (u_int32_t *) ((char *)gph + sizeof(*gph), gph->id); ++ u_int32_t *evtmask = (u_int32_t *) ((char *)gph + sizeof(*gph)); + + if (len < sizeof(*gph) + sizeof(u_int32_t)) + return -EINVAL; +@@ -471,18 +471,15 @@ + + static int sms_send_cb(struct gsmd_atcmd *cmd, void *ctx, char *resp) + { +- struct gsmd_user *gu = ctx; ++ struct gsmd_user *gu = (struct gsmd_user *) ctx; + struct gsmd_ucmd *ucmd; +- +- ucmd = gsmd_ucmd_fill(strlen(resp)+1, GSMD_MSG_SMS, +- GSMD_SMS_SEND, 0); ++ ++ ucmd = gsmd_ucmd_fill(strlen(resp) + 1, ++ GSMD_MSG_SMS, GSMD_SMS_SEND, cmd->id); + if (!ucmd) + return -ENOMEM; +- + strcpy(ucmd->buf, resp); +- + usock_cmd_enqueue(ucmd, gu); +- + return 0; + } + +@@ -520,34 +517,142 @@ + return 0; + } + ++int packing_7bit_character(char *src, char *dest) ++{ ++ int i,j = 0; ++ unsigned char ch1, ch2; ++ char tmp[2]; ++ int shift = 0; ++ ++ *dest = '\0'; ++ ++ for ( i=0; i<strlen(src); i++ ) { ++ ++ ch1 = src[i] & 0x7F; ++ ch1 = ch1 >> shift; ++ ch2 = src[(i+1)] & 0x7F; ++ ch2 = ch2 << (7-shift); ++ ++ ch1 = ch1 | ch2; ++ ++ j = strlen(dest); ++ sprintf(tmp, "%X", (ch1 >> 4)); ++ dest[j++] = tmp[0]; ++ sprintf(tmp, "%X", (ch1 & 0x0F)); ++ dest[j++] = tmp[0]; ++ dest[j++] = '\0'; ++ ++ shift++; ++ ++ if ( 7 == shift ) { ++ shift = 0; ++ i++; ++ } ++ } ++ ++ return 0; ++} ++ ++/* Refer to GSM 03.40 subclause 9.2.3.3, for SMS-SUBMIT */ ++static int usock_pdu_make_smssubmit(char *dest, struct gsmd_sms_send *src) ++{ ++ u_int8_t header[10 + GSMD_ADDR_MAXLEN]; ++ int pos = 0, i, coding7bit = 1; ++ ++ /* (Should be optional but some modems require it) SMSC Length octet ++ * is prepended. If omitted or zero, use SMSC stored in the phone. */ ++ header[pos ++] = 0x00; ++ ++ header[pos ++] = ++ GSMD_SMS_TP_MTI_SUBMIT | ++ (0 << 2) | /* Reject Duplicates: 0 */ ++ GSMD_SMS_TP_VPF_NOT_PRESENT | ++ GSMD_SMS_TP_SRR_NOT_REQUEST | ++ GSMD_SMS_TP_UDHI_NO_HEADER | ++ GSMD_SMS_TP_RP_NOT_SET; ++ ++ /* TP-Message-Reference - 00 lets the phone set the number itself */ ++ header[pos ++] = 0x00; ++ ++ header[pos ++] = strlen(src->addr.number); ++ header[pos ++] = src->addr.type; ++ for (i = 0; src->addr.number[i]; i ++) { ++ header[pos] = src->addr.number[i ++] - '0'; ++ if (src->addr.number[i]) ++ header[pos ++] |= (src->addr.number[i] - '0') << 4; ++ else { ++ header[pos ++] |= 0xf0; ++ break; ++ } ++ } ++ ++ /* TP-Protocol-Identifier - 00 means implicit */ ++ header[pos ++] = 0x00; ++ ++ /* TP-Data-Coding-Scheme - 00 for 7-bit default alphabet */ ++ header[pos ++] = coding7bit ? 0x00 : 0x04; ++ ++ /* TP-Validity-Period, if present, would go here */ ++ ++ header[pos ++] = src->payload.length; ++ ++ if (dest) { ++ for (i = 0; i < pos; i ++) { ++ sprintf(dest, "%02X", header[i]); ++ dest += 2; ++ } ++ if (coding7bit) ++ packing_7bit_character(src->payload.data, dest); ++ else ++ for (i = 0; i < src->payload.length; i ++) { ++ sprintf(dest, "%02X", src->payload.data[i]); ++ dest += 2; ++ } ++ } ++ ++ if (coding7bit) ++ return ((src->payload.length * 7 + 7) >> 3) + pos; ++ else ++ return src->payload.length + pos; ++} ++ ++static const char *gsmd_cmgl_stat[] = { ++ "REC UNREAD", "REC READ", "STO UNSENT", "STO SENT", "ALL", ++}; ++ + static int usock_rcv_sms(struct gsmd_user *gu, struct gsmd_msg_hdr *gph, + int len) + { + /* FIXME: TEXT mode support!! */ + struct gsmd_atcmd *cmd = NULL; + struct gsmd_sms_delete *gsd; +- struct gsmd_sms *gs; ++ struct gsmd_sms_send *gss; + struct gsmd_sms_write *gsw; + int *stat, *index; + int atcmd_len; + char buf[1024]; +- ++ + switch (gph->msg_subtype) { + case GSMD_SMS_LIST: + /* FIXME: only support PDU mode!! */ + if(len < sizeof(*gph) + sizeof(int)) + return -EINVAL; +- stat = (int *) ((void *)gph + sizeof(*gph)); ++ stat = (int *) ((void *)gph + sizeof(*gph)); ++ if (*stat < 0 || *stat > 4) ++ return -EINVAL; + +- sprintf(buf, "%d", *stat); +- +- atcmd_len = 1 + strlen("AT+CMGL=") + strlen(buf); +- cmd = atcmd_fill("AT+CMGL=", atcmd_len, +- &sms_list_cb, gu, gph->id); ++ if (gu->gsmd->flags & GSMD_FLAG_SMS_FMT) ++ atcmd_len = sprintf(buf, "AT+CMGL=\"%s\"", ++ gsmd_cmgl_stat[*stat]); ++ else ++ atcmd_len = sprintf(buf, "AT+CMGL=%i", *stat); ++ ++ cmd = atcmd_fill(buf, atcmd_len + 1, ++ &sms_list_cb, gu, gph->id); + if (!cmd) + return -ENOMEM; +- sprintf(cmd->buf, "AT+CMGL=%s", buf); + break; ++ + case GSMD_SMS_READ: + /* FIXME: only support PDU mode!! */ + if(len < sizeof(*gph) + sizeof(int)) +@@ -563,6 +668,34 @@ + return -ENOMEM; + sprintf(cmd->buf, "AT+CMGR=%s", buf); + break; ++ ++ case GSMD_SMS_SEND: ++ if (len < sizeof(*gph) + sizeof(*gss)) ++ return -EINVAL; ++ gss = (struct gsmd_sms_send *) ((void *) gph + sizeof(*gph)); ++ ++ if (gu->gsmd->flags & GSMD_FLAG_SMS_FMT) { ++ atcmd_len = sprintf(buf, "AT+CMGS=\"%s\"\n%.*s", ++ gss->addr.number, ++ gss->payload.length, ++ gss->payload.data); ++ } else { ++ atcmd_len = sprintf(buf, "AT+CMGS=%i\n", ++ usock_pdu_make_smssubmit(NULL, ++ gss) - 1); ++ atcmd_len += usock_pdu_make_smssubmit(buf + atcmd_len, ++ gss) * 2; ++ } ++ buf[atcmd_len ++] = 26; /* ^Z ends the message */ ++ buf[atcmd_len ++] = 0; ++ ++ cmd = atcmd_fill(buf, atcmd_len, &sms_send_cb, gu, gph->id); ++ if (!cmd) ++ return -ENOMEM; ++ break; ++ case GSMD_SMS_WRITE: ++ gsmd_log(GSMD_DEBUG, "sms write\n"); ++ break; + #if 0 + case GSMD_SMS_SEND: + /* FIXME: only support PDU mode!! */ +@@ -610,8 +743,8 @@ + default: + return -EINVAL; + } +- +- gsmd_log(GSMD_DEBUG, "%s\n", cmd->buf); ++ ++ gsmd_log(GSMD_DEBUG, "%s\n", cmd ? cmd->buf : 0); + if (cmd) + return atcmd_submit(gu->gsmd, cmd); + else +@@ -867,7 +1000,7 @@ + [GSMD_MSG_PIN] = &usock_rcv_pin, + [GSMD_MSG_PHONE] = &usock_rcv_phone, + [GSMD_MSG_NETWORK] = &usock_rcv_network, +- [GSMD_MSG_SMS] = &usock_rcv_sms, ++ [GSMD_MSG_SMS] = &usock_rcv_sms, + //[GSMD_MSG_PHONEBOOK] = &usock_rcv_phonebook, + }; + +Index: gsm/src/gsmd/vendor_ti.c +=================================================================== +--- gsm.orig/src/gsmd/vendor_ti.c 2007-07-31 13:58:37.000000000 +0200 ++++ gsm/src/gsmd/vendor_ti.c 2007-07-31 14:23:32.000000000 +0200 +@@ -277,7 +277,7 @@ + + static int ticalypso_initsettings(struct gsmd *g) + { +- int rc; ++ int rc = 0; + struct gsmd_atcmd *cmd; + + /* use +CTZR: to report time zone changes */ +Index: gsm/src/libgsmd/libgsmd_sms.c +=================================================================== +--- gsm.orig/src/libgsmd/libgsmd_sms.c 2007-07-31 13:58:37.000000000 +0200 ++++ gsm/src/libgsmd/libgsmd_sms.c 2007-07-31 14:23:32.000000000 +0200 +@@ -83,19 +83,33 @@ + return 0; + } + +-int lgsmd_sms_send(struct lgsm_handle *lh, +- const struct lgsm_sms *sms) ++#ifndef MIN ++# define MIN(a,b) (((a) < (b)) ? (a) : (b)) ++#endif ++ ++int lgsmd_sms_send(struct lgsm_handle *lh, ++ const struct lgsm_sms *sms) + { + /* FIXME: only support PDU mode */ + struct gsmd_msg_hdr *gmh; +- struct gsmd_sms *gs; ++ struct gsmd_sms_send *gss; + int rc; + + gmh = lgsm_gmh_fill(GSMD_MSG_SMS, +- GSMD_SMS_SEND, sizeof(*gs)); ++ GSMD_SMS_SEND, sizeof(*gss)); + if (!gmh) + return -ENOMEM; +- gs = (struct gsmd_sms *) gmh->data; ++ gss = (struct gsmd_sms_send *) gmh->data; ++ ++ gss->addr.type = ++ GSMD_TOA_NPI_ISDN | ++ GSMD_TOA_TON_UNKNOWN | ++ GSMD_TOA_RESERVED; ++ strncpy(gss->addr.number, sms->addr, sizeof(gss->addr.number)); ++ ++ gss->payload.length = ++ MIN(strlen(sms->data), sizeof(gss->payload.data)); ++ memcpy(gss->payload.data, sms->data, gss->payload.length); + + rc = lgsm_send(lh, gmh); + if (rc < gmh->len + sizeof(*gmh)) { +@@ -108,7 +122,7 @@ + return 0; + } + +-int lgsmd_sms_write(struct lgsm_handle *lh, ++int lgsmd_sms_write(struct lgsm_handle *lh, + const struct lgsm_sms_write *sms_write) + { + /* FIXME: only support PDU mode */ diff --git a/packages/gsm/files/tihtc-csq-fix.patch b/packages/gsm/files/tihtc-csq-fix.patch new file mode 100644 index 0000000000..3346d85809 --- /dev/null +++ b/packages/gsm/files/tihtc-csq-fix.patch @@ -0,0 +1,27 @@ +Index: gsm/src/gsmd/vendor_tihtc.c +=================================================================== +--- gsm.orig/src/gsmd/vendor_tihtc.c 2007-06-03 16:26:39.000000000 +0200 ++++ gsm/src/gsmd/vendor_tihtc.c 2007-06-03 16:26:41.000000000 +0200 +@@ -90,6 +90,8 @@ + struct gsmd_evt_auxdata *aux; + struct gsmd_ucmd *ucmd = usock_build_event(GSMD_MSG_EVENT, GSMD_EVT_SIGNAL, + sizeof(*aux)); ++ static int rssi_table[] = { 0,5,10,15,20,25,99 }; ++ unsigned int i; + + DEBUGP("entering htccsq_parse param=`%s'\n", param); + if (!ucmd) +@@ -98,9 +100,10 @@ + + aux = (struct gsmd_evt_auxdata *) ucmd->buf; + +- /* FIXME: contains values 1-5, should be mapped to 0-31 somehow? */ +- /* 2 --> 11 */ +- aux->u.signal.sigq.rssi = atoi(buf); ++ i = atoi(buf); ++ if (i > 6) ++ i = 6; ++ aux->u.signal.sigq.rssi = rssi_table[atoi(buf)]; + aux->u.signal.sigq.ber = 99; + + DEBUGP("sending EVT_SIGNAL\n"); diff --git a/packages/gsm/files/universal-wcdma.patch b/packages/gsm/files/universal-wcdma.patch new file mode 100644 index 0000000000..a162ce2326 --- /dev/null +++ b/packages/gsm/files/universal-wcdma.patch @@ -0,0 +1,29 @@ +Index: gsm/src/gsmd/vendor_qc.c +=================================================================== +--- gsm.orig/src/gsmd/vendor_qc.c 2007-06-13 20:13:47.000000000 +0200 ++++ gsm/src/gsmd/vendor_qc.c 2007-06-13 20:45:19.000000000 +0200 +@@ -69,8 +69,15 @@ + return -EIO; + } + ++static int wcdma_parse(char *buf, int len, const char *param, ++ struct gsmd *gsmd) ++{ ++ return 0; ++} ++ + static const struct gsmd_unsolicit qc_unsolicit[] = { + { "@HTCCSQ", &htccsq_parse }, /* Signal Quality */ ++ { "[WCDMA]", &wcdma_parse }, /* ignore [WCDMA] messages */ + + /* FIXME: parse the below and generate the respective events */ + +@@ -97,7 +109,7 @@ + + struct gsmd_vendor_plugin gsmd_vendor_plugin = { + .name = "Qualcomm msm6250", +- .ext_chars = "@", ++ .ext_chars = "@[", + .num_unsolicit = ARRAY_SIZE(qc_unsolicit), + .unsolicit = qc_unsolicit, + .detect = &qc_detect, diff --git a/packages/gsm/libgsmd_svn.bb b/packages/gsm/libgsmd_svn.bb index 860adf3b0a..87b7dc090d 100644 --- a/packages/gsm/libgsmd_svn.bb +++ b/packages/gsm/libgsmd_svn.bb @@ -1,24 +1,44 @@ DESCRIPTION = "GSM libraries and daemons implementing the 07.10 specification" HOMEPAGE = "http://www.openmoko.org" -LICENSE = "GPL" +LICENSE = "GPL LGPL" SECTION = "libs/gsm" PROVIDES += "gsmd" -PV = "0.0+svn${SRCDATE}" -PR = "r2" +PV = "0.1+svn${SRCDATE}" +PR = "r16" -SRC_URI = "svn://svn.openmoko.org/trunk/src/target;module=gsm;proto=http" +SRC_URI = "svn://svn.openmoko.org/trunk/src/target;module=gsm;proto=http \ + file://gsmd \ + file://default \ + file://extreplychars.patch;patch=1 \ + file://getopt-wait-interpreter-ready.patch;patch=1 \ + file://tihtc-csq-fix.patch;patch=1 \ + file://universal-wcdma.patch;patch=1 \ + file://mlbuf-in-gsmd-struct.patch;patch=1 \ + file://libgsmd-tool-fix.patch;patch=1 \ + file://sms-hacks.patch;patch=1" S = "${WORKDIR}/gsm" -inherit autotools pkgconfig +inherit autotools pkgconfig update-rc.d + +INITSCRIPT_NAME = "gsmd" +INITSCRIPT_PARAMS = "defaults 35" do_stage() { autotools_stage_all } -PACKAGES =+ "${PN}-tools gsmd" +do_install_append() { + install -d ${D}/${sysconfdir}/init.d + install -m 0755 ${WORKDIR}/gsmd ${D}/${sysconfdir}/init.d/ + install -d ${D}/${sysconfdir}/default + install ${WORKDIR}/default ${D}/${sysconfdir}/default/gsmd +} + +PACKAGES =+ "${PN}-tools gsmd gsmd-plugins" RDEPENDS_${PN} = "gsmd" +RRECOMMENDS_gsmd = "gsmd-plugins" FILES_${PN}-tools = "${bindir}/*" -FILES_gsmd = "${sbindir}/gsmd" +FILES_gsmd = "${sbindir}/gsmd ${sysconfdir}" +FILES_gsmd-plugins = "${libdir}/gsmd/*.so*" PACKAGES_DYNAMIC = "libgsmd* gsmd" - |