diff options
author | laforge <laforge@99fdad57-331a-0410-800a-d7fa5415bdb3> | 2006-10-20 20:41:12 +0000 |
---|---|---|
committer | laforge <laforge@99fdad57-331a-0410-800a-d7fa5415bdb3> | 2006-10-20 20:41:12 +0000 |
commit | 8045fdfb09c2e3b466f371b2ab64ff01f9f7aec1 (patch) | |
tree | 270a3b123e7d4de7cb55da08e6cf6eb39461777e /src/gsmd | |
parent | 561a8d7fa4a003862b2640bd3458c0188ae2eab8 (diff) |
- some more gsmd / libgsmd code
- use autotools for build process
git-svn-id: http://svn.openmoko.org/trunk/src/target/gsm@94 99fdad57-331a-0410-800a-d7fa5415bdb3
Diffstat (limited to 'src/gsmd')
-rw-r--r-- | src/gsmd/Makefile | 377 | ||||
-rw-r--r-- | src/gsmd/atcmd.c | 65 | ||||
-rw-r--r-- | src/gsmd/atcmd.h | 1 | ||||
-rw-r--r-- | src/gsmd/gsmd.c | 51 | ||||
-rw-r--r-- | src/gsmd/gsmd.h | 1 | ||||
-rw-r--r-- | src/gsmd/unsolicited.c | 119 | ||||
-rw-r--r-- | src/gsmd/unsolicited.h | 1 | ||||
-rw-r--r-- | src/gsmd/usock.c | 30 |
8 files changed, 624 insertions, 21 deletions
diff --git a/src/gsmd/Makefile b/src/gsmd/Makefile index ab0a1bf..c447464 100644 --- a/src/gsmd/Makefile +++ b/src/gsmd/Makefile @@ -1,14 +1,373 @@ +# Makefile.in generated by automake 1.6.3 from Makefile.am. +# src/gsmd/Makefile. Generated from Makefile.in by configure. -CFLAGS:=-I../../include -Wall -g -gsmd_OBJS:=gsmd.o atcmd.o select.o vendor_ti.o usock.o unsolicited.o +# 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. -all: gsmd +# 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. -gsmd: $(gsmd_OBJS) - $(CC) -o $@ $^ -%.o: %.c - $(CC) $(CFLAGS) -o $@ -c $^ +SHELL = /bin/sh -clean: - rm -f $(gsmd_OBJS) gsmd +srcdir = . +top_srcdir = ../.. + +prefix = /usr/local +exec_prefix = ${prefix} + +bindir = ${exec_prefix}/bin +sbindir = ${exec_prefix}/sbin +libexecdir = ${exec_prefix}/libexec +datadir = ${prefix}/share +sysconfdir = ${prefix}/etc +sharedstatedir = ${prefix}/com +localstatedir = ${prefix}/var +libdir = ${exec_prefix}/lib +infodir = ${prefix}/share/info +mandir = ${prefix}/share/man +includedir = ${prefix}/include +oldincludedir = /usr/include +pkgdatadir = $(datadir)/gsmd +pkglibdir = $(libdir)/gsmd +pkgincludedir = $(includedir)/gsmd +top_builddir = ../.. + +ACLOCAL = ${SHELL} /home/laforge/projects/kommerz/fic/phone/svn/src/target/gsm/missing --run aclocal-1.6 +AUTOCONF = ${SHELL} /home/laforge/projects/kommerz/fic/phone/svn/src/target/gsm/missing --run autoconf +AUTOMAKE = ${SHELL} /home/laforge/projects/kommerz/fic/phone/svn/src/target/gsm/missing --run automake-1.6 +AUTOHEADER = ${SHELL} /home/laforge/projects/kommerz/fic/phone/svn/src/target/gsm/missing --run autoheader + +am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd +INSTALL = /usr/bin/install -c +INSTALL_PROGRAM = ${INSTALL} +INSTALL_DATA = ${INSTALL} -m 644 +install_sh_DATA = $(install_sh) -c -m 644 +install_sh_PROGRAM = $(install_sh) -c +install_sh_SCRIPT = $(install_sh) -c +INSTALL_SCRIPT = ${INSTALL} +INSTALL_HEADER = $(INSTALL_DATA) +transform = s,x,x, +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +build_alias = +build_triplet = x86_64-unknown-linux-gnu +host_alias = +host_triplet = x86_64-unknown-linux-gnu +target_alias = +target_triplet = x86_64-unknown-linux-gnu + +EXEEXT = +OBJEXT = o +PATH_SEPARATOR = : +AMTAR = ${SHELL} /home/laforge/projects/kommerz/fic/phone/svn/src/target/gsm/missing --run tar +AR = ar +AS = @AS@ +AWK = gawk +CC = gcc +CXX = g++ +CXXCPP = g++ -E +DEPDIR = .deps +DLLTOOL = @DLLTOOL@ +ECHO = echo +EGREP = /bin/grep -E +F77 = +GCJ = @GCJ@ +GCJFLAGS = @GCJFLAGS@ +INSTALL_STRIP_PROGRAM = ${SHELL} $(install_sh) -c -s +LIBTOOL = $(SHELL) $(top_builddir)/libtool +LIBTOOL_DEPS = ./ltmain.sh +LN_S = ln -s +OBJDUMP = @OBJDUMP@ +PACKAGE = gsmd +RANLIB = ranlib +RC = @RC@ +STRIP = strip +VERSION = 0.0.1 +am__include = include +am__quote = +install_sh = /home/laforge/projects/kommerz/fic/phone/svn/src/target/gsm/install-sh +INCLUDES = $(all_includes) -I$(top_srcdir)/include +AM_CFLAGS = -std=gnu99 + +bin_PROGRAMS = gsmd + +gsmd_SOURCES = gsmd.c atcmd.c select.c vendor_ti.c usock.c unsolicited.c +subdir = src/gsmd +mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs +CONFIG_CLEAN_FILES = +bin_PROGRAMS = gsmd$(EXEEXT) +PROGRAMS = $(bin_PROGRAMS) + +am_gsmd_OBJECTS = gsmd.$(OBJEXT) atcmd.$(OBJEXT) select.$(OBJEXT) \ + vendor_ti.$(OBJEXT) usock.$(OBJEXT) unsolicited.$(OBJEXT) +gsmd_OBJECTS = $(am_gsmd_OBJECTS) +gsmd_LDADD = $(LDADD) +gsmd_DEPENDENCIES = +gsmd_LDFLAGS = + +DEFS = -DPACKAGE_NAME=\"\" -DPACKAGE_TARNAME=\"\" -DPACKAGE_VERSION=\"\" -DPACKAGE_STRING=\"\" -DPACKAGE_BUGREPORT=\"\" -DPACKAGE=\"gsmd\" -DVERSION=\"0.0.1\" -DSTDC_HEADERS=1 -DHAVE_SYS_TYPES_H=1 -DHAVE_SYS_STAT_H=1 -DHAVE_STDLIB_H=1 -DHAVE_STRING_H=1 -DHAVE_MEMORY_H=1 -DHAVE_STRINGS_H=1 -DHAVE_INTTYPES_H=1 -DHAVE_STDINT_H=1 -DHAVE_UNISTD_H=1 -DHAVE_DLFCN_H=1 +DEFAULT_INCLUDES = -I. -I$(srcdir) +CPPFLAGS = +LDFLAGS = +LIBS = +depcomp = $(SHELL) $(top_srcdir)/depcomp +am__depfiles_maybe = depfiles +DEP_FILES = ./$(DEPDIR)/atcmd.Po ./$(DEPDIR)/gsmd.Po \ + ./$(DEPDIR)/select.Po ./$(DEPDIR)/unsolicited.Po \ + ./$(DEPDIR)/usock.Po ./$(DEPDIR)/vendor_ti.Po +COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ + $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +LTCOMPILE = $(LIBTOOL) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) \ + $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +CCLD = $(CC) +LINK = $(LIBTOOL) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ + $(AM_LDFLAGS) $(LDFLAGS) -o $@ +CFLAGS = -g -O2 +DIST_SOURCES = $(gsmd_SOURCES) +DIST_COMMON = Makefile.am Makefile.in +SOURCES = $(gsmd_SOURCES) + +all: all-am + +.SUFFIXES: +.SUFFIXES: .c .lo .o .obj +$(srcdir)/Makefile.in: Makefile.am $(top_srcdir)/configure.in $(ACLOCAL_M4) + cd $(top_srcdir) && \ + $(AUTOMAKE) --gnu src/gsmd/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 +gsmd$(EXEEXT): $(gsmd_OBJECTS) $(gsmd_DEPENDENCIES) + @rm -f gsmd$(EXEEXT) + $(LINK) $(gsmd_LDFLAGS) $(gsmd_OBJECTS) $(gsmd_LDADD) $(LIBS) + +mostlyclean-compile: + -rm -f *.$(OBJEXT) core *.core + +distclean-compile: + -rm -f *.tab.c + +include ./$(DEPDIR)/atcmd.Po +include ./$(DEPDIR)/gsmd.Po +include ./$(DEPDIR)/select.Po +include ./$(DEPDIR)/unsolicited.Po +include ./$(DEPDIR)/usock.Po +include ./$(DEPDIR)/vendor_ti.Po + +distclean-depend: + -rm -rf ./$(DEPDIR) + +.c.o: + source='$<' object='$@' libtool=no \ + depfile='$(DEPDIR)/$*.Po' tmpdepfile='$(DEPDIR)/$*.TPo' \ + $(CCDEPMODE) $(depcomp) \ + $(COMPILE) -c `test -f '$<' || echo '$(srcdir)/'`$< + +.c.obj: + source='$<' object='$@' libtool=no \ + depfile='$(DEPDIR)/$*.Po' tmpdepfile='$(DEPDIR)/$*.TPo' \ + $(CCDEPMODE) $(depcomp) \ + $(COMPILE) -c `cygpath -w $<` + +.c.lo: + source='$<' object='$@' libtool=yes \ + depfile='$(DEPDIR)/$*.Plo' tmpdepfile='$(DEPDIR)/$*.TPlo' \ + $(CCDEPMODE) $(depcomp) \ + $(LTCOMPILE) -c -o $@ `test -f '$<' || echo '$(srcdir)/'`$< +CCDEPMODE = depmode=gcc3 + +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 + +#gsmd_LDADD = ../libgsmd/libgsmd.la +#gsmd_LDFLAGS = -dynamic +# 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: diff --git a/src/gsmd/atcmd.c b/src/gsmd/atcmd.c index f482eb2..ed061e2 100644 --- a/src/gsmd/atcmd.c +++ b/src/gsmd/atcmd.c @@ -3,10 +3,13 @@ #include <stdlib.h> #include <string.h> #include <errno.h> +#include <termios.h> #include <sys/types.h> #include <common/linux_list.h> +#include <gsmd/ts0707.h> + #include "gsmd.h" #include "atcmd.h" #include "unsolicited.h" @@ -44,8 +47,10 @@ static inline int llparse_append(struct llparser *llp, char byte) if (llp->cur < llp->buf + llp->len) { *(llp->cur++) = byte; return 0; - } else + } else { + printf("llp->cur too big!!!\n"); return -EFBIG; + } } static int llparse_byte(struct llparser *llp, char byte) @@ -121,6 +126,12 @@ static int llparse_string(struct llparser *llp, char *buf, unsigned int len) return 0; } +static int llparse_init(struct llparser *llp) +{ + llp->state = LLPARSE_STATE_IDLE; + return 0; +} + /* mid-level parser */ static int parse_final_result(const char *res) @@ -143,6 +154,7 @@ static int ml_parse(const char *buf, int len, void *ctx) /* responses come in order, so first response has to be for first * command we sent, i.e. first entry in list */ cmd = llist_entry(g->busy_atcmds.next, struct gsmd_atcmd, list); + cmd->resp = buf; if (buf[0] == '+') { /* an extended response */ @@ -214,33 +226,40 @@ static int ml_parse(const char *buf, int len, void *ctx) } final_cb: + if (cmd->ret != 0) + generate_event_from_cme(g, cmd->ret); if (final) { /* remove from list of currently executing cmds */ llist_del(&cmd->list); - if (cmd->cb) { + /* if we're finished with current commands, but still have pending + * commands: we want to WRITE again */ + if (llist_empty(&g->busy_atcmds) && !llist_empty(&g->pending_atcmds)) + g->gfd_uart.when |= GSMD_FD_WRITE; + + if (!cmd->cb) { fprintf(stderr, "command without cb!!!\n"); return -EINVAL; } return cmd->cb(cmd, cmd->ctx); - } return 0; -} +} /* callback to be called if [virtual] UART has some data for us */ static int atcmd_select_cb(int fd, unsigned int what, void *data) { - int len; + int len, rc; static char rxbuf[1024]; struct gsmd *g = data; if (what & GSMD_FD_READ) { + memset(rxbuf, 0, sizeof(rxbuf)); while ((len = read(fd, rxbuf, sizeof(rxbuf)))) { - int rc; - if (len < 0) { + if (errno == EAGAIN) + return 0; DEBUGP("ERROR reading from fd %u: %d (%s)\n", fd, len, strerror(errno)); return len; @@ -257,7 +276,8 @@ static int atcmd_select_cb(int fd, unsigned int what, void *data) if (what & GSMD_FD_WRITE) { struct gsmd_atcmd *pos, *pos2; llist_for_each_entry_safe(pos, pos2, &g->pending_atcmds, list) { - int rc = write(fd, pos->buf, strlen(pos->buf)); + len = strlen(pos->buf); + rc = write(fd, pos->buf, strlen(pos->buf)); if (rc == 0) { DEBUGP("write returns 0, aborting\n"); break; @@ -270,13 +290,24 @@ static int atcmd_select_cb(int fd, unsigned int what, void *data) fprintf(stderr, "short write!!! FIXME!\n"); exit(3); } + 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); + + /* we only send one cmd at the moment */ + g->gfd_uart.when &= ~GSMD_FD_WRITE; + break; } } +#if 0 + if (llist_empty(&g->pending_atcmds)) + g->gfd_uart.when &= ~GSMD_FD_WRITE; +#endif + + return 0; } @@ -314,6 +345,18 @@ int atcmd_submit(struct gsmd *g, struct gsmd_atcmd *cmd) return 0; } +void atcmd_drain(int fd) +{ + int rc; + struct termios t; + rc = tcflush(fd, TCIOFLUSH); + rc = tcgetattr(fd, &t); + printf("c_iflag = 0x%08x, c_oflag = 0x%08x, c_cflag = 0x%08x, c_lflag = 0x%08x\n", + t.c_iflag, t.c_oflag, t.c_cflag, t.c_lflag); + t.c_iflag = t.c_oflag = 0; + rc = tcsetattr(fd, TCSANOW, &t); +} + /* init atcmd parser */ int atcmd_init(struct gsmd *g, int sockfd) { @@ -322,7 +365,13 @@ int atcmd_init(struct gsmd *g, int sockfd) g->gfd_uart.data = g; g->gfd_uart.cb = &atcmd_select_cb; + INIT_LLIST_HEAD(&g->pending_atcmds); + INIT_LLIST_HEAD(&g->busy_atcmds); + + llparse_init (&g->llp); + g->llp.cur = g->llp.buf; + g->llp.len = sizeof(g->llp.buf); g->llp.cb = &ml_parse; g->llp.ctx = g; g->llp.flags = LGSM_ATCMD_F_EXTENDED; diff --git a/src/gsmd/atcmd.h b/src/gsmd/atcmd.h index f6b9d1d..ded3f00 100644 --- a/src/gsmd/atcmd.h +++ b/src/gsmd/atcmd.h @@ -8,5 +8,6 @@ typedef int atcmd_cb_t(struct gsmd_atcmd *cmd, void *ctx); struct gsmd_atcmd *atcmd_fill(const char *cmd, int rlen, atcmd_cb_t *cb, void *ctx); int atcmd_submit(struct gsmd *g, struct gsmd_atcmd *cmd); int atcmd_init(struct gsmd *g, int sockfd); +void atcmd_drain(int fd); #endif diff --git a/src/gsmd/gsmd.c b/src/gsmd/gsmd.c index b77e54e..b617eb1 100644 --- a/src/gsmd/gsmd.c +++ b/src/gsmd/gsmd.c @@ -22,7 +22,7 @@ static int gsmd_test_atcb(struct gsmd_atcmd *cmd, void *ctx) { - printf("returned: `%s'\n", cmd->buf); + printf("`%s' returned `%s'\n", cmd->buf, cmd->resp); free(cmd); return 0; } @@ -34,10 +34,25 @@ static int gsmd_test(struct gsmd *gsmd) return atcmd_submit(gsmd, cmd); } +static int atcmd_test(struct gsmd *gsmd) +{ + struct gsmd_atcmd *cmd; + cmd = atcmd_fill("ATE0", 255, &gsmd_test_atcb, NULL); + return atcmd_submit(gsmd, cmd); +} + static int gsmd_initsettings(struct gsmd *gsmd) { + int rc; struct gsmd_atcmd *cmd; - //cmd = atcmd_fill("ATV1;+CRC=1;+CREG=2;+CLIP=1;+COLP=1", 255, &f + + cmd = atcmd_fill("ATV1", 255, &gsmd_test_atcb, NULL); + rc = atcmd_submit(gsmd, cmd); + if (rc < 0) + return rc; + + cmd = atcmd_fill("+CRC=1;+CREG=2;+CMEE=2;+CLIP=1;+COLP=1", 255, &gsmd_test_atcb, NULL); + return atcmd_submit(gsmd, cmd); } struct bdrt { @@ -85,6 +100,13 @@ static int set_baudrate(int fd, int baudrate) static struct gsmd g; +static int gsmd_initialize(struct gsmd *g) +{ + INIT_LLIST_HEAD(&g->users); + + return 0; +} + static struct option opts[] = { { "version", 0, NULL, 'V' }, { "daemon", 0, NULL, 'd' }, @@ -93,6 +115,19 @@ static struct option opts[] = { { "speed", 1, NULL, 's' }, }; +static void print_help(void) +{ + printf("gsmd - (C) 2006 by Harald Welte <laforge@gnumonks.org>\n" + "This program is FREE SOFTWARE under the terms of GNU GPL\n\n" + "Usage:\n" + "\t-v\t--version\tDisplay program version\n" + "\t-d\t--daemon\tDeamonize\n" + "\t-h\t--help\t\tDisplay this help message\n" + "\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" + ); +} + int main(int argc, char **argv) { int fd, argch; @@ -102,7 +137,7 @@ int main(int argc, char **argv) char *device = "/dev/ttyUSB0"; /*FIXME: parse commandline, set daemonize, device, ... */ - while ((argch = getopt_long(argc, argv, "Vdhps:", opts, NULL)) != -1) { + while ((argch = getopt_long(argc, argv, "Vdhp:s:", opts, NULL)) != -1) { switch (argch) { case 'V': /* FIXME */ @@ -112,6 +147,8 @@ int main(int argc, char **argv) break; case 'h': /* FIXME */ + print_help(); + exit(0); break; case 'p': device = optarg; @@ -135,10 +172,16 @@ int main(int argc, char **argv) exit(1); } + if (gsmd_initialize(&g) < 0) { + fprintf(stderr, "internal error\n"); + exit(1); + } + if (atcmd_init(&g, fd) < 0) { fprintf(stderr, "can't initialize UART device\n"); exit(1); } + atcmd_drain(fd); if (usock_init(&g) < 0) { fprintf(stderr, "can't open unix socket\n"); @@ -155,7 +198,9 @@ int main(int argc, char **argv) setsid(); } + atcmd_test(&g); gsmd_test(&g); + gsmd_initsettings(&g); while (1) { int ret = gsmd_select_main(); diff --git a/src/gsmd/gsmd.h b/src/gsmd/gsmd.h index ff05a27..7a94ef7 100644 --- a/src/gsmd/gsmd.h +++ b/src/gsmd/gsmd.h @@ -18,6 +18,7 @@ struct gsmd_atcmd { u_int8_t flags; int32_t ret; u_int32_t buflen; + char *resp; char buf[]; }; diff --git a/src/gsmd/unsolicited.c b/src/gsmd/unsolicited.c index fdcdac7..2c7fddf 100644 --- a/src/gsmd/unsolicited.c +++ b/src/gsmd/unsolicited.c @@ -7,6 +7,7 @@ #include <gsmd/usock.h> #include <gsmd/event.h> +#include <gsmd/ts0707.h> #include "gsmd.h" #include "usock.h" @@ -270,3 +271,121 @@ int unsolicited_parse(struct gsmd *g, const char *buf, int len, const char *para return -EINVAL; } +static unsigned int errors_creating_events[] = { + GSM0707_CME_PHONE_FAILURE, + GSM0707_CME_PHONE_NOCONNECT, + GSM0707_CME_PHONE_ADAPT_RESERVED, + GSM0707_CME_PH_SIM_PIN_REQUIRED, + GSM0707_CME_PH_FSIM_PIN_REQUIRED, + GSM0707_CME_PH_FSIM_PUK_REQUIRED, + GSM0707_CME_SIM_NOT_INSERTED, + GSM0707_CME_SIM_PIN_REQUIRED, + GSM0707_CME_SIM_PUK_REQUIRED, + GSM0707_CME_SIM_FAILURE, + GSM0707_CME_SIM_BUSY, + GSM0707_CME_SIM_WRONG, + GSM0707_CME_SIM_PIN2_REQUIRED, + GSM0707_CME_SIM_PUK2_REQUIRED, + GSM0707_CME_MEMORY_FULL, + GSM0707_CME_MEMORY_FAILURE, + GSM0707_CME_NETPERS_PIN_REQUIRED, + GSM0707_CME_NETPERS_PUK_REQUIRED, + GSM0707_CME_NETSUBSET_PIN_REQUIRED, + GSM0707_CME_NETSUBSET_PUK_REQUIRED, + GSM0707_CME_PROVIDER_PIN_REQUIRED, + GSM0707_CME_PROVIDER_PUK_REQUIRED, + GSM0707_CME_CORPORATE_PIN_REQUIRED, + GSM0707_CME_CORPORATE_PUK_REQUIRED, +}; + +static int is_in_array(unsigned int val, unsigned int *arr, unsigned int arr_len) +{ + unsigned int i; + + for (i = 0; i < arr_len; i++) { + if (arr[i] == val) + return 1; + } + + return 0; +} + + +int generate_event_from_cme(struct gsmd *g, unsigned int cme_error) +{ + struct gsmd_ucmd *gu; + struct gsmd_evt_auxdata *eaux; + if (!is_in_array(cme_error, errors_creating_events, + ARRAY_SIZE(errors_creating_events))) + return 0; + + gu = build_event(GSMD_MSG_EVENT, GSMD_EVT_PIN, sizeof(*eaux)); + if (!gu) + return -1; + eaux = ((void *)gu) + sizeof(*gu); + + switch (cme_error) { + case GSM0707_CME_PH_SIM_PIN_REQUIRED: + eaux->u.pin.type = GSMD_PIN_PH_SIM_PIN; + break; + case GSM0707_CME_PH_FSIM_PIN_REQUIRED: + eaux->u.pin.type = GSMD_PIN_PH_FSIM_PIN; + break; + case GSM0707_CME_PH_FSIM_PUK_REQUIRED: + eaux->u.pin.type = GSMD_PIN_PH_FSIM_PUK; + break; + case GSM0707_CME_SIM_PIN_REQUIRED: + eaux->u.pin.type = GSMD_PIN_SIM_PIN; + break; + case GSM0707_CME_SIM_PUK_REQUIRED: + eaux->u.pin.type = GSMD_PIN_SIM_PUK; + break; + case GSM0707_CME_SIM_PIN2_REQUIRED: + eaux->u.pin.type = GSMD_PIN_SIM_PIN2; + break; + case GSM0707_CME_SIM_PUK2_REQUIRED: + eaux->u.pin.type = GSMD_PIN_SIM_PUK2; + break; + case GSM0707_CME_NETPERS_PIN_REQUIRED: + eaux->u.pin.type = GSMD_PIN_PH_NET_PIN; + break; + case GSM0707_CME_NETPERS_PUK_REQUIRED: + eaux->u.pin.type = GSMD_PIN_PH_NET_PUK; + break; + case GSM0707_CME_NETSUBSET_PIN_REQUIRED: + eaux->u.pin.type = GSMD_PIN_PH_NETSUB_PIN; + break; + case GSM0707_CME_NETSUBSET_PUK_REQUIRED: + eaux->u.pin.type = GSMD_PIN_PH_NETSUB_PUK; + break; + case GSM0707_CME_PROVIDER_PIN_REQUIRED: + eaux->u.pin.type = GSMD_PIN_PH_SP_PIN; + break; + case GSM0707_CME_PROVIDER_PUK_REQUIRED: + eaux->u.pin.type = GSMD_PIN_PH_SP_PUK; + break; + case GSM0707_CME_CORPORATE_PIN_REQUIRED: + eaux->u.pin.type = GSMD_PIN_PH_CORP_PIN; + break; + case GSM0707_CME_CORPORATE_PUK_REQUIRED: + eaux->u.pin.type = GSMD_PIN_PH_CORP_PUK; + break; + + case GSM0707_CME_SIM_FAILURE: + case GSM0707_CME_SIM_BUSY: + case GSM0707_CME_SIM_WRONG: + case GSM0707_CME_MEMORY_FULL: + case GSM0707_CME_MEMORY_FAILURE: + case GSM0707_CME_PHONE_FAILURE: + case GSM0707_CME_PHONE_NOCONNECT: + case GSM0707_CME_PHONE_ADAPT_RESERVED: + case GSM0707_CME_SIM_NOT_INSERTED: + /* FIXME */ + return 0; + break; + default: + return 0; + break; + } + return usock_evt_send(g, gu, GSMD_EVT_PIN); +} diff --git a/src/gsmd/unsolicited.h b/src/gsmd/unsolicited.h index 4cc5bb5..fb99e1b 100644 --- a/src/gsmd/unsolicited.h +++ b/src/gsmd/unsolicited.h @@ -4,5 +4,6 @@ #include "gsmd.h" int unsolicited_parse(struct gsmd *g, const char *buf, int len, const char *param); +int generate_event_from_cme(struct gsmd *g, unsigned int cme_error); #endif diff --git a/src/gsmd/usock.c b/src/gsmd/usock.c index b00c031..7c90c5d 100644 --- a/src/gsmd/usock.c +++ b/src/gsmd/usock.c @@ -57,6 +57,15 @@ static int usock_rcv_pcmd(struct gsmd_user *gu, char *buf, int len) return atcmd_submit(gu->gsmd, cmd); } break; + case GSMD_PCMD_EVT_SUBSCRIPTIONS: + { + u_int32_t *evtmask = (u_int32_t *) (buf + sizeof(*gph)); + if (len < sizeof(*gph) + sizeof(u_int32_t)) + return -EINVAL; + + gu->subscriptions = *evtmask; + } + break; default: return -EINVAL; } @@ -76,7 +85,18 @@ static int gsmd_usock_user_cb(int fd, unsigned int what, void *data) int rcvlen; /* read data from socket, determine what he wants */ rcvlen = read(fd, buf, sizeof(buf)); - return usock_rcv_pcmd(gu, buf, rcvlen); + if (rcvlen == 0) { + /* EOF, this client has just vanished */ + gsmd_unregister_fd(&gu->gfd); + close(fd); + /* destroy whole user structure */ + llist_del(&gu->list); + /* FIXME: delete budy ucmds from finished_ucmds */ + return 0; + } else if (rcvlen < 0) + return rcvlen; + else + return usock_rcv_pcmd(gu, buf, rcvlen); } if (what & GSMD_FD_WRITE) { @@ -133,6 +153,7 @@ static int gsmd_usock_cb(int fd, unsigned int what, void *data) newuser->gsmd = g; llist_add(&newuser->list, &g->users); + gsmd_register_fd(&newuser->gfd); } return 0; @@ -148,6 +169,7 @@ int usock_init(struct gsmd *g) if (fd < 0) return fd; + memset(&sun, 0, sizeof(sun)); sun.sun_family = AF_UNIX; memcpy(sun.sun_path, GSMD_UNIX_SOCKET, sizeof(GSMD_UNIX_SOCKET)); @@ -157,6 +179,12 @@ int usock_init(struct gsmd *g) return rc; } + rc = listen(fd, 10); + if (rc < 0) { + close(fd); + return rc; + } + g->gfd_sock.fd = fd; g->gfd_sock.when = GSMD_FD_READ | GSMD_FD_EXCEPT; g->gfd_sock.data = g; |