libgsmd: update gsmd patches
authorPhilipp Zabel <philipp.zabel@gmail.com>
Tue, 31 Jul 2007 09:56:27 +0000 (09:56 +0000)
committerPhilipp Zabel <philipp.zabel@gmail.com>
Tue, 31 Jul 2007 09:56:27 +0000 (09:56 +0000)
- alive-start-if-interpreter-ready.patch and
  vendor-qc-v0.patch went upstream
- add mlbuf-static-bss.patch and
  Andrzej Zaborowski's sms-hacks.patch and libgsmd-tool-fix.patch

packages/gsm/files/alive-start-if-interpreter-ready.patch [deleted file]
packages/gsm/files/libgsmd-tool-fix.patch [new file with mode: 0644]
packages/gsm/files/mlbuf-static-bss.patch [new file with mode: 0644]
packages/gsm/files/sms-hacks.patch [new file with mode: 0644]
packages/gsm/files/vendor-qc-v0.patch [deleted file]
packages/gsm/libgsmd_svn.bb

diff --git a/packages/gsm/files/alive-start-if-interpreter-ready.patch b/packages/gsm/files/alive-start-if-interpreter-ready.patch
deleted file mode 100644 (file)
index 20104d2..0000000
+++ /dev/null
@@ -1,39 +0,0 @@
-Index: gsm/src/gsmd/atcmd.c
-===================================================================
---- gsm.orig/src/gsmd/atcmd.c  2007-06-03 13:24:44.000000000 +0200
-+++ gsm/src/gsmd/atcmd.c       2007-06-03 13:24:46.000000000 +0200
-@@ -185,6 +185,7 @@
-           !strcmp(buf, "AT-Command Interpreter ready")) {
-               g->interpreter_ready = 1;
-               gsmd_initsettings(g);
-+              gmsd_alive_start(g);
-               return 0;
-       }
-Index: gsm/src/gsmd/gsmd.c
-===================================================================
---- gsm.orig/src/gsmd/gsmd.c   2007-06-03 13:22:02.000000000 +0200
-+++ gsm/src/gsmd/gsmd.c        2007-06-03 13:22:56.000000000 +0200
-@@ -128,7 +128,7 @@
-       gsmd_timer_register(tmr);
- }
--static int gmsd_alive_start(struct gsmd *gsmd)
-+int gmsd_alive_start(struct gsmd *gsmd)
- {
-       struct timeval tv;
-@@ -478,10 +478,11 @@
-       /* select a vendor plugin */
-       gsmd_vendor_plugin_find(&g);
--      if (g.interpreter_ready)
-+      if (g.interpreter_ready) {
-               gsmd_initsettings(&g);
-       
--      gmsd_alive_start(&g);
-+              gmsd_alive_start(&g);
-+      }
-       gsmd_opname_init(&g);
diff --git a/packages/gsm/files/libgsmd-tool-fix.patch b/packages/gsm/files/libgsmd-tool-fix.patch
new file mode 100644 (file)
index 0000000..8938f5a
--- /dev/null
@@ -0,0 +1,19 @@
+Index: gsm/src/util/atcmd.c
+===================================================================
+--- gsm.orig/src/util/atcmd.c  2007-07-31 11:44:32.000000000 +0200
++++ gsm/src/util/atcmd.c       2007-07-31 11:46:44.000000000 +0200
+@@ -91,9 +91,11 @@
+                               continue;
+                       }
+                       printf("STR=`%s'\n", buf);
++
++                      /* this is a synchronous call for a passthrough
++                       * command */
++                      lgsm_passthrough(lgsmh, buf, rbuf, &rlen);
++                      printf("RSTR=`%s'\n", rbuf);
+               }
+-              /* this is a synchronous call for a passthrough command */
+-              lgsm_passthrough(lgsmh, buf, rbuf, &rlen);
+-              printf("RSTR=`%s'\n", rbuf);
+       }
+ }
diff --git a/packages/gsm/files/mlbuf-static-bss.patch b/packages/gsm/files/mlbuf-static-bss.patch
new file mode 100644 (file)
index 0000000..65b3449
--- /dev/null
@@ -0,0 +1,21 @@
+Index: gsm/src/gsmd/atcmd.c
+===================================================================
+--- gsm.orig/src/gsmd/atcmd.c  2007-07-31 11:44:51.000000000 +0200
++++ gsm/src/gsmd/atcmd.c       2007-07-31 11:45:09.000000000 +0200
+@@ -171,13 +171,14 @@
+       return -1;
+ }
++static char mlbuf[MLPARSE_BUF_SIZE];
++static int mlbuf_len;
++
+ static int ml_parse(const char *buf, int len, void *ctx)
+ {
+       struct gsmd *g = ctx;
+       struct gsmd_atcmd *cmd = NULL;
+-      static char mlbuf[MLPARSE_BUF_SIZE];
+       int rc = 0, final = 0;
+-      int mlbuf_len;
+       DEBUGP("buf=`%s'(%d)\n", buf, len);
diff --git a/packages/gsm/files/sms-hacks.patch b/packages/gsm/files/sms-hacks.patch
new file mode 100644 (file)
index 0000000..e94386a
--- /dev/null
@@ -0,0 +1,821 @@
+From 3e5832569d3b29a90b29b5d5ac0ffad4765bcff3 Mon Sep 17 00:00:00 2001
+From: Andrzej Zaborowski <balrog@zabor.org>
+Date: Fri, 6 Jul 2007 06:55:12 +0200
+Subject: [PATCH] SMS hacks 2
+
+---
+ include/gsmd/gsmd.h         |    8 ++-
+ include/gsmd/usock.h        |   35 ++++++++-
+ include/gsmd/vendorplugin.h |    2 +-
+ include/libgsmd/sms.h       |    2 +-
+ src/gsmd/atcmd.c            |  130 +++++++++++++++++++-------------
+ src/gsmd/sms_cb.c           |   19 ++++-
+ src/gsmd/usock.c            |  175 +++++++++++++++++++++++++++++++++++++-----
+ src/gsmd/vendor_ti.c        |    2 +-
+ src/libgsmd/libgsmd_sms.c   |   26 +++++--
+ 11 files changed, 320 insertions(+), 91 deletions(-)
+
+Index: gsm/include/gsmd/gsmd.h
+===================================================================
+--- gsm.orig/include/gsmd/gsmd.h       2007-07-31 11:44:32.000000000 +0200
++++ gsm/include/gsmd/gsmd.h    2007-07-31 11:46:44.000000000 +0200
+@@ -27,6 +27,7 @@
+       u_int32_t buflen;
+       u_int16_t id;
+       u_int8_t flags;
++      char *cur;
+       char buf[];
+ };
+@@ -36,6 +37,8 @@
+       LLPARSE_STATE_IDLE_LF,          /* LF before response (V1) */
+       LLPARSE_STATE_RESULT,           /* within result payload */
+       LLPARSE_STATE_RESULT_CR,        /* CR after result */
++      LLPARSE_STATE_PROMPT,           /* within a "> " prompt */
++      LLPARSE_STATE_PROMPT_SPC,       /* a complete "> " prompt */
+       LLPARSE_STATE_ERROR,            /* something went wrong */
+                                       /* ... idle again */
+ };
+@@ -52,6 +55,7 @@
+       unsigned int flags;
+       void *ctx;
+       int (*cb)(const char *buf, int len, void *ctx);
++      int (*prompt_cb)(void *ctx);
+       char *cur;
+       char buf[LLPARSE_BUF_SIZE];
+ };
+@@ -59,6 +63,7 @@
+ struct gsmd;
+ #define GSMD_FLAG_V0          0x0001  /* V0 responses to be expected from TA */
++#define GSMD_FLAG_SMS_FMT     0x0002  /* Use TEXT rather than PDU mode */
+ struct gsmd {
+       unsigned int flags;
+@@ -92,7 +97,8 @@
+ extern int gsmdlog_init(const char *path);
+ /* write a message to the daemons' logfile */
+-void __gsmd_log(int level, const char *file, int line, const char *function, const char *message, ...);
++void __gsmd_log(int level, const char *file, int line, const char *function, const char *message, ...)
++      __attribute__ ((__format__ (__printf__, 5, 6)));
+ /* macro for logging including filename and line number */
+ #define gsmd_log(level, format, args ...) \
+       __gsmd_log(level, __FILE__, __LINE__, __FUNCTION__, format, ## args)
+Index: gsm/include/gsmd/usock.h
+===================================================================
+--- gsm.orig/include/gsmd/usock.h      2007-07-31 11:44:32.000000000 +0200
++++ gsm/include/gsmd/usock.h   2007-07-31 11:46:44.000000000 +0200
+@@ -139,7 +139,7 @@
+ /* for SMS-SUBMIT, SMS-DELIVER */
+ enum gsmd_sms_tp_udhi {
+       GSMD_SMS_TP_UDHI_NO_HEADER      = (0<<6),
+-      GSMD_SMS_TP_UDHI_WTIH_HEADER    = (1<<6),
++      GSMD_SMS_TP_UDHI_WITH_HEADER    = (1<<6),
+ };
+ /* SMS delflg from 3GPP TS 07.05, Clause 3.5.4 */
+@@ -160,6 +160,34 @@
+       GSMD_PHONEBOOK_GET_SUPPORT      = 6,
+ };
++/* Type-of-Address, Numbering Plan Identification field */
++enum gsmd_toa_npi {
++      GSMD_TOA_NPI_UNKNOWN            = 0x0,
++      GSMD_TOA_NPI_ISDN               = 0x1,
++      GSMD_TOA_NPI_DATA               = 0x3,
++      GSMD_TOA_NPI_TELEX              = 0x4,
++      GSMD_TOA_NPI_NATIONAL           = 0x8,
++      GSMD_TOA_NPI_PRIVATE            = 0x9,
++      GSMD_TOA_NPI_ERMES              = 0xa,
++      GSMD_TOA_NPI_RESERVED           = 0xf,
++};
++
++/* Type-of-Address, Type-of-Number field */
++enum gsmd_toa_ton {
++      GSMD_TOA_TON_UNKNOWN            = (0<<4),
++      GSMD_TOA_TON_INTERNATIONAL      = (1<<4),
++      GSMD_TOA_TON_NATIONAL           = (2<<4),
++      GSMD_TOA_TON_NETWORK            = (3<<4),
++      GSMD_TOA_TON_SUBSCRIBER         = (4<<4),
++      GSMD_TOA_TON_ALPHANUMERIC       = (5<<4),
++      GSMD_TOA_TON_ABBREVIATED        = (6<<4),
++};
++
++/* Type-of-Address, bit 7 always 1 */
++enum gsmd_toa_reserved {
++      GSMD_TOA_RESERVED               = (1<<7),
++};
++
+ /* Length from 3GPP TS 04.08, Clause 10.5.4.7 */
+ #define GSMD_ADDR_MAXLEN      32
+@@ -269,6 +297,11 @@
+       char user_data[140];
+ } __attribute__ ((packed));
++struct gsmd_sms_send {
++      struct gsmd_addr addr;
++      struct gsmd_sms payload;
++};
++
+ /* Refer to GSM 07.07 subclause 8.12 */
+ struct gsmd_phonebook_readrg {
+       u_int8_t index1;
+Index: gsm/include/gsmd/vendorplugin.h
+===================================================================
+--- gsm.orig/include/gsmd/vendorplugin.h       2007-07-31 11:46:28.000000000 +0200
++++ gsm/include/gsmd/vendorplugin.h    2007-07-31 11:46:44.000000000 +0200
+@@ -12,7 +12,7 @@
+ struct gsmd_vendor_plugin {
+       struct llist_head list;
+       unsigned char *name;
+-      unsigned char *ext_chars;
++      char *ext_chars;
+       unsigned int num_unsolicit;
+       const struct gsmd_unsolicit *unsolicit;
+       int (*detect)(struct gsmd *g);
+Index: gsm/include/libgsmd/sms.h
+===================================================================
+--- gsm.orig/include/libgsmd/sms.h     2007-07-31 11:44:32.000000000 +0200
++++ gsm/include/libgsmd/sms.h  2007-07-31 11:46:44.000000000 +0200
+@@ -83,7 +83,7 @@
+ extern int lgsmd_sms_send(struct lgsm_handle *lh, const struct lgsm_sms *sms);
+ /* Write Message to Memory */
+-extern int lgsmd_sms_write(struct lgsm_handle *lh, 
++extern int lgsmd_sms_write(struct lgsm_handle *lh,
+               const struct lgsm_sms_write *sms_write);
+ /* Packing of 7-bit characters, refer to GSM 03.38 subclause 6.1.2.1.1 */
+Index: gsm/src/gsmd/atcmd.c
+===================================================================
+--- gsm.orig/src/gsmd/atcmd.c  2007-07-31 11:46:42.000000000 +0200
++++ gsm/src/gsmd/atcmd.c       2007-07-31 11:47:03.000000000 +0200
+@@ -82,9 +82,12 @@
+       switch (llp->state) {
+       case LLPARSE_STATE_IDLE:
++      case LLPARSE_STATE_PROMPT_SPC:
+               if (llp->flags & LGSM_ATCMD_F_EXTENDED) {
+                       if (byte == '\r')
+                               llp->state = LLPARSE_STATE_IDLE_CR;
++                      else if (byte == '>')
++                              llp->state = LLPARSE_STATE_PROMPT;
+                       else {
+ #ifdef STRICT
+                               llp->state = LLPARSE_STATE_ERROR;
+@@ -108,6 +111,8 @@
+               /* can we really go directly into result_cr ? */
+               if (byte == '\r')
+                       llp->state = LLPARSE_STATE_RESULT_CR;
++              else if (byte == '>')
++                      llp->state = LLPARSE_STATE_PROMPT;
+               else {
+                       llp->state = LLPARSE_STATE_RESULT;
+                       ret = llparse_append(llp, byte);
+@@ -127,6 +132,16 @@
+                       memset(llp->buf, 0, LLPARSE_BUF_SIZE);
+               }
+               break;
++      case LLPARSE_STATE_PROMPT:
++              if (byte == ' ')
++                      llp->state = LLPARSE_STATE_PROMPT_SPC;
++              else {
++                      /* this was not a real "> " prompt */
++                      llparse_append(llp, '>');
++                      ret = llparse_append(llp, byte);
++                      llp->state = LLPARSE_STATE_RESULT;
++              }
++              break;
+       case LLPARSE_STATE_ERROR:
+               break;
+       }
+@@ -147,6 +162,10 @@
+                       /* FIXME: what to do with return value ? */
+                       llp->cb(llp->buf, llp->cur - llp->buf, llp->ctx);
+               }
++
++              /* if a full SMS-style prompt was received, poke the select */
++              if (llp->state == LLPARSE_STATE_PROMPT_SPC)
++                      llp->prompt_cb(llp->ctx);
+       }
+       return 0;
+@@ -178,7 +197,7 @@
+ {
+       struct gsmd *g = ctx;
+       struct gsmd_atcmd *cmd = NULL;
+-      int rc = 0, final = 0;
++      int rc = 0;
+       DEBUGP("buf=`%s'(%d)\n", buf, len);
+@@ -232,7 +251,6 @@
+                       DEBUGP("error number %lu\n", err_nr);
+                       if (cmd)
+                               cmd->ret = err_nr;
+-                      final = 1;
+                       goto final_cb;
+               }
+               if (!strncmp(buf+1, "CMS ERROR", 9)) {
+@@ -242,7 +260,6 @@
+                       DEBUGP("error number %lu\n", err_nr);
+                       if (cmd)
+                               cmd->ret = err_nr;
+-                      final = 1;
+                       goto final_cb;
+               }
+@@ -274,7 +291,7 @@
+                       /* it might be a multiline response, so if there's a previous
+                          response, send out mlbuf and start afresh with an empty buffer */
+-                      if (mlbuf[0] != 0) {
++                      if (mlbuf_len) {
+                               if (!cmd->cb) {
+                                       gsmd_log(GSMD_NOTICE, "command without cb!!!\n");
+                               } else {
+@@ -282,8 +299,8 @@
+                                       cmd->resp = mlbuf;
+                                       rc = cmd->cb(cmd, cmd->ctx, cmd->resp);
+                                       DEBUGP("Clearing mlbuf\n");
+-                                      mlbuf[0] = 0;
+                               }
++                              mlbuf_len = 0;
+                       }
+                       /* the current buf will be appended to mlbuf below */
+@@ -302,7 +319,6 @@
+                       DEBUGP("unspecified error\n");
+                       if (cmd)
+                               cmd->ret = 4;
+-                      final = 1;
+                       goto final_cb;
+               }
+@@ -311,7 +327,6 @@
+                       /* Part of Case 'C' */
+                       if (cmd)
+                               cmd->ret = 0;
+-                      final = 1;
+                       goto final_cb;
+               }
+@@ -320,14 +335,12 @@
+               if (!strncmp(buf, "NO CARRIER", 11) ||
+                   ((g->flags & GSMD_FLAG_V0) && buf[0] == '3')) {
+                       /* Part of Case 'D' */
+-                      final = 1;
+                       goto final_cb;
+               }
+               if (!strncmp(buf, "BUSY", 4) ||
+                   ((g->flags & GSMD_FLAG_V0) && buf[0] == '7')) {
+                       /* Part of Case 'D' */
+-                      final = 1;
+                       goto final_cb;
+               }
+       }
+@@ -335,21 +348,13 @@
+       /* we reach here, if we are at an information response that needs to be
+        * passed on */
+-      if (mlbuf[0] == 0) {
+-              DEBUGP("Filling mlbuf\n");
+-              strncat(mlbuf, buf, sizeof(mlbuf)-1);
+-      } else {
+-              DEBUGP("Appending buf to mlbuf\n");
+-              mlbuf_len = strlen(mlbuf);
+-              if (mlbuf_len+1 < sizeof(mlbuf)) {
+-                      mlbuf[mlbuf_len] = '\n';
+-                      mlbuf[mlbuf_len+1] = '\0';
+-                      strncat(mlbuf, buf, sizeof(mlbuf)-mlbuf_len-2);
+-              } else {
+-                      DEBUGP("response too big for mlbuf!!!\n");
+-                      return -EFBIG;
+-              }
+-      }
++      if (mlbuf_len)
++              mlbuf[mlbuf_len ++] = '\n';
++      DEBUGP("Appending buf to mlbuf\n");
++      if (len > sizeof(mlbuf) - mlbuf_len)
++              len = sizeof(mlbuf) - mlbuf_len;
++      memcpy(mlbuf + mlbuf_len, buf, len);
++      mlbuf_len += len;
+       return 0;
+ final_cb:
+@@ -366,13 +371,16 @@
+       } else {
+               DEBUGP("Calling final cmd->cb()\n");
+               /* send final result code if there is no information response in mlbuf */
+-              if (mlbuf[0] == 0)
+-                      cmd->resp = buf;
+-              else
++              if (mlbuf_len) {
+                       cmd->resp = mlbuf;
++                      mlbuf[mlbuf_len] = 0;
++                      gsmd_log(GSMD_NOTICE,
++                                      "the text discarded is %s\n", buf);
++              } else
++                      cmd->resp = buf;
+               rc = cmd->cb(cmd, cmd->ctx, cmd->resp);
+               DEBUGP("Clearing mlbuf\n");
+-              mlbuf[0] = 0;
++              mlbuf_len = 0;
+       }
+       /* remove from list of currently executing cmds */
+@@ -385,7 +393,15 @@
+               g->gfd_uart.when |= GSMD_FD_WRITE;
+       return rc;
+-}     
++}
++
++/* called when the modem asked for a new line of a multiline atcmd */
++static int atcmd_prompt(void *data)
++{
++      struct gsmd *g = data;
++
++      g->gfd_uart.when |= GSMD_FD_WRITE;
++}
+ /* callback to be called if [virtual] UART has some data for us */
+ static int atcmd_select_cb(int fd, unsigned int what, void *data)
+@@ -393,6 +409,7 @@
+       int len, rc;
+       static char rxbuf[1024];
+       struct gsmd *g = data;
++      char *cr;
+       if (what & GSMD_FD_READ) {
+               memset(rxbuf, 0, sizeof(rxbuf));
+@@ -416,8 +433,12 @@
+       if ((what & GSMD_FD_WRITE) && g->interpreter_ready) {
+               struct gsmd_atcmd *pos, *pos2;
+               llist_for_each_entry_safe(pos, pos2, &g->pending_atcmds, list) {
+-                      len = strlen(pos->buf);
+-                      rc = write(fd, pos->buf, strlen(pos->buf));
++                      cr = strchr(pos->cur, '\n');
++                      if (cr)
++                              len = cr - pos->cur;
++                      else
++                              len = pos->buflen;
++                      rc = write(fd, pos->cur, len);
+                       if (rc == 0) {
+                               gsmd_log(GSMD_ERROR, "write returns 0, aborting\n");
+                               break;
+@@ -426,27 +447,32 @@
+                                       fd, rc);
+                               return rc;
+                       }
+-                      if (rc < len) {
+-                              gsmd_log(GSMD_FATAL, "short write!!! FIXME!\n");
+-                              exit(3);
+-                      }
++                      if (cr && rc == len)
++                              rc ++;  /* Skip the \n */
++                      pos->buflen -= rc;
++                      pos->cur += rc;
+                       write(fd, "\r", 1);
+-                      /* success: remove from global list of to-be-sent atcmds */
+-                      llist_del(&pos->list);
+-                      /* append to global list of executing atcmds */
+-                      llist_add_tail(&pos->list, &g->busy_atcmds);
++
++                      if (!pos->buflen) {
++                              /* success: remove from global list of
++                               * to-be-sent atcmds */
++                              llist_del(&pos->list);
++                              /* append to global list of executing atcmds */
++                              llist_add_tail(&pos->list, &g->busy_atcmds);
+                               /* we only send one cmd at the moment */
+-                              g->gfd_uart.when &= ~GSMD_FD_WRITE;
+                               break;
++                      } else {
++                              /* The write was short or the atcmd has more
++                               * lines to send after a "> ".  */
++                              if (!(rc < len))
++                                      break;
++                      }
+               }
+-      }
+-#if 0
+-      if (llist_empty(&g->pending_atcmds))
++              /* Either pending_atcmds is empty or a command has to wait */
+               g->gfd_uart.when &= ~GSMD_FD_WRITE;
+-#endif
+-              
++      }
+       return 0;
+ }
+@@ -457,10 +483,10 @@
+ {
+       int buflen = strlen(cmd);
+       struct gsmd_atcmd *atcmd;
+-      
++
+       if (rlen > buflen)
+               buflen = rlen;
+-      
++
+       atcmd = talloc_size(__atcmd_ctx, sizeof(*atcmd)+ buflen);
+       if (!atcmd)
+               return NULL;
+@@ -471,6 +497,7 @@
+       atcmd->ret = -255;
+       atcmd->buflen = buflen;
+       atcmd->buf[buflen-1] = '\0';
++      atcmd->cur = atcmd->buf;
+       atcmd->cb = cb;
+       atcmd->resp = NULL;
+       strncpy(atcmd->buf, cmd, buflen-1);
+@@ -483,8 +510,9 @@
+ {
+       DEBUGP("submitting command `%s'\n", cmd->buf);
++      if (llist_empty(&g->pending_atcmds))
++              g->gfd_uart.when |= GSMD_FD_WRITE;
+       llist_add_tail(&cmd->list, &g->pending_atcmds);
+-      g->gfd_uart.when |= GSMD_FD_WRITE;
+       return 0;
+ }
+@@ -520,9 +548,9 @@
+       g->llp.cur = g->llp.buf;
+       g->llp.len = sizeof(g->llp.buf);
+       g->llp.cb = &ml_parse;
++      g->llp.prompt_cb = &atcmd_prompt;
+       g->llp.ctx = g;
+       g->llp.flags = LGSM_ATCMD_F_EXTENDED;
+       return gsmd_register_fd(&g->gfd_uart);
+-}     
+-
++}
+Index: gsm/src/gsmd/sms_cb.c
+===================================================================
+--- gsm.orig/src/gsmd/sms_cb.c 2007-07-31 11:44:32.000000000 +0200
++++ gsm/src/gsmd/sms_cb.c      2007-07-31 11:46:44.000000000 +0200
+@@ -91,9 +91,6 @@
+       if (!ucmd)
+               return -ENOMEM;
+-
+-      
+-      
+       ucmd->hdr.version = GSMD_PROTO_VERSION;
+       ucmd->hdr.msg_type = GSMD_MSG_SMS;
+       ucmd->hdr.msg_subtype = GSMD_SMS_GETMSG_STORAGE;
+@@ -188,14 +185,26 @@
+ int sms_cb_init(struct gsmd *gsmd)
+ {
+       struct gsmd_atcmd *atcmd;
++      char buffer[10];
+       atcmd = atcmd_fill("AT+CSMS=0", NULL, gu, 0);
+       if (!atcmd)
+               return -ENOMEM;
+       atcmd_submit(gsmd, atcmd);
+-      /* Switch into "text mode" (Section 3.2.3) */
+-      atcdm = atcmd_fill("AT+CMGF=1", 9, &sms_cb_init_cb, gu, 0);
++      /* If text mode, set the encoding */
++      if (gu->gsmd->flags & GSMD_FLAG_SMS_FMT) {
++              atcmd = atcmd_fill("AT+CSCS=\"IRA\"", 13, NULL, gu, 0);
++              if (!atcmd)
++                      return -ENOMEM;
++              atcmd_submit(gsmd, atcmd);
++      }
++
++      /* Switch into desired mode (Section 3.2.3) */
++      snprintf(buffer, sizeof(buffer), "AT+CMGF=%i",
++                      (gu->gsmd->flags & GSMD_FLAG_SMS_FMT) ?
++                      GSMD_SMS_FMT_TEXT : GSMD_SMS_FMT_PDU);
++      atcmd = atcmd_fill(buffer, strlen(buffer), &sms_cb_init_cb, gu, 0);
+       if (!atcmd)
+               return -ENOMEM;
+Index: gsm/src/gsmd/usock.c
+===================================================================
+--- gsm.orig/src/gsmd/usock.c  2007-07-31 11:44:32.000000000 +0200
++++ gsm/src/gsmd/usock.c       2007-07-31 11:46:44.000000000 +0200
+@@ -75,7 +75,7 @@
+       ucmd->hdr.version = GSMD_PROTO_VERSION;
+       ucmd->hdr.msg_type = GSMD_MSG_PASSTHROUGH;
+       ucmd->hdr.msg_subtype = GSMD_PASSTHROUGH_RESP;
+-      ucmd->hdr.len = strlen(resp)+1;
++      ucmd->hdr.len = rlen;
+       ucmd->hdr.id = cmd->id;
+       memcpy(ucmd->buf, resp, ucmd->hdr.len);
+@@ -100,7 +100,7 @@
+ static int usock_rcv_event(struct gsmd_user *gu, struct gsmd_msg_hdr *gph, int len)
+ {
+-      u_int32_t *evtmask = (u_int32_t *) ((char *)gph + sizeof(*gph), gph->id);
++      u_int32_t *evtmask = (u_int32_t *) ((char *)gph + sizeof(*gph));
+       if (len < sizeof(*gph) + sizeof(u_int32_t))
+               return -EINVAL;
+@@ -471,18 +471,15 @@
+ static int sms_send_cb(struct gsmd_atcmd *cmd, void *ctx, char *resp)
+ {
+-      struct gsmd_user *gu = ctx;     
++      struct gsmd_user *gu = (struct gsmd_user *) ctx;
+       struct gsmd_ucmd *ucmd; 
+-      
+-      ucmd = gsmd_ucmd_fill(strlen(resp)+1, GSMD_MSG_SMS,
+-                            GSMD_SMS_SEND, 0);
++
++      ucmd = gsmd_ucmd_fill(strlen(resp) + 1,
++                      GSMD_MSG_SMS, GSMD_SMS_SEND, cmd->id);
+       if (!ucmd)
+               return -ENOMEM;
+-      
+       strcpy(ucmd->buf, resp);
+-
+       usock_cmd_enqueue(ucmd, gu);
+-
+       return 0;
+ }
+@@ -520,34 +517,142 @@
+       return 0;
+ }
++int packing_7bit_character(char *src, char *dest)
++{
++      int i,j = 0;
++      unsigned char ch1, ch2;
++      char tmp[2];
++      int shift = 0;
++      
++      *dest = '\0';
++
++      for ( i=0; i<strlen(src); i++ ) {
++              
++              ch1 = src[i] & 0x7F;
++              ch1 = ch1 >> shift;
++              ch2 = src[(i+1)] & 0x7F;
++              ch2 = ch2 << (7-shift); 
++
++              ch1 = ch1 | ch2;
++              
++              j = strlen(dest);
++              sprintf(tmp, "%X", (ch1 >> 4)); 
++              dest[j++] = tmp[0];
++              sprintf(tmp, "%X", (ch1 & 0x0F));
++              dest[j++] = tmp[0];             
++              dest[j++] = '\0';               
++                      
++              shift++;
++              
++              if ( 7 == shift ) {
++                      shift = 0;
++                      i++;
++              }
++      }                       
++      
++      return 0;
++}
++
++/* Refer to GSM 03.40 subclause 9.2.3.3, for SMS-SUBMIT */
++static int usock_pdu_make_smssubmit(char *dest, struct gsmd_sms_send *src)
++{
++      u_int8_t header[10 + GSMD_ADDR_MAXLEN];
++      int pos = 0, i, coding7bit = 1;
++
++      /* (Should be optional but some modems require it) SMSC Length octet
++       * is prepended.  If omitted or zero, use SMSC stored in the phone.  */
++      header[pos ++] = 0x00;
++
++      header[pos ++] =
++              GSMD_SMS_TP_MTI_SUBMIT |
++              (0 << 2) |              /* Reject Duplicates: 0 */
++              GSMD_SMS_TP_VPF_NOT_PRESENT |
++              GSMD_SMS_TP_SRR_NOT_REQUEST |
++              GSMD_SMS_TP_UDHI_NO_HEADER |
++              GSMD_SMS_TP_RP_NOT_SET;
++
++      /* TP-Message-Reference - 00 lets the phone set the number itself */
++      header[pos ++] = 0x00;
++
++      header[pos ++] = strlen(src->addr.number);
++      header[pos ++] = src->addr.type;
++      for (i = 0; src->addr.number[i]; i ++) {
++              header[pos] = src->addr.number[i ++] - '0';
++              if (src->addr.number[i])
++                      header[pos ++] |= (src->addr.number[i] - '0') << 4;
++              else {
++                      header[pos ++] |= 0xf0;
++                      break;
++              }
++      }
++
++      /* TP-Protocol-Identifier - 00 means implicit */
++      header[pos ++] = 0x00;
++
++      /* TP-Data-Coding-Scheme - 00 for 7-bit default alphabet */
++      header[pos ++] = coding7bit ? 0x00 : 0x04;
++
++      /* TP-Validity-Period, if present, would go here */
++
++      header[pos ++] = src->payload.length;
++
++      if (dest) {
++              for (i = 0; i < pos; i ++) {
++                      sprintf(dest, "%02X", header[i]);
++                      dest += 2;
++              }
++              if (coding7bit)
++                      packing_7bit_character(src->payload.data, dest);
++              else
++                      for (i = 0; i < src->payload.length; i ++) {
++                              sprintf(dest, "%02X", src->payload.data[i]);
++                              dest += 2;
++                      }
++      }
++
++      if (coding7bit)
++              return ((src->payload.length * 7 + 7) >> 3) + pos;
++      else
++              return src->payload.length + pos;
++}
++
++static const char *gsmd_cmgl_stat[] = {
++      "REC UNREAD", "REC READ", "STO UNSENT", "STO SENT", "ALL",
++};
++
+ static int usock_rcv_sms(struct gsmd_user *gu, struct gsmd_msg_hdr *gph, 
+                        int len)
+ {
+       /* FIXME: TEXT mode support!!  */
+       struct gsmd_atcmd *cmd = NULL;
+       struct gsmd_sms_delete *gsd;
+-      struct gsmd_sms *gs;
++      struct gsmd_sms_send *gss;
+       struct gsmd_sms_write *gsw;
+       int *stat, *index;
+       int atcmd_len;
+       char buf[1024];
+-      
++
+       switch (gph->msg_subtype) {
+       case GSMD_SMS_LIST:
+               /* FIXME: only support PDU mode!! */
+               if(len < sizeof(*gph) + sizeof(int))
+                       return -EINVAL;
+-              stat = (int *) ((void *)gph + sizeof(*gph));    
++              stat = (int *) ((void *)gph + sizeof(*gph));
++              if (*stat < 0 || *stat > 4)
++                      return -EINVAL;
+-              sprintf(buf, "%d", *stat);      
+-                              
+-              atcmd_len = 1 + strlen("AT+CMGL=") + strlen(buf);
+-              cmd = atcmd_fill("AT+CMGL=", atcmd_len,
+-                               &sms_list_cb, gu, gph->id);
++              if (gu->gsmd->flags & GSMD_FLAG_SMS_FMT)
++                      atcmd_len = sprintf(buf, "AT+CMGL=\"%s\"",
++                                      gsmd_cmgl_stat[*stat]);
++              else
++                      atcmd_len = sprintf(buf, "AT+CMGL=%i", *stat);
++
++              cmd = atcmd_fill(buf, atcmd_len + 1,
++                              &sms_list_cb, gu, gph->id);
+               if (!cmd)
+                       return -ENOMEM;
+-              sprintf(cmd->buf, "AT+CMGL=%s", buf);
+               break;
++
+       case GSMD_SMS_READ:
+               /* FIXME: only support PDU mode!! */
+               if(len < sizeof(*gph) + sizeof(int))
+@@ -563,6 +668,34 @@
+                       return -ENOMEM;
+               sprintf(cmd->buf, "AT+CMGR=%s", buf);
+               break;
++
++      case GSMD_SMS_SEND:
++              if (len < sizeof(*gph) + sizeof(*gss))
++                      return -EINVAL;
++              gss = (struct gsmd_sms_send *) ((void *) gph + sizeof(*gph));   
++
++              if (gu->gsmd->flags & GSMD_FLAG_SMS_FMT) {
++                      atcmd_len = sprintf(buf, "AT+CMGS=\"%s\"\n%.*s",
++                                      gss->addr.number,
++                                      gss->payload.length,
++                                      gss->payload.data);
++              } else {
++                      atcmd_len = sprintf(buf, "AT+CMGS=%i\n",
++                                      usock_pdu_make_smssubmit(NULL,
++                                              gss) - 1);
++                      atcmd_len += usock_pdu_make_smssubmit(buf + atcmd_len,
++                                      gss) * 2;
++              }
++              buf[atcmd_len ++] = 26; /* ^Z ends the message */
++              buf[atcmd_len ++] = 0;
++
++              cmd = atcmd_fill(buf, atcmd_len, &sms_send_cb, gu, gph->id);
++              if (!cmd)
++                      return -ENOMEM;
++              break;
++      case GSMD_SMS_WRITE:
++              gsmd_log(GSMD_DEBUG, "sms write\n");
++              break;
+ #if 0
+       case GSMD_SMS_SEND:
+               /* FIXME: only support PDU mode!! */
+@@ -610,8 +743,8 @@
+       default:
+               return -EINVAL;
+       }
+-              
+-      gsmd_log(GSMD_DEBUG, "%s\n", cmd->buf);
++
++      gsmd_log(GSMD_DEBUG, "%s\n", cmd ? cmd->buf : 0);
+       if (cmd)
+               return atcmd_submit(gu->gsmd, cmd);
+       else
+@@ -867,7 +1000,7 @@
+       [GSMD_MSG_PIN]          = &usock_rcv_pin,
+       [GSMD_MSG_PHONE]        = &usock_rcv_phone,
+       [GSMD_MSG_NETWORK]      = &usock_rcv_network,
+-      [GSMD_MSG_SMS]          = &usock_rcv_sms,       
++      [GSMD_MSG_SMS]          = &usock_rcv_sms,
+       //[GSMD_MSG_PHONEBOOK]  = &usock_rcv_phonebook,
+ };
+Index: gsm/src/gsmd/vendor_ti.c
+===================================================================
+--- gsm.orig/src/gsmd/vendor_ti.c      2007-07-31 11:46:28.000000000 +0200
++++ gsm/src/gsmd/vendor_ti.c   2007-07-31 11:46:44.000000000 +0200
+@@ -277,7 +277,7 @@
+ static int ticalypso_initsettings(struct gsmd *g)
+ {
+-      int rc;
++      int rc = 0;
+       struct gsmd_atcmd *cmd;
+       /* use +CTZR: to report time zone changes */
+Index: gsm/src/libgsmd/libgsmd_sms.c
+===================================================================
+--- gsm.orig/src/libgsmd/libgsmd_sms.c 2007-07-31 11:44:32.000000000 +0200
++++ gsm/src/libgsmd/libgsmd_sms.c      2007-07-31 11:46:44.000000000 +0200
+@@ -83,19 +83,33 @@
+       return 0;
+ }
+-int lgsmd_sms_send(struct lgsm_handle *lh, 
+-              const struct lgsm_sms *sms)   
++#ifndef MIN
++# define MIN(a,b)     (((a) < (b)) ? (a) : (b))
++#endif
++
++int lgsmd_sms_send(struct lgsm_handle *lh,
++              const struct lgsm_sms *sms)
+ {
+       /* FIXME: only support PDU mode */
+       struct gsmd_msg_hdr *gmh;
+-      struct gsmd_sms *gs;
++      struct gsmd_sms_send *gss;
+       int rc;
+       gmh = lgsm_gmh_fill(GSMD_MSG_SMS,
+-                      GSMD_SMS_SEND, sizeof(*gs));
++                      GSMD_SMS_SEND, sizeof(*gss));
+       if (!gmh)
+               return -ENOMEM;
+-      gs = (struct gsmd_sms *) gmh->data;
++      gss = (struct gsmd_sms_send *) gmh->data;
++
++      gss->addr.type =
++              GSMD_TOA_NPI_ISDN |
++              GSMD_TOA_TON_UNKNOWN |
++              GSMD_TOA_RESERVED;
++      strncpy(gss->addr.number, sms->addr, sizeof(gss->addr.number));
++
++      gss->payload.length =
++              MIN(strlen(sms->data), sizeof(gss->payload.data));
++      memcpy(gss->payload.data, sms->data, gss->payload.length);
+       rc = lgsm_send(lh, gmh);
+       if (rc < gmh->len + sizeof(*gmh)) {
+@@ -108,7 +122,7 @@
+       return 0;
+ }
+-int lgsmd_sms_write(struct lgsm_handle *lh, 
++int lgsmd_sms_write(struct lgsm_handle *lh,
+               const struct lgsm_sms_write *sms_write)
+ {
+       /* FIXME: only support PDU mode */
+
diff --git a/packages/gsm/files/vendor-qc-v0.patch b/packages/gsm/files/vendor-qc-v0.patch
deleted file mode 100644 (file)
index 8306f8a..0000000
+++ /dev/null
@@ -1,38 +0,0 @@
-Index: gsm/src/gsmd/vendor_qc.c
-===================================================================
---- gsm.orig/src/gsmd/vendor_qc.c      2007-06-13 20:13:47.000000000 +0200
-+++ gsm/src/gsmd/vendor_qc.c   2007-06-13 20:45:19.000000000 +0200
-@@ -81,6 +88,9 @@
- {
-       /* FIXME: do actual detection of vendor if we have multiple vendors */
-       /* open /proc/cpuinfo and check for HTC Universal? */
-+
-+      /* The Qualcomm chip starts in V0 mode */
-+      g->flags |= GSMD_FLAG_V0;
-       return 1;
- }
-Index: gsm/src/gsmd/gsmd.c
-===================================================================
---- gsm.orig/src/gsmd/gsmd.c   2007-06-13 20:13:47.000000000 +0200
-+++ gsm/src/gsmd/gsmd.c        2007-06-13 20:49:54.000000000 +0200
-@@ -62,7 +62,8 @@
- {
-       struct gsmd_alive_priv *alp = ctx;
--      if (!strcmp(resp, "OK"))
-+      if (!strcmp(resp, "OK") ||
-+          ((alp->gsmd->flags & GSMD_FLAG_V0) && resp[0] == '0'))
-               alp->alive_responded = 1;
-       return 0;
- }
-@@ -201,7 +202,8 @@
- {
-       struct gsmd *gsmd = ctx;
--      if (strcmp(resp, "OK")) {
-+      if (strcmp(resp, "OK") &&
-+          (!(gsmd->flags & GSMD_FLAG_V0) || resp[0] != '0')) {
-               gsmd_log(GSMD_FATAL, "response '%s' to initial command invalid", resp);
-               exit(5);
-       }
index 7fc54a5..31b23de 100644 (file)
@@ -4,17 +4,18 @@ LICENSE = "GPL"
 SECTION = "libs/gsm"
 PROVIDES += "gsmd"
 PV = "0.0+svn${SRCDATE}"
-PR = "r14"
+PR = "r15"
 
 SRC_URI = "svn://svn.openmoko.org/trunk/src/target;module=gsm;proto=http \
            file://gsmd \
            file://default \
            file://extreplychars.patch;patch=1 \
            file://getopt-wait-interpreter-ready.patch;patch=1 \
-           file://alive-start-if-interpreter-ready.patch;patch=1 \
            file://tihtc-csq-fix.patch;patch=1 \
-           file://vendor-qc-v0.patch;patch=1 \
-           file://universal-wcdma.patch;patch=1"
+           file://universal-wcdma.patch;patch=1 \
+           file://mlbuf-static-bss.patch;patch=1 \
+           file://libgsmd-tool-fix.patch;patch=1 \
+           file://sms-hacks.patch;patch=1"
 
 S = "${WORKDIR}/gsm"