diff options
author | Philipp Zabel <philipp.zabel@gmail.com> | 2007-04-05 09:04:17 +0000 |
---|---|---|
committer | Philipp Zabel <philipp.zabel@gmail.com> | 2007-04-05 09:04:17 +0000 |
commit | 6a111dc1a6d7cc44ac3019ced52d5bbc17f0b136 (patch) | |
tree | 0d3133df2e7d0bc35bea9fb46fbb7e6682643d97 /packages/gsm/files | |
parent | b96de293f83c5860731e5a63ef27b1af2921a23c (diff) |
libgsmd: experimental plugin infrastructure for magician and universal
- subject to change
Diffstat (limited to 'packages/gsm/files')
-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/interpreter-ready.patch | 47 | ||||
-rw-r--r-- | packages/gsm/files/magician/default | 5 | ||||
-rw-r--r-- | packages/gsm/files/magician/ldisc.patch | 66 | ||||
-rw-r--r-- | packages/gsm/files/magician/vendor-tihtc.patch | 325 | ||||
-rw-r--r-- | packages/gsm/files/numeric.patch | 56 | ||||
-rw-r--r-- | packages/gsm/files/plugin.patch | 935 |
8 files changed, 1004 insertions, 440 deletions
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..3c9a8da949 --- /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" + +# 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/interpreter-ready.patch b/packages/gsm/files/interpreter-ready.patch deleted file mode 100644 index cc6b9c6e2b..0000000000 --- a/packages/gsm/files/interpreter-ready.patch +++ /dev/null @@ -1,47 +0,0 @@ -Index: gsm/include/gsmd/gsmd.h -=================================================================== ---- gsm.orig/include/gsmd/gsmd.h 2007-03-29 17:07:10.000000000 +0200 -+++ gsm/include/gsmd/gsmd.h 2007-03-29 17:07:43.000000000 +0200 -@@ -58,6 +58,7 @@ - - struct gsmd { - unsigned int flags; -+ int interpreter_ready; - struct gsmd_fd gfd_uart; - struct gsmd_fd gfd_sock; - struct llparser llp; -Index: gsm/src/gsmd/atcmd.c -=================================================================== ---- gsm.orig/src/gsmd/atcmd.c 2007-03-29 17:06:01.000000000 +0200 -+++ gsm/src/gsmd/atcmd.c 2007-03-29 17:08:27.000000000 +0200 -@@ -183,6 +183,7 @@ - * an empty string or that 'ready' string, we need to init the modem */ - if (strlen(buf) == 0 || - !strcmp(buf, "AT-Command Interpreter ready")) { -+ g->interpreter_ready = 1; - gsmd_initsettings(g); - return 0; - } -@@ -372,7 +373,7 @@ - } - - /* write pending commands to UART */ -- if (what & GSMD_FD_WRITE) { -+ 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); -Index: gsm/src/gsmd/gsmd.c -=================================================================== ---- gsm.orig/src/gsmd/gsmd.c 2007-03-29 17:06:04.000000000 +0200 -+++ gsm/src/gsmd/gsmd.c 2007-03-29 17:08:59.000000000 +0200 -@@ -291,7 +291,8 @@ - - gsmd_vendor_plugin_find(&g); - -- gsmd_initsettings(&g); -+ if (g.interpreter_ready) -+ gsmd_initsettings(&g); - - gsmd_opname_init(&g); - diff --git a/packages/gsm/files/magician/default b/packages/gsm/files/magician/default index a9c3b94b1d..523d0b9479 100644 --- a/packages/gsm/files/magician/default +++ b/packages/gsm/files/magician/default @@ -1,9 +1,10 @@ # gsmd This shell script configures for the gsmd init script. -# Set line Discipline 17 (N_TIHTC), needs ldisc.patch-ed gsmd -GSMD_OPTS="-s 115200 -F -D 17" +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/magician/ldisc.patch b/packages/gsm/files/magician/ldisc.patch deleted file mode 100644 index 30d4a8812a..0000000000 --- a/packages/gsm/files/magician/ldisc.patch +++ /dev/null @@ -1,66 +0,0 @@ -Index: gsm/src/gsmd/gsmd.c -=================================================================== ---- gsm.orig/src/gsmd/gsmd.c 2007-03-29 15:29:31.000000000 +0200 -+++ gsm/src/gsmd/gsmd.c 2007-03-29 15:33:07.000000000 +0200 -@@ -32,6 +32,7 @@ - #define _GNU_SOURCE - #include <getopt.h> - -+#include <sys/ioctl.h> - #include <sys/types.h> - #include <sys/stat.h> - -@@ -150,6 +151,7 @@ - { "speed", 1, NULL, 's' }, - { "logfile", 1, NULL, 'l' }, - { "hwflow", 0, NULL, 'F' }, -+ { "ldisc", 1, NULL, 'D' }, - { "leak-report", 0, NULL, 'L' }, - { 0, 0, 0, 0 } - }; -@@ -165,6 +167,7 @@ - "\t-p dev\t--device dev\tSpecify serial device to be used\n" - "\t-s spd\t--speed spd\tSpecify speed in bps (9600,38400,115200,...)\n" - "\t-F\t--hwflow\tHardware Flow Control (RTS/CTS)\n" -+ "\t-D\t--ldisc num\tSet line discipline (0=N_TTY,...)\n" - "\t-L\t--leak-report\tLeak Report of talloc memory allocator\n" - "\t-l file\t--logfile file\tSpecify a logfile to log to\n" - ); -@@ -191,6 +194,7 @@ - int daemonize = 0; - int bps = 115200; - int hwflow = 0; -+ int ldisc = 0; - char *device = "/dev/ttyUSB0"; - char *logfile = "syslog"; - -@@ -202,7 +206,7 @@ - gsmd_tallocs = talloc_named_const(NULL, 1, "GSMD"); - - /*FIXME: parse commandline, set daemonize, device, ... */ -- while ((argch = getopt_long(argc, argv, "FVLdhp:s:l:", opts, NULL)) != -1) { -+ while ((argch = getopt_long(argc, argv, "FVLdhp:s:l:D:", opts, NULL)) != -1) { - switch (argch) { - case 'V': - /* FIXME */ -@@ -232,6 +236,8 @@ - fprintf(stderr, "can't open logfile `%s'\n", optarg); - exit(2); - } -+ case 'D': -+ ldisc = atoi(optarg); - break; - } - } -@@ -249,6 +255,11 @@ - exit(1); - } - -+ if (ldisc && ioctl(fd, TIOCSETD, &ldisc) < 0) { -+ fprintf(stderr, "can't set line discipline\n"); -+ exit(1); -+ } -+ - if (gsmd_initialize(&g) < 0) { - fprintf(stderr, "internal error\n"); - exit(1); diff --git a/packages/gsm/files/magician/vendor-tihtc.patch b/packages/gsm/files/magician/vendor-tihtc.patch deleted file mode 100644 index a2f22ffbea..0000000000 --- a/packages/gsm/files/magician/vendor-tihtc.patch +++ /dev/null @@ -1,325 +0,0 @@ -Index: gsm/src/gsmd/vendor_tihtc.c -=================================================================== ---- /dev/null 1970-01-01 00:00:00.000000000 +0000 -+++ gsm/src/gsmd/vendor_tihtc.c 2007-03-27 13:12:05.000000000 +0200 -@@ -0,0 +1,294 @@ -+/* TI [Calypso] with HTC firmware gsmd plugin -+ * -+ * Written by Philipp Zabel <philipp.zabel@gmail.com> -+ * based on vendor_ti.c -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License as published by -+ * the Free Software Foundation; either version 2 of the License, or -+ * (at your option) any later version. -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public License along -+ * with this program; if not, write to the Free Software Foundation, Inc., -+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -+ * -+ */ -+ -+#include <stdlib.h> -+#include <unistd.h> -+#include <string.h> -+#include <stdio.h> -+#include <errno.h> -+ -+#include "gsmd.h" -+ -+#include <gsmd/gsmd.h> -+#include <gsmd/usock.h> -+#include <gsmd/event.h> -+#include <gsmd/talloc.h> -+#include <gsmd/extrsp.h> -+#include <gsmd/atcmd.h> -+#include <gsmd/vendorplugin.h> -+#include <gsmd/unsolicited.h> -+ -+#if 0 -+#include "vendorplugin.h" -+ -+static int -+ti_getopt(struct gsmd *gh, int optname, void *optval, int *optlen) -+{ -+ switch (optname) { -+ case GSMD_OPT_CIPHER_IND: -+ /* FIXME: send AT%CPRI=? */ -+ break; -+ default: -+ return -EINVAL; -+ } -+} -+ -+static int -+ti_setopt(struct gsmd *gh, int optname, const void *optval, int optlen) -+{ -+ switch (optname) { -+ case GSMD_OPT_CIPHER_IND: -+ /* FIXME: send AT%CPRI= */ -+ break; -+ default: -+ return -EINVAL; -+ } -+} -+ -+#endif -+ -+ -+static int htccsq_parse(char *buf, int len, const char *param, -+ struct gsmd *gsmd) -+{ -+ char *tok; -+ struct gsmd_evt_auxdata *aux; -+ struct gsmd_ucmd *ucmd = usock_build_event(GSMD_MSG_EVENT, GSMD_EVT_SIGNAL, -+ sizeof(*aux)); -+ -+ DEBUGP("entering htccsq_parse param=`%s'\n", param); -+ if (!ucmd) -+ return -EINVAL; -+ -+ -+ 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); -+ aux->u.signal.sigq.ber = 99; -+ -+ DEBUGP("sending EVT_SIGNAL\n"); -+ usock_evt_send(gsmd, ucmd, GSMD_EVT_SIGNAL); -+ -+ return 0; -+ -+out_free_io: -+ free(ucmd); -+ return -EIO; -+} -+ -+static int cpri_parse(char *buf, int len, const char *param, struct gsmd *gsmd) -+{ -+ char *tok1, *tok2; -+ -+ tok1 = strtok(buf, ","); -+ if (!tok1) -+ return -EIO; -+ -+ tok2 = strtok(NULL, ","); -+ if (!tok2) { -+ switch (atoi(tok1)) { -+ case 0: -+ gsmd->dev_state.ciph_ind.flags &= ~GSMD_CIPHIND_ACTIVE; -+ break; -+ case 1: -+ gsmd->dev_state.ciph_ind.flags |= GSMD_CIPHIND_ACTIVE; -+ break; -+ case 2: -+ gsmd->dev_state.ciph_ind.flags |= GSMD_CIPHIND_DISABLED_SIM; -+ break; -+ } -+ } else { -+ struct gsmd_evt_auxdata *aux; -+ struct gsmd_ucmd *ucmd = usock_build_event(GSMD_MSG_EVENT, -+ GSMD_EVT_CIPHER, -+ sizeof(*aux)); -+ if (!ucmd) -+ return -ENOMEM; -+ -+ aux = (struct gsmd_evt_auxdata *) ucmd->buf; -+ -+ aux->u.cipher.net_state_gsm = atoi(tok1); -+ aux->u.cipher.net_state_gsm = atoi(tok2); -+ -+ usock_evt_send(gsmd, ucmd, GSMD_EVT_CIPHER); -+ } -+ -+ return 0; -+} -+ -+/* Call Progress Information */ -+static int cpi_parse(char *buf, int len, const char *param, struct gsmd *gsmd) -+{ -+ char *tok; -+ struct gsmd_evt_auxdata *aux; -+ struct gsmd_ucmd *ucmd = usock_build_event(GSMD_MSG_EVENT, -+ GSMD_EVT_OUT_STATUS, -+ sizeof(*aux)); -+ -+ DEBUGP("entering cpi_parse param=`%s'\n", param); -+ if (!ucmd) -+ return -EINVAL; -+ -+ aux = (struct gsmd_evt_auxdata *) ucmd->buf; -+ -+ /* Format: cId, msgType, ibt, tch, dir,[mode],[number],[type],[alpha],[cause],line */ -+ -+ /* call ID */ -+ tok = strtok(buf, ","); -+ if (!tok) -+ goto out_free_io; -+ -+ /* message type (layer 3) */ -+ tok = strtok(NULL, ","); -+ if (!tok) -+ goto out_free_io; -+ aux->u.call_status.prog = atoi(tok); -+ -+ /* in-band tones */ -+ tok = strtok(NULL, ","); -+ if (!tok) -+ goto out_free_io; -+ -+ if (*tok == '1') -+ aux->u.call_status.ibt = 1; -+ else -+ aux->u.call_status.ibt = 0; -+ -+ /* TCH allocated */ -+ tok = strtok(NULL, ","); -+ if (!tok) -+ goto out_free_io; -+ -+ if (*tok == '1') -+ aux->u.call_status.tch = 1; -+ else -+ aux->u.call_status.tch = 0; -+ -+ /* direction */ -+ tok = strtok(NULL, ","); -+ if (!tok) -+ goto out_send; -+ -+ switch (*tok) { -+ case '0': -+ case '1': -+ case '2': -+ case '3': -+ aux->u.call_status.dir = (*tok - '0'); -+ break; -+ default: -+ break; -+ } -+ -+ /* mode */ -+ tok = strtok(NULL, ","); -+ if (!tok) -+ goto out_send; -+ -+out_send: -+ usock_evt_send(gsmd, ucmd, GSMD_EVT_OUT_STATUS); -+ -+ return 0; -+ -+out_free_io: -+ talloc_free(ucmd); -+ return -EIO; -+} -+ -+static const struct gsmd_unsolicit tihtc_unsolicit[] = { -+ { "%HTCCSQ", &htccsq_parse }, /* Signal Quality */ -+ { "%CPRI", &cpri_parse }, /* Ciphering Indication */ -+ { "%CPI", &cpi_parse }, /* Call Progress Information */ -+ -+ /* FIXME: parse the below and generate the respective events */ -+ -+ /* %CGREG: reports extended information about GPRS registration state */ -+}; -+ -+static int cpi_detect_cb(struct gsmd_atcmd *cmd, void *ctx, char *resp) -+{ -+ struct gsmd *g = ctx; -+ struct gsm_extrsp *er; -+ -+ if (strncmp(resp, "%CPI: ", 6)) -+ return -EINVAL; -+ resp += 6; -+ -+ er = extrsp_parse(cmd, resp); -+ if (!er) -+ return -EINVAL; -+ -+ if (extrsp_supports(er, 0, 3)) -+ return gsmd_simplecmd(g, "AT%CPI=3"); -+ else if (extrsp_supports(er, 0, 2)) -+ return gsmd_simplecmd(g, "AT%CPI=2"); -+ else -+ DEBUGP("Call Progress Indication mode 2 or 3 not supported!!\n"); -+ -+ talloc_free(er); -+ return 0; -+} -+ -+static int tihtc_detect(struct gsmd *g) -+{ -+ /* FIXME: do actual detection of vendor if we have multiple vendors */ -+ /* open /proc/cpuinfo and check for HTC Magician or HTC Blueangel? */ -+ /* check for N_TIHTC ldisc? or set it ourselves? */ -+ return 1; -+} -+ -+static int tihtc_initsettings(struct gsmd *g) -+{ -+ int rc; -+ struct gsmd_atcmd *cmd; -+ -+ /* use %CGREG */ -+ //rc |= gsmd_simplecmd(g, "AT%CGREG=3"); -+ /* enable %CPRI: ciphering indications */ -+ rc |= gsmd_simplecmd(g, "AT%CPRI=1"); -+ /* enable %HTCCSQ: signal quality reports */ -+ rc |= gsmd_simplecmd(g, "AT%HTCCSQ=1"); -+ /* send unsolicited commands at any time */ -+ rc |= gsmd_simplecmd(g, "AT%CUNS=0"); -+ -+ /* enable %CPI: call progress indication */ -+ cmd = atcmd_fill("AT%CPI=?", 9, &cpi_detect_cb, g, 0); -+ if (cmd) -+ atcmd_submit(g, cmd); -+ -+ return rc; -+} -+ -+static struct gsmd_vendor_plugin plugin_tihtc = { -+ .name = "TI Calypso / HTC firmware", -+ .num_unsolicit = ARRAY_SIZE(tihtc_unsolicit), -+ .unsolicit = tihtc_unsolicit, -+ .detect = &tihtc_detect, -+ .initsettings = &tihtc_initsettings, -+}; -+ -+/* FIXME: this will be _init() when we make this a plugin */ -+int tihtc_init(void) -+{ -+ return gsmd_vendor_plugin_register(&plugin_tihtc); -+} -Index: gsm/src/gsmd/gsmd.c -=================================================================== ---- gsm.orig/src/gsmd/gsmd.c 2007-03-27 13:07:59.000000000 +0200 -+++ gsm/src/gsmd/gsmd.c 2007-03-27 13:08:08.000000000 +0200 -@@ -276,7 +276,7 @@ - } - - /* FIXME: do this dynamically */ -- ticalypso_init(); -+ tihtc_init(); - - gsmd_vendor_plugin_find(&g); - -Index: gsm/src/gsmd/Makefile.am -=================================================================== ---- gsm.orig/src/gsmd/Makefile.am 2007-03-27 13:09:11.000000000 +0200 -+++ gsm/src/gsmd/Makefile.am 2007-03-27 13:09:20.000000000 +0200 -@@ -4,7 +4,7 @@ - sbin_PROGRAMS = gsmd - - gsmd_SOURCES = gsmd.c atcmd.c select.c vendor.c usock.c unsolicited.c log.c \ -- vendor_ti.c talloc.c operator_cache.c ext_response.c -+ vendor_ti.c vendor_tihtc.c talloc.c operator_cache.c ext_response.c - #gsmd_LDADD = ../libgsmd/libgsmd.la - #gsmd_LDFLAGS = -dynamic - diff --git a/packages/gsm/files/numeric.patch b/packages/gsm/files/numeric.patch new file mode 100644 index 0000000000..cd1990cbe5 --- /dev/null +++ b/packages/gsm/files/numeric.patch @@ -0,0 +1,56 @@ +Index: gsm/src/gsmd/atcmd.c +=================================================================== +--- gsm.orig/src/gsmd/atcmd.c 2007-04-02 09:59:16.000000000 +0200 ++++ gsm/src/gsmd/atcmd.c 2007-04-02 10:10:54.000000000 +0200 +@@ -207,7 +207,7 @@ + * TBD + */ + +- if (buf[0] == '+' || buf[0] == '%') { ++ if (buf[0] == '+' || buf[0] == '%' || buf[0] == '@') { + /* an extended response */ + const char *colon = strchr(buf, ':'); + if (!colon) { +@@ -269,14 +269,13 @@ + memcpy(cmd->buf, buf, len); + } + } else { +- if (!strcmp(buf, "RING")) { ++ if (!strcmp(buf, "RING") || buf[0] == '2') { + /* this is the only non-extended unsolicited return + * code, part of Case 'B' */ + return unsolicited_parse(g, buf, len, NULL); + } + +- if (!strcmp(buf, "ERROR") || +- ((g->flags & GSMD_FLAG_V0) && buf[0] == '4')) { ++ if (!strcmp(buf, "ERROR") || buf[0] == '4') { + /* Part of Case 'C' */ + DEBUGP("unspecified error\n"); + if (cmd) +@@ -285,8 +284,7 @@ + goto final_cb; + } + +- if (!strncmp(buf, "OK", 2) +- || ((g->flags & GSMD_FLAG_V0) && buf[0] == '0')) { ++ if (!strncmp(buf, "OK", 2) || buf[0] == '0') { + /* Part of Case 'C' */ + if (cmd) + cmd->ret = 0; +@@ -296,13 +294,13 @@ + + /* FIXME: handling of those special commands in response to + * ATD / ATA */ +- if (!strncmp(buf, "NO CARRIER", 11)) { ++ if (!strncmp(buf, "NO CARRIER", 11) || buf[0] == '3') { + /* Part of Case 'D' */ + final = 1; + goto final_cb; + } + +- if (!strncmp(buf, "BUSY", 4)) { ++ if (!strncmp(buf, "BUSY", 4) || buf[0] == '7') { + /* Part of Case 'D' */ + final = 1; + goto final_cb; diff --git a/packages/gsm/files/plugin.patch b/packages/gsm/files/plugin.patch new file mode 100644 index 0000000000..7f455ce718 --- /dev/null +++ b/packages/gsm/files/plugin.patch @@ -0,0 +1,935 @@ +Index: gsm/include/gsmd/gsmd.h +=================================================================== +--- gsm.orig/include/gsmd/gsmd.h 2007-04-02 09:58:55.000000000 +0200 ++++ gsm/include/gsmd/gsmd.h 2007-04-02 11:03:41.000000000 +0200 +@@ -7,6 +7,7 @@ + + #include <common/linux_list.h> + ++#include <gsmd/machineplugin.h> + #include <gsmd/vendorplugin.h> + #include <gsmd/select.h> + #include <gsmd/state.h> +@@ -58,12 +59,14 @@ + + struct gsmd { + unsigned int flags; ++ int interpreter_ready; + struct gsmd_fd gfd_uart; + struct gsmd_fd gfd_sock; + struct llparser llp; + struct llist_head users; + struct llist_head pending_atcmds; /* our busy gsmd_atcmds */ + struct llist_head busy_atcmds; /* our busy gsmd_atcmds */ ++ struct gsmd_machine_plugin *machinepl; + struct gsmd_vendor_plugin *vendorpl; + struct gsmd_device_state dev_state; + +Index: gsm/include/gsmd/machineplugin.h +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ gsm/include/gsmd/machineplugin.h 2007-04-02 11:03:41.000000000 +0200 +@@ -0,0 +1,24 @@ ++#ifndef _GSMD_MACHINEPLUG_H ++#define _GSMD_MACHINEPLUG_H ++ ++#ifdef __GSMD__ ++ ++#include <common/linux_list.h> ++#include <gsmd/gsmd.h> ++ ++struct gsmd; ++ ++struct gsmd_machine_plugin { ++ struct llist_head list; ++ unsigned char *name; ++ int (*detect)(struct gsmd *g); ++ int (*init)(struct gsmd *g, int fd); ++}; ++ ++extern int gsmd_machine_plugin_register(struct gsmd_machine_plugin *pl); ++extern void gsmd_machine_plugin_unregister(struct gsmd_machine_plugin *pl); ++extern int gsmd_machine_plugin_find(struct gsmd *g); ++ ++#endif /* __GSMD__ */ ++ ++#endif +Index: gsm/src/gsmd/machine_tihtc.c +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ gsm/src/gsmd/machine_tihtc.c 2007-04-02 11:03:41.000000000 +0200 +@@ -0,0 +1,71 @@ ++/* TI [Calypso] with HTC firmware machine plugin ++ * ++ * Written by Philipp Zabel <philipp.zabel@gmail.com> ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License as published by ++ * the Free Software Foundation; either version 2 of the License, or ++ * (at your option) any later version. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public License along ++ * with this program; if not, write to the Free Software Foundation, Inc., ++ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. ++ * ++ */ ++ ++#include <stdlib.h> ++#include <unistd.h> ++#include <string.h> ++#include <stdio.h> ++#include <errno.h> ++#include <sys/ioctl.h> ++ ++#include "gsmd.h" ++ ++#include <gsmd/gsmd.h> ++#include <gsmd/usock.h> ++#include <gsmd/event.h> ++#include <gsmd/talloc.h> ++#include <gsmd/extrsp.h> ++#include <gsmd/machineplugin.h> ++ ++#define N_TIHTC 17 ++ ++static int tihtc_detect(struct gsmd *g) ++{ ++ /* FIXME: do actual detection of machine if we have multiple machines */ ++ return 1; ++} ++ ++static int tihtc_init(struct gsmd *g, int fd) ++{ ++ int ldisc = N_TIHTC; ++ int rc; ++ ++ /* ++ * Himalaya, Blueangel, Alpine and Magican ++ * power up their GSM chipsets when the ++ * tty is opened. Wait for the "AT-Command ++ * Interpreter ready" message before trying ++ * to send commands. ++ */ ++ g->interpreter_ready = 0; ++ ++ /* Set the line discipline to N_TIHTC */ ++ rc = ioctl(fd, TIOCSETD, &ldisc); ++ if (rc < 0) ++ fprintf(stderr, "can't set line discipline\n"); ++ ++ return rc; ++} ++ ++struct gsmd_machine_plugin gsmd_machine_plugin = { ++ .name = "TI Calypso / HTC firmware", ++ .detect = &tihtc_detect, ++ .init = &tihtc_init, ++}; +Index: gsm/src/gsmd/machine_generic.c +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ gsm/src/gsmd/machine_generic.c 2007-04-02 11:03:41.000000000 +0200 +@@ -0,0 +1,61 @@ ++/* generic machine plugin ++ * ++ * Written by Philipp Zabel <philipp.zabel@gmail.com> ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License as published by ++ * the Free Software Foundation; either version 2 of the License, or ++ * (at your option) any later version. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public License along ++ * with this program; if not, write to the Free Software Foundation, Inc., ++ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. ++ * ++ */ ++ ++#include <stdlib.h> ++#include <unistd.h> ++#include <string.h> ++#include <stdio.h> ++#include <errno.h> ++ ++#include "gsmd.h" ++ ++#include <gsmd/gsmd.h> ++#include <gsmd/usock.h> ++#include <gsmd/event.h> ++#include <gsmd/talloc.h> ++#include <gsmd/extrsp.h> ++#include <gsmd/machineplugin.h> ++ ++static int generic_detect(struct gsmd *g) ++{ ++ /* FIXME: do actual detection of machine if we have multiple machines */ ++ return 1; ++} ++ ++static int generic_init(struct gsmd *g, int fd) ++{ ++ int rc; ++ ++ /* ++ * We assume that the GSM chipset can take ++ * input immediately, so we don't have to ++ * wait for the "AT-Command Interpreter ready" ++ * message before trying to send commands. ++ */ ++ g->interpreter_ready = 1; ++ ++ return 0; ++} ++ ++struct gsmd_machine_plugin gsmd_machine_plugin = { ++ .name = "generic", ++ .detect = &generic_detect, ++ .init = &generic_init, ++}; +Index: gsm/src/gsmd/machine.c +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ gsm/src/gsmd/machine.c 2007-04-02 13:43:04.000000000 +0200 +@@ -0,0 +1,140 @@ ++/* gsmd machine plugin core ++ * ++ * Written by Philipp Zabel <philipp.zabel@gmail.com> ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License as published by ++ * the Free Software Foundation; either version 2 of the License, or ++ * (at your option) any later version. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public License along ++ * with this program; if not, write to the Free Software Foundation, Inc., ++ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. ++ * ++ */ ++ ++#include <dlfcn.h> ++#include <errno.h> ++#include <stdio.h> ++#include <string.h> ++ ++#include <common/linux_list.h> ++ ++#include "gsmd.h" ++ ++#include <gsmd/gsmd.h> ++#include <gsmd/machineplugin.h> ++ ++static LLIST_HEAD(machinepl_list); ++ ++int gsmd_machine_plugin_register(struct gsmd_machine_plugin *pl) ++{ ++ llist_add(&pl->list, &machinepl_list); ++ ++ return 0; ++} ++ ++void gsmd_machine_plugin_unregister(struct gsmd_machine_plugin *pl) ++{ ++ llist_del(&pl->list); ++} ++ ++int gsmd_machine_plugin_find(struct gsmd *g) ++{ ++ struct gsmd_machine_plugin *pl; ++ ++ if (g->machinepl) ++ return -EEXIST; ++ ++ llist_for_each_entry(pl, &machinepl_list, list) { ++ if (pl->detect(g) == 1) { ++ DEBUGP("selecting machine plugin \"%s\"\n", pl->name); ++ g->machinepl = pl; ++ return 1; ++ } ++ } ++ ++ return 0; ++} ++ ++int gsmd_machine_plugin_load(char *name) ++{ ++ int rc = -1; ++ void *plugin; ++ struct gsmd_machine_plugin *pl; ++ char buf[128]; ++ ++ DEBUGP("loading machine plugin \"%s\"\n", name); ++ ++ snprintf(buf, sizeof(buf), PLUGINDIR"/libgsmd-machine_%s.so", name); ++ ++ plugin = dlopen(buf, RTLD_LAZY); ++ if (!plugin) { ++ fprintf(stderr, "gsmd_machine_plugin_load: %s\n", dlerror()); ++ return -1; ++ } ++ ++ pl = dlsym(plugin, "gsmd_machine_plugin"); ++ if (pl) ++ rc = gsmd_machine_plugin_register(pl); ++ else ++ dlclose(plugin); ++ ++ return rc; ++} ++ ++/* maybe /etc/gsmd/cpuinfo */ ++struct machines { ++ char *cpuinfo; ++ char *machine; ++ char *vendor; ++} machines[] = { ++ { "GTA01", "generic", "ti" }, ++ { "HTC Blueangel", "tihtc", "tihtc" }, ++ { "HTC Himalaya", "tihtc", "tihtc" }, ++ { "HTC Magician", "tihtc", "tihtc" }, ++ { "HTC Universal", "generic", "qc" }, ++ { NULL, NULL, NULL }, ++}; ++ ++int gsmd_machine_plugin_init(struct gsmd *g, int fd) ++{ ++ FILE *cpuinfo; ++ char buf[1024]; ++ char *line, *machine = NULL; ++ int i, rc; ++ ++ cpuinfo = fopen("/proc/cpuinfo", "r"); ++ fread(buf, sizeof(buf), 1, cpuinfo); ++ fclose(cpuinfo); ++ ++ line = strtok(buf, "\n"); ++ while (line = strtok(NULL, "\n")) { ++ if (strncmp(line, "Hardware\t: ", 11) == 0) { ++ machine = line+11; ++ break; ++ } ++ } ++ /* FIXME: do this dynamically */ ++ if (machine) { ++ for (i = 0; machines[i].cpuinfo; i++) { ++ if (strcmp(machine, machines[i].cpuinfo) == 0) { ++ DEBUGP("detected %s\n", machine); ++ rc = gsmd_machine_plugin_load(machines[i].machine); ++ rc |= gsmd_vendor_plugin_load(machines[i].vendor); ++ return rc; ++ } ++ } ++ } ++ /* load generic machine and all vendor plugins */ ++ rc = gsmd_machine_plugin_load("generic"); ++ gsmd_vendor_plugin_load("ti"); ++ gsmd_vendor_plugin_load("tihtc"); ++ gsmd_vendor_plugin_load("qc"); ++ return rc; ++} +Index: gsm/src/gsmd/vendor_qc.c +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ gsm/src/gsmd/vendor_qc.c 2007-04-02 11:03:41.000000000 +0200 +@@ -0,0 +1,104 @@ ++/* Qualcomm [msm6250] gsmd plugin ++ * ++ * Written by Philipp Zabel <philipp.zabel@gmail.com> ++ * based on vendor_ti.c ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License as published by ++ * the Free Software Foundation; either version 2 of the License, or ++ * (at your option) any later version. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public License along ++ * with this program; if not, write to the Free Software Foundation, Inc., ++ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. ++ * ++ */ ++ ++#include <stdlib.h> ++#include <unistd.h> ++#include <string.h> ++#include <stdio.h> ++#include <errno.h> ++ ++#include "gsmd.h" ++ ++#include <gsmd/gsmd.h> ++#include <gsmd/usock.h> ++#include <gsmd/event.h> ++#include <gsmd/talloc.h> ++#include <gsmd/extrsp.h> ++#include <gsmd/atcmd.h> ++#include <gsmd/vendorplugin.h> ++#include <gsmd/unsolicited.h> ++ ++static int htccsq_parse(char *buf, int len, const char *param, ++ struct gsmd *gsmd) ++{ ++ char *tok; ++ 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 }; /* FIXME */ ++ unsigned int i; ++ ++ DEBUGP("entering htccsq_parse param=`%s'\n", param); ++ if (!ucmd) ++ return -EINVAL; ++ ++ ++ aux = (struct gsmd_evt_auxdata *) ucmd->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"); ++ usock_evt_send(gsmd, ucmd, GSMD_EVT_SIGNAL); ++ ++ return 0; ++ ++out_free_io: ++ free(ucmd); ++ return -EIO; ++} ++ ++static const struct gsmd_unsolicit qc_unsolicit[] = { ++ { "@HTCCSQ", &htccsq_parse }, /* Signal Quality */ ++ ++ /* FIXME: parse the below and generate the respective events */ ++ ++ /* %CGREG: reports extended information about GPRS registration state */ ++}; ++ ++static int qc_detect(struct gsmd *g) ++{ ++ /* FIXME: do actual detection of vendor if we have multiple vendors */ ++ /* open /proc/cpuinfo and check for HTC Universal? */ ++ return 1; ++} ++ ++static int qc_initsettings(struct gsmd *g) ++{ ++ int rc; ++ struct gsmd_atcmd *cmd; ++ ++ /* enable @HTCCSQ: signal quality reports */ ++ rc |= gsmd_simplecmd(g, "AT@HTCCSQ=1"); ++ ++ return rc; ++} ++ ++struct gsmd_vendor_plugin gsmd_vendor_plugin = { ++ .name = "Qualcomm msm6250", ++ .num_unsolicit = ARRAY_SIZE(qc_unsolicit), ++ .unsolicit = qc_unsolicit, ++ .detect = &qc_detect, ++ .initsettings = &qc_initsettings, ++}; +Index: gsm/src/gsmd/Makefile.am +=================================================================== +--- gsm.orig/src/gsmd/Makefile.am 2007-04-02 09:58:55.000000000 +0200 ++++ gsm/src/gsmd/Makefile.am 2007-04-02 13:33:11.000000000 +0200 +@@ -1,11 +1,26 @@ + INCLUDES = $(all_includes) -I$(top_srcdir)/include + AM_CFLAGS = -std=gnu99 ++plugindir = $(libdir)/gsmd + + sbin_PROGRAMS = gsmd + +-gsmd_SOURCES = gsmd.c atcmd.c select.c vendor.c usock.c unsolicited.c log.c \ +- vendor_ti.c talloc.c operator_cache.c ext_response.c +-#gsmd_LDADD = ../libgsmd/libgsmd.la +-#gsmd_LDFLAGS = -dynamic ++gsmd_CFLAGS = -D PLUGINDIR=\"$(plugindir)\" ++gsmd_SOURCES = gsmd.c atcmd.c select.c machine.c vendor.c unsolicited.c log.c \ ++ usock.c talloc.c operator_cache.c ext_response.c ++gsmd_LDADD = -ldl ++gsmd_LDFLAGS = -Wl,--export-dynamic ++ ++plugin_LTLIBRARIES = libgsmd-machine_generic.la \ ++ libgsmd-machine_tihtc.la \ ++ libgsmd-vendor_ti.la \ ++ libgsmd-vendor_tihtc.la \ ++ libgsmd-vendor_qc.la ++ ++libgsmd_machine_generic_la_SOURCES = machine_generic.c ++libgsmd_machine_tihtc_la_SOURCES = machine_tihtc.c ++ ++libgsmd_vendor_ti_la_SOURCES = vendor_ti.c ++libgsmd_vendor_tihtc_la_SOURCES = vendor_tihtc.c ++libgsmd_vendor_qc_la_SOURCES = vendor_qc.c + + noinst_HEADERS = gsmd.h +Index: gsm/src/gsmd/atcmd.c +=================================================================== +--- gsm.orig/src/gsmd/atcmd.c 2007-04-02 11:03:40.000000000 +0200 ++++ gsm/src/gsmd/atcmd.c 2007-04-02 11:03:41.000000000 +0200 +@@ -183,6 +183,7 @@ + * an empty string or that 'ready' string, we need to init the modem */ + if (strlen(buf) == 0 || + !strcmp(buf, "AT-Command Interpreter ready")) { ++ g->interpreter_ready = 1; + gsmd_initsettings(g); + return 0; + } +@@ -370,7 +371,7 @@ + } + + /* write pending commands to UART */ +- if (what & GSMD_FD_WRITE) { ++ 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); +Index: gsm/src/gsmd/vendor_tihtc.c +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ gsm/src/gsmd/vendor_tihtc.c 2007-04-02 13:16:45.000000000 +0200 +@@ -0,0 +1,305 @@ ++/* TI [Calypso] with HTC firmware gsmd plugin ++ * ++ * Written by Philipp Zabel <philipp.zabel@gmail.com> ++ * based on vendor_ti.c ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License as published by ++ * the Free Software Foundation; either version 2 of the License, or ++ * (at your option) any later version. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public License along ++ * with this program; if not, write to the Free Software Foundation, Inc., ++ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. ++ * ++ */ ++ ++#include <stdlib.h> ++#include <unistd.h> ++#include <string.h> ++#include <stdio.h> ++#include <errno.h> ++ ++#include "gsmd.h" ++ ++#include <gsmd/gsmd.h> ++#include <gsmd/usock.h> ++#include <gsmd/event.h> ++#include <gsmd/talloc.h> ++#include <gsmd/extrsp.h> ++#include <gsmd/atcmd.h> ++#include <gsmd/vendorplugin.h> ++#include <gsmd/unsolicited.h> ++ ++static int gsmd_test_atcb(struct gsmd_atcmd *cmd, void *ctx, char *resp) ++{ ++ printf("`%s' returned `%s'\n", cmd->buf, resp); ++ return 0; ++} ++ ++int gsmd_simplecmd(struct gsmd *gsmd, char *cmdtxt) ++{ ++ struct gsmd_atcmd *cmd; ++ cmd = atcmd_fill(cmdtxt, strlen(cmdtxt)+1, &gsmd_test_atcb, NULL, 0); ++ if (!cmd) ++ return -ENOMEM; ++ ++ return atcmd_submit(gsmd, cmd); ++} ++ ++ ++#if 0 ++#include "vendorplugin.h" ++ ++static int ++ti_getopt(struct gsmd *gh, int optname, void *optval, int *optlen) ++{ ++ switch (optname) { ++ case GSMD_OPT_CIPHER_IND: ++ /* FIXME: send AT%CPRI=? */ ++ break; ++ default: ++ return -EINVAL; ++ } ++} ++ ++static int ++ti_setopt(struct gsmd *gh, int optname, const void *optval, int optlen) ++{ ++ switch (optname) { ++ case GSMD_OPT_CIPHER_IND: ++ /* FIXME: send AT%CPRI= */ ++ break; ++ default: ++ return -EINVAL; ++ } ++} ++ ++#endif ++ ++ ++static int htccsq_parse(char *buf, int len, const char *param, ++ struct gsmd *gsmd) ++{ ++ char *tok; ++ struct gsmd_evt_auxdata *aux; ++ struct gsmd_ucmd *ucmd = usock_build_event(GSMD_MSG_EVENT, GSMD_EVT_SIGNAL, ++ sizeof(*aux)); ++ ++ DEBUGP("entering htccsq_parse param=`%s'\n", param); ++ if (!ucmd) ++ return -EINVAL; ++ ++ ++ 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); ++ aux->u.signal.sigq.ber = 99; ++ ++ DEBUGP("sending EVT_SIGNAL\n"); ++ usock_evt_send(gsmd, ucmd, GSMD_EVT_SIGNAL); ++ ++ return 0; ++ ++out_free_io: ++ free(ucmd); ++ return -EIO; ++} ++ ++static int cpri_parse(char *buf, int len, const char *param, struct gsmd *gsmd) ++{ ++ char *tok1, *tok2; ++ ++ tok1 = strtok(buf, ","); ++ if (!tok1) ++ return -EIO; ++ ++ tok2 = strtok(NULL, ","); ++ if (!tok2) { ++ switch (atoi(tok1)) { ++ case 0: ++ gsmd->dev_state.ciph_ind.flags &= ~GSMD_CIPHIND_ACTIVE; ++ break; ++ case 1: ++ gsmd->dev_state.ciph_ind.flags |= GSMD_CIPHIND_ACTIVE; ++ break; ++ case 2: ++ gsmd->dev_state.ciph_ind.flags |= GSMD_CIPHIND_DISABLED_SIM; ++ break; ++ } ++ } else { ++ struct gsmd_evt_auxdata *aux; ++ struct gsmd_ucmd *ucmd = usock_build_event(GSMD_MSG_EVENT, ++ GSMD_EVT_CIPHER, ++ sizeof(*aux)); ++ if (!ucmd) ++ return -ENOMEM; ++ ++ aux = (struct gsmd_evt_auxdata *) ucmd->buf; ++ ++ aux->u.cipher.net_state_gsm = atoi(tok1); ++ aux->u.cipher.net_state_gsm = atoi(tok2); ++ ++ usock_evt_send(gsmd, ucmd, GSMD_EVT_CIPHER); ++ } ++ ++ return 0; ++} ++ ++/* Call Progress Information */ ++static int cpi_parse(char *buf, int len, const char *param, struct gsmd *gsmd) ++{ ++ char *tok; ++ struct gsmd_evt_auxdata *aux; ++ struct gsmd_ucmd *ucmd = usock_build_event(GSMD_MSG_EVENT, ++ GSMD_EVT_OUT_STATUS, ++ sizeof(*aux)); ++ ++ DEBUGP("entering cpi_parse param=`%s'\n", param); ++ if (!ucmd) ++ return -EINVAL; ++ ++ aux = (struct gsmd_evt_auxdata *) ucmd->buf; ++ ++ /* Format: cId, msgType, ibt, tch, dir,[mode],[number],[type],[alpha],[cause],line */ ++ ++ /* call ID */ ++ tok = strtok(buf, ","); ++ if (!tok) ++ goto out_free_io; ++ ++ /* message type (layer 3) */ ++ tok = strtok(NULL, ","); ++ if (!tok) ++ goto out_free_io; ++ aux->u.call_status.prog = atoi(tok); ++ ++ /* in-band tones */ ++ tok = strtok(NULL, ","); ++ if (!tok) ++ goto out_free_io; ++ ++ if (*tok == '1') ++ aux->u.call_status.ibt = 1; ++ else ++ aux->u.call_status.ibt = 0; ++ ++ /* TCH allocated */ ++ tok = strtok(NULL, ","); ++ if (!tok) ++ goto out_free_io; ++ ++ if (*tok == '1') ++ aux->u.call_status.tch = 1; ++ else ++ aux->u.call_status.tch = 0; ++ ++ /* direction */ ++ tok = strtok(NULL, ","); ++ if (!tok) ++ goto out_send; ++ ++ switch (*tok) { ++ case '0': ++ case '1': ++ case '2': ++ case '3': ++ aux->u.call_status.dir = (*tok - '0'); ++ break; ++ default: ++ break; ++ } ++ ++ /* mode */ ++ tok = strtok(NULL, ","); ++ if (!tok) ++ goto out_send; ++ ++out_send: ++ usock_evt_send(gsmd, ucmd, GSMD_EVT_OUT_STATUS); ++ ++ return 0; ++ ++out_free_io: ++ talloc_free(ucmd); ++ return -EIO; ++} ++ ++static const struct gsmd_unsolicit tihtc_unsolicit[] = { ++ { "%HTCCSQ", &htccsq_parse }, /* Signal Quality */ ++ { "%CPRI", &cpri_parse }, /* Ciphering Indication */ ++ { "%CPI", &cpi_parse }, /* Call Progress Information */ ++ ++ /* FIXME: parse the below and generate the respective events */ ++ ++ /* %CGREG: reports extended information about GPRS registration state */ ++}; ++ ++static int cpi_detect_cb(struct gsmd_atcmd *cmd, void *ctx, char *resp) ++{ ++ struct gsmd *g = ctx; ++ struct gsm_extrsp *er; ++ ++ if (strncmp(resp, "%CPI: ", 6)) ++ return -EINVAL; ++ resp += 6; ++ ++ er = extrsp_parse(cmd, resp); ++ if (!er) ++ return -EINVAL; ++ ++ if (extrsp_supports(er, 0, 3)) ++ return gsmd_simplecmd(g, "AT%CPI=3"); ++ else if (extrsp_supports(er, 0, 2)) ++ return gsmd_simplecmd(g, "AT%CPI=2"); ++ else ++ DEBUGP("Call Progress Indication mode 2 or 3 not supported!!\n"); ++ ++ talloc_free(er); ++ return 0; ++} ++ ++static int tihtc_detect(struct gsmd *g) ++{ ++ /* FIXME: do actual detection of vendor if we have multiple vendors */ ++ /* open /proc/cpuinfo and check for HTC Magician or HTC Blueangel? */ ++ /* check for N_TIHTC ldisc? or set it ourselves? */ ++ return 1; ++} ++ ++static int tihtc_initsettings(struct gsmd *g) ++{ ++ int rc; ++ struct gsmd_atcmd *cmd; ++ ++ /* use %CGREG */ ++ //rc |= gsmd_simplecmd(g, "AT%CGREG=3"); ++ /* enable %CPRI: ciphering indications */ ++ rc |= gsmd_simplecmd(g, "AT%CPRI=1"); ++ /* enable %HTCCSQ: signal quality reports */ ++ rc |= gsmd_simplecmd(g, "AT%HTCCSQ=1"); ++ /* send unsolicited commands at any time */ ++ rc |= gsmd_simplecmd(g, "AT%CUNS=0"); ++ ++ /* enable %CPI: call progress indication */ ++ cmd = atcmd_fill("AT%CPI=?", 9, &cpi_detect_cb, g, 0); ++ if (cmd) ++ atcmd_submit(g, cmd); ++ ++ return rc; ++} ++ ++struct gsmd_vendor_plugin gsmd_vendor_plugin = { ++ .name = "TI Calypso / HTC firmware", ++ .num_unsolicit = ARRAY_SIZE(tihtc_unsolicit), ++ .unsolicit = tihtc_unsolicit, ++ .detect = &tihtc_detect, ++ .initsettings = &tihtc_initsettings, ++}; +Index: gsm/src/gsmd/vendor_ti.c +=================================================================== +--- gsm.orig/src/gsmd/vendor_ti.c 2007-04-02 09:58:55.000000000 +0200 ++++ gsm/src/gsmd/vendor_ti.c 2007-04-02 11:03:41.000000000 +0200 +@@ -301,16 +301,10 @@ + return rc; + } + +-static struct gsmd_vendor_plugin plugin_ticalypso = { ++struct gsmd_vendor_plugin gsmd_vendor_plugin = { + .name = "TI Calypso", + .num_unsolicit = ARRAY_SIZE(ticalypso_unsolicit), + .unsolicit = ticalypso_unsolicit, + .detect = &ticalypso_detect, + .initsettings = &ticalypso_initsettings, + }; +- +-/* FIXME: this will be _init() when we make this a plugin */ +-int ticalypso_init(void) +-{ +- return gsmd_vendor_plugin_register(&plugin_ticalypso); +-} +Index: gsm/src/gsmd/gsmd.c +=================================================================== +--- gsm.orig/src/gsmd/gsmd.c 2007-04-02 09:58:55.000000000 +0200 ++++ gsm/src/gsmd/gsmd.c 2007-04-02 13:39:40.000000000 +0200 +@@ -254,6 +254,21 @@ + exit(1); + } + ++ if (gsmd_machine_plugin_init(&g) < 0) { ++ fprintf(stderr, "no machine plugins found\n"); ++ exit(1); ++ } ++ ++ /* select a machine plugin and load possible vendor plugins */ ++ gsmd_machine_plugin_find(&g); ++ ++ /* initialize the machine plugin */ ++ if (g.machinepl->init) ++ if (g.machinepl->init(&g, fd) < 0) { ++ fprintf(stderr, "couldn't initialize machine plugin\n"); ++ exit(1); ++ } ++ + if (atcmd_init(&g, fd) < 0) { + fprintf(stderr, "can't initialize UART device\n"); + exit(1); +@@ -275,12 +290,11 @@ + setsid(); + } + +- /* FIXME: do this dynamically */ +- ticalypso_init(); +- ++ /* select a vendor plugin */ + gsmd_vendor_plugin_find(&g); + +- gsmd_initsettings(&g); ++ if (g.interpreter_ready) ++ gsmd_initsettings(&g); + + gsmd_opname_init(&g); + +Index: gsm/src/gsmd/vendor.c +=================================================================== +--- gsm.orig/src/gsmd/vendor.c 2007-04-02 09:58:55.000000000 +0200 ++++ gsm/src/gsmd/vendor.c 2007-04-02 13:38:38.000000000 +0200 +@@ -20,7 +20,10 @@ + * + */ + ++#include <dlfcn.h> + #include <errno.h> ++#include <stdio.h> ++#include <string.h> + + #include <common/linux_list.h> + +@@ -52,6 +55,7 @@ + + llist_for_each_entry(pl, &vendorpl_list, list) { + if (pl->detect(g) == 1) { ++ DEBUGP("selecting vendor plugin \"%s\"\n", pl->name); + g->vendorpl = pl; + return 1; + } +@@ -59,3 +63,29 @@ + + return 0; + } ++ ++int gsmd_vendor_plugin_load(char *name) ++{ ++ int rc = -1; ++ void *lib; ++ struct gsmd_vendor_plugin *pl; ++ char buf[128]; ++ ++ DEBUGP("loading vendor plugin \"%s\"\n", name); ++ ++ snprintf(buf, sizeof(buf), PLUGINDIR"/libgsmd-vendor_%s.so", name); ++ ++ lib = dlopen(buf, RTLD_LAZY); ++ if (!lib) { ++ fprintf(stderr, "gsmd_vendor_plugin_load: %s\n", dlerror()); ++ return -1; ++ } ++ ++ pl = dlsym(lib, "gsmd_vendor_plugin"); ++ if (pl) ++ rc = gsmd_vendor_plugin_register(pl); ++ else ++ dlclose(lib); ++ ++ return rc; ++} |