summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/Makefile.am1
-rw-r--r--src/gsmd/Makefile377
-rw-r--r--src/gsmd/atcmd.c65
-rw-r--r--src/gsmd/atcmd.h1
-rw-r--r--src/gsmd/gsmd.c51
-rw-r--r--src/gsmd/gsmd.h1
-rw-r--r--src/gsmd/unsolicited.c119
-rw-r--r--src/gsmd/unsolicited.h1
-rw-r--r--src/gsmd/usock.c30
-rw-r--r--src/libgsmd/Makefile.am9
-rw-r--r--src/libgsmd/libgsmd.c5
-rw-r--r--src/libgsmd/libgsmd_voicecall.c2
-rw-r--r--src/util/Makefile.am9
-rw-r--r--src/util/libgsmd-tool.c64
14 files changed, 712 insertions, 23 deletions
diff --git a/src/Makefile.am b/src/Makefile.am
new file mode 100644
index 0000000..f6641bc
--- /dev/null
+++ b/src/Makefile.am
@@ -0,0 +1 @@
+SUBDIRS = gsmd libgsmd util
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;
diff --git a/src/libgsmd/Makefile.am b/src/libgsmd/Makefile.am
new file mode 100644
index 0000000..2e8988f
--- /dev/null
+++ b/src/libgsmd/Makefile.am
@@ -0,0 +1,9 @@
+LIBVERSION= 0:0:0
+INCLUDES = $(all_includes) -I$(top_srcdir)/include
+AM_CFLAGS = -std=gnu99
+
+lib_LTLIBRARIES = libgsmd.la
+
+libgsmd_la_LDFLAGS = -Wc,-nostartfiles -version-info $(LIBVERSION)
+libgsmd_la_SOURCES = libgsmd.c libgsmd_input.c libgsmd_voicecall.c
+
diff --git a/src/libgsmd/libgsmd.c b/src/libgsmd/libgsmd.c
index 7eb2701..77b8499 100644
--- a/src/libgsmd/libgsmd.c
+++ b/src/libgsmd/libgsmd.c
@@ -9,6 +9,7 @@
#include <sys/socket.h>
#include <sys/un.h>
+#include <gsmd/usock.h>
#include <libgsmd/libgsmd.h>
#include "lgsm_internals.h"
@@ -40,7 +41,7 @@ static int lgsm_open_backend(struct lgsm_handle *lh, const char *device)
{
int rc;
- if (!strcmp(device, "gsmd")) {
+ if (!strcmp(device, LGSMD_DEVICE_GSMD)) {
struct sockaddr_un sun;
/* use unix domain socket to gsm daemon */
@@ -48,8 +49,10 @@ static int lgsm_open_backend(struct lgsm_handle *lh, const char *device)
if (lh->fd < 0)
return lh->fd;
+ memset(&sun, 0, sizeof(sun));
sun.sun_family = AF_UNIX;
memcpy(sun.sun_path, GSMD_UNIX_SOCKET, sizeof(GSMD_UNIX_SOCKET));
+ printf("sizeof(GSMD_UNIX_SOCKET) = %u\n", sizeof(GSMD_UNIX_SOCKET));
rc = connect(lh->fd, (struct sockaddr *)&sun, sizeof(sun));
if (rc < 0) {
diff --git a/src/libgsmd/libgsmd_voicecall.c b/src/libgsmd/libgsmd_voicecall.c
index f59bdff..25c565d 100644
--- a/src/libgsmd/libgsmd_voicecall.c
+++ b/src/libgsmd/libgsmd_voicecall.c
@@ -2,7 +2,7 @@
#include <libgsmd/voicecall.h>
-#include "libgsmd/internals.h"
+#include "lgsm_internals.h"
int lgsm_voice_out_init(struct lgsm_handle *lh,
diff --git a/src/util/Makefile.am b/src/util/Makefile.am
new file mode 100644
index 0000000..bb257f5
--- /dev/null
+++ b/src/util/Makefile.am
@@ -0,0 +1,9 @@
+INCLUDES = $(all_includes) -I$(top_srcdir)/include
+AM_CFLAGS = -std=gnu99
+
+bin_PROGRAMS = libgsmd-tool
+
+libgsmd_tool_SOURCES = libgsmd-tool.c
+libgsmd_tool_LDADD = ../libgsmd/libgsmd.la
+libgsmd_tool_LDFLAGS = -dynamic
+
diff --git a/src/util/libgsmd-tool.c b/src/util/libgsmd-tool.c
new file mode 100644
index 0000000..a3da490
--- /dev/null
+++ b/src/util/libgsmd-tool.c
@@ -0,0 +1,64 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+
+#define _GNU_SOURCE
+#include <getopt.h>
+
+#include <libgsmd/libgsmd.h>
+
+static struct lgsm_handle *lgsmh;
+static int verbose = 0;
+
+static struct option opts[] = {
+ { "help", 0, 0, 'h' },
+ { "version", 0, 0, 'V' },
+ { "verbose", 0, 0, 'v' },
+ { 0, 0, 0, 0 }
+};
+
+static void help(void)
+{
+ printf("Usage:\n"
+ "\t-h\t--help\tPrint this Help message\n"
+ "\t-V\t--version\tPrint version number\n"
+ "\t-v\t--verbose\tBe more verbose\n");
+}
+
+int main(int argc, char **argv)
+{
+ int rc, i;
+
+ printf("libgsm-tool - (C) 2006 by Harald Welte\n"
+ "This program is Free Software and has ABSOLUTELY NO WARRANTY\n\n");
+
+ while (1) {
+ int c, option_index = 0;
+ c = getopt_long(argc, argv, "hVv", opts, &option_index);
+ if (c == -1)
+ break;
+
+ switch (c) {
+ case 'v':
+ verbose = 1;
+ break;
+ case 'V':
+ /* FIXME */
+ break;
+ case 'h':
+ help();
+ exit(0);
+ break;
+ }
+ }
+
+ lgsmh = lgsm_init(LGSMD_DEVICE_GSMD);
+ if (!lgsmh) {
+ fprintf(stderr, "Can't connect to gsmd\n");
+ exit(1);
+ }
+
+
+ exit(0);
+}
personal git repositories of Harald Welte. Your mileage may vary