Send commitlog mailing list submissions to
        [email protected]

To subscribe or unsubscribe via the World Wide Web, visit
        http://lists.openmoko.org/mailman/listinfo/commitlog
or, via email, send a message with subject or body 'help' to
        [EMAIL PROTECTED]

You can reach the person managing the list at
        [EMAIL PROTECTED]

When replying, please edit your Subject line so it is more specific
than "Re: Contents of commitlog digest..."
Today's Topics:

   1. r2711 - in trunk/src/target/gsm: include/gsmd src/gsmd
      src/util ([EMAIL PROTECTED])
   2. r2712 - in trunk/src/target/gsm: include/gsmd src/gsmd
      ([EMAIL PROTECTED])
   3. r2713 - in trunk/src/target/gsm: include/gsmd include/libgsmd
      src/gsmd src/libgsmd src/util ([EMAIL PROTECTED])
--- Begin Message ---
Author: laforge
Date: 2007-08-16 06:20:03 +0200 (Thu, 16 Aug 2007)
New Revision: 2711

Modified:
   trunk/src/target/gsm/include/gsmd/sms.h
   trunk/src/target/gsm/include/gsmd/usock.h
   trunk/src/target/gsm/src/gsmd/Makefile.am
   trunk/src/target/gsm/src/gsmd/gsmd.c
   trunk/src/target/gsm/src/gsmd/sms_cb.c
   trunk/src/target/gsm/src/gsmd/sms_pdu.c
   trunk/src/target/gsm/src/gsmd/usock.c
   trunk/src/target/gsm/src/util/event.c
Log:
>From 5b7c50fd08b8f76f761958c8a8243e6c23118fa3 Mon Sep 17 00:00:00 2001
From: Andrzej Zaborowski <[EMAIL PROTECTED]>
Date: Thu, 12 Jul 2007 14:26:46 +0200
Subject: [PATCH] Incoming SMS events

This is a proposed patch to emit a gsmd event when a new SMS arrives, also
modifies libgsmd-tool to display the notification.  It makes sms_cb.c compile
but only really implements the bits necessary to make it build and for the
notifications to work.  I chose AT+CNMI mode 1 (i.e. store messages in memory
and report the location through +CMTI, rather than print the message right away
through +CMT) because the parser doesn't support multiline unsolicited
responses - in fact it can't support those because in a situation when a normal
command is executing and an unsolicited response comes in (which is the case
when sending a message to yourself) it is impossible for the parser to
distinguish whether the line after the unsolicited response is part of that
response or part of the command's response.


Modified: trunk/src/target/gsm/include/gsmd/sms.h
===================================================================
--- trunk/src/target/gsm/include/gsmd/sms.h     2007-08-16 04:18:54 UTC (rev 
2710)
+++ trunk/src/target/gsm/include/gsmd/sms.h     2007-08-16 04:20:03 UTC (rev 
2711)
@@ -5,6 +5,8 @@
 
 #include <gsmd/gsmd.h>
 
+int sms_cb_init(struct gsmd *gsmd);
+
 int sms_pdu_make_smssubmit(char *dest, const struct gsmd_sms_submit *src);
 int sms_pdu_to_msg(struct gsmd_sms_list *dst, const u_int8_t *src,
                int pdulen, int len);

Modified: trunk/src/target/gsm/include/gsmd/usock.h
===================================================================
--- trunk/src/target/gsm/include/gsmd/usock.h   2007-08-16 04:18:54 UTC (rev 
2710)
+++ trunk/src/target/gsm/include/gsmd/usock.h   2007-08-16 04:20:03 UTC (rev 
2711)
@@ -55,6 +55,11 @@
        GSMD_PHONE_POWERDOWN    = 2,
 };
 
+enum gsmd_msg_cb {
+       GSMD_CB_SUBSCRIBE       = 1,
+       GSMD_CB_UNSUBSCRIBE     = 2,
+};
+
 enum gsmd_msg_network {
        GSMD_NETWORK_REGISTER   = 1,
        GSMD_NETWORK_SIGQ_GET   = 2,
@@ -65,11 +70,15 @@
 };
 
 enum gsmd_msg_sms {
-       GSMD_SMS_LIST           = 1,
-       GSMD_SMS_READ           = 2,
-       GSMD_SMS_SEND           = 3,
-       GSMD_SMS_WRITE          = 4,
-       GSMD_SMS_DELETE         = 5,    
+       GSMD_SMS_LIST                   = 1,
+       GSMD_SMS_READ                   = 2,
+       GSMD_SMS_SEND                   = 3,
+       GSMD_SMS_WRITE                  = 4,
+       GSMD_SMS_DELETE                 = 5,
+       GSMD_SMS_GET_MSG_STORAGE        = 6,
+       GSMD_SMS_SET_MSG_STORAGE        = 7,
+       GSMD_SMS_GET_SERVICE_CENTRE     = 8,
+       GSMD_SMS_SET_SERVICE_CENTRE     = 9,
 };
 
 /* SMS stat from 3GPP TS 07.05, Clause 3.1 */
@@ -248,8 +257,8 @@
                        struct gsmd_addr addr;
                } colp;
                struct {
-                       /* TBD */
-                       struct gsmd_addr addr;
+                       u_int8_t memtype;
+                       int index;
                } sms;
                struct {
                        enum gsmd_pin_type type;

Modified: trunk/src/target/gsm/src/gsmd/Makefile.am
===================================================================
--- trunk/src/target/gsm/src/gsmd/Makefile.am   2007-08-16 04:18:54 UTC (rev 
2710)
+++ trunk/src/target/gsm/src/gsmd/Makefile.am   2007-08-16 04:20:03 UTC (rev 
2711)
@@ -7,7 +7,7 @@
 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 timer.c operator_cache.c ext_response.c \
-              sms_pdu.c
+              sms_cb.c sms_pdu.c
 gsmd_LDADD = -ldl
 gsmd_LDFLAGS = -Wl,--export-dynamic
 

Modified: trunk/src/target/gsm/src/gsmd/gsmd.c
===================================================================
--- trunk/src/target/gsm/src/gsmd/gsmd.c        2007-08-16 04:18:54 UTC (rev 
2710)
+++ trunk/src/target/gsm/src/gsmd/gsmd.c        2007-08-16 04:20:03 UTC (rev 
2711)
@@ -185,8 +185,10 @@
 #if 0
        /* Select TE character set */           
        rc |= gsmd_simplecmd(gsmd, "AT+CSCS=\"UCS2\"");
-#endif 
+#endif
 
+       sms_cb_init(gsmd);
+
        if (gsmd->vendorpl && gsmd->vendorpl->initsettings)
                return gsmd->vendorpl->initsettings(gsmd);
        else

Modified: trunk/src/target/gsm/src/gsmd/sms_cb.c
===================================================================
--- trunk/src/target/gsm/src/gsmd/sms_cb.c      2007-08-16 04:18:54 UTC (rev 
2710)
+++ trunk/src/target/gsm/src/gsmd/sms_cb.c      2007-08-16 04:20:03 UTC (rev 
2711)
@@ -36,11 +36,11 @@
 #include <gsmd/select.h>
 #include <gsmd/atcmd.h>
 #include <gsmd/usock.h>
+#include <gsmd/unsolicited.h>
 
 enum ts0705_mem_type {
        GSM0705_MEMTYPE_NONE,
        GSM0705_MEMTYPE_BROADCAST,
-       GSM0705_MEMTYPE_BROADCAST,
        GSM0705_MEMTYPE_ME_MESSAGE,
        GSM0705_MEMTYPE_MT,
        GSM0705_MEMTYPE_SIM,
@@ -48,7 +48,7 @@
        GSM0705_MEMTYPE_SR,
 };
 
-static const char *ts0705_memtype_name = {
+static const char *ts0705_memtype_name[] = {
        [GSM0705_MEMTYPE_NONE]          = "NONE",
        [GSM0705_MEMTYPE_BROADCAST]     = "BM",
        [GSM0705_MEMTYPE_ME_MESSAGE]    = "ME",
@@ -70,9 +70,10 @@
        return GSM0705_MEMTYPE_NONE;
 }
 
+/* TODO: move to headers */
 struct __gsmd_sms_storage {
-       u_int8 memtype;
-       u_int8_t pad[3]
+       u_int8_t memtype;
+       u_int8_t pad[3];
        u_int16_t used;
        u_int16_t total;
 } __attribute__ ((packed));
@@ -85,21 +86,34 @@
 {
        struct gsmd_user *gu = ctx;
        struct gsmd_ucmd *ucmd = ucmd_alloc(sizeof(struct gsmd_sms_storage));
+       struct gsmd_sms_storage *gss = (typeof(gss)) ucmd->buf;
+       char buf[3][3];
 
        DEBUGP("entering(cmd=%p, gu=%p)\n", cmd, gu);
 
        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;
-       ucmd->hdr.len = ...;
+       ucmd->hdr.msg_subtype = GSMD_SMS_GET_MSG_STORAGE;
+       ucmd->hdr.len = sizeof(struct gsmd_sms_storage);
        ucmd->hdr.id = cmd->id;
-       
+
+       if (sscanf(resp, "+CPMS: \"%2[A-Z]\",%hi,%hi,"
+                               "\"%2[A-Z]\",%hi,%hi,\"%2[A-Z]\",%hi,%hi",
+                               buf[0], &gss->mem[0].used, &gss->mem[0].total,
+                               buf[1], &gss->mem[1].used, &gss->mem[1].total,
+                               buf[2], &gss->mem[2].used, &gss->mem[2].total)
+                       < 9) {
+               talloc_free(ucmd);
+               return -EINVAL;
+       }
+
+       gss->mem[0].memtype = parse_memtype(buf[0]);
+       gss->mem[1].memtype = parse_memtype(buf[1]);
+       gss->mem[2].memtype = parse_memtype(buf[2]);
+
        usock_cmd_enqueue(ucmd, gu);
 
        return 0;
@@ -113,14 +127,13 @@
 
        switch (gph->msg_subtype) {
        case GSMD_SMS_GET_SERVICE_CENTRE:
-               
-               break;
+               return;
        case GSMD_SMS_SET_SERVICE_CENTRE:
-               break;
+               return;
        case GSMD_SMS_SET_MSG_STORAGE:
-               break;
+               return;
        case GSMD_SMS_GET_MSG_STORAGE:
-               cmd = atcmd_fill("AT+CPMS?", 8, ...);
+               cmd = atcmd_fill("AT+CPMS?", 8 + 1, usock_cpms_cb, gu, 0);
                break;
        }
 
@@ -131,7 +144,6 @@
 static int usock_rcv_cb(struct gsmd_user *gu, struct gsmd_msg_hdr *gph,
                        int len)
 {
-
        switch (gph->msg_subtype) {
        case GSMD_CB_SUBSCRIBE:
                break;
@@ -139,44 +151,158 @@
                break;
        }
 
-       return 
+       return -ENOSYS;
 }
 
-
 /* Unsolicited messages related to SMS / CB */
 static int cmti_parse(char *buf, int len, const char *param,
                      struct gsmd *gsmd)
 {
+       char memstr[3];
+       struct gsmd_ucmd *ucmd = ucmd_alloc(sizeof(struct gsmd_evt_auxdata));
+       struct gsmd_evt_auxdata *aux = (struct gsmd_evt_auxdata *) ucmd->buf;
+
+       if (!ucmd)
+               return -ENOMEM;
+
+       ucmd->hdr.version = GSMD_PROTO_VERSION;
+       ucmd->hdr.msg_type = GSMD_MSG_EVENT;
+       ucmd->hdr.msg_subtype = GSMD_EVT_IN_SMS;
+       ucmd->hdr.len = sizeof(*aux);
+
+       if (sscanf(param, "\"%2[A-Z]\",%i", memstr, &aux->u.sms.index) < 2) {
+               talloc_free(ucmd);
+               return -EINVAL;
+       }
+
+       aux->u.sms.memtype = parse_memtype(memstr);
+
+       return usock_evt_send(gsmd, ucmd, GSMD_EVT_IN_SMS);
 }
 
 static int cmt_parse(char *buf, int len, const char *param,
                     struct gsmd *gsmd)
 {
+       /* TODO: TEXT mode */
+       u_int8_t pdu[180];
+       const char *comma = strchr(param, ',');
+       char *cr;
+       int i;
+       struct gsmd_sms_list msg;
+
+       if (!comma)
+               return -EINVAL;
+       len = strtoul(comma + 1, &cr, 10);
+       if (cr[0] != '\n')
+               return -EINVAL;
+
+       cr ++;
+       for (i = 0; cr[0] >= '0' && cr[1] >= '0' && i < 180; i ++) {
+               if (sscanf(cr, "%2hhX", &pdu[i]) < 1) {
+                       gsmd_log(GSMD_DEBUG, "malformed input (%i)\n", i);
+                       return -EINVAL;
+               }
+               cr += 2;
+       }
+       if (sms_pdu_to_msg(&msg, pdu, len, i)) {
+               gsmd_log(GSMD_DEBUG, "malformed PDU\n");
+               return -EINVAL;
+       }
+
+       /* FIXME: generate some kind of event */
+       return -ENOSYS;
 }
 
 static int cbmi_parse(char *buf, int len, const char *param,
                      struct gsmd *gsmd)
 {
+       char memstr[3];
+       int memtype, index;
+
+       if (sscanf(param, "\"%2[A-Z]\",%i", memstr, &index) < 2)
+               return -EINVAL;
+
+       memtype = parse_memtype(memstr);
+       /* FIXME: generate some kind of event */
+       return -ENOSYS;
 }
 
 static int cbm_parse(char *buf, int len, const char *param,
                     struct gsmd *gsmd)
 {
+       /* TODO: TEXT mode */
+       u_int8_t pdu[180];
+       char *cr;
+       int i;
+       struct gsmd_sms_list msg;
+
+       len = strtoul(param, &cr, 10);
+       if (cr[0] != '\n')
+               return -EINVAL;
+
+       cr ++;
+       for (i = 0; cr[0] >= '0' && cr[1] >= '0' && i < 180; i ++) {
+               if (sscanf(cr, "%2hhX", &pdu[i]) < 1) {
+                       gsmd_log(GSMD_DEBUG, "malformed input (%i)\n", i);
+                       return -EINVAL;
+               }
+               cr += 2;
+       }
+       if (sms_pdu_to_msg(&msg, pdu, len, i)) {
+               gsmd_log(GSMD_DEBUG, "malformed PDU\n");
+               return -EINVAL;
+       }
+
+       /* FIXME: generate some kind of event */
+       return -ENOSYS;
 }
 
 static int cdsi_parse(char *buf, int len, const char *param,
                      struct gsmd *gsmd)
 {
+       char memstr[3];
+       int memtype, index;
+
+       if (sscanf(param, "\"%2[A-Z]\",%i", memstr, &index) < 2)
+               return -EINVAL;
+
+       memtype = parse_memtype(memstr);
+       /* FIXME: generate some kind of event */
+       return -ENOSYS;
 }
 
 static int cds_parse(char *buf, int len, const char *param,
                     struct gsmd *gsmd)
 {
+       /* TODO: TEXT mode */
+       u_int8_t pdu[180];
+       char *cr;
+       int i;
+       struct gsmd_sms_list msg;
+
+       len = strtoul(param, &cr, 10);
+       if (cr[0] != '\n')
+               return -EINVAL;
+
+       cr ++;
+       for (i = 0; cr[0] >= '0' && cr[1] >= '0' && i < 180; i ++) {
+               if (sscanf(cr, "%2hhX", &pdu[i]) < 1) {
+                       gsmd_log(GSMD_DEBUG, "malformed input (%i)\n", i);
+                       return -EINVAL;
+               }
+               cr += 2;
+       }
+       if (sms_pdu_to_msg(&msg, pdu, len, i)) {
+               gsmd_log(GSMD_DEBUG, "malformed PDU\n");
+               return -EINVAL;
+       }
+
+       /* FIXME: generate some kind of event */
+       return -ENOSYS;
 }
 
-
-static const struct gsmd_unsolocit gsm0705_unsolicit[] = {
-       { "+CMTI",      &cmti_parse },  /* SMS Deliver Index (stored in ME/TA) 
*/
+static const struct gsmd_unsolicit gsm0705_unsolicit[] = {
+       { "+CMTI",      &cmti_parse },  /* SMS Deliver Index (stored in ME/TA)*/
        { "+CMT",       &cmt_parse },   /* SMS Deliver to TE */
        { "+CBMI",      &cbmi_parse },  /* Cell Broadcast Message Index */
        { "+CBM",       &cbm_parse },   /* Cell Broadcast Message */
@@ -189,24 +315,43 @@
        struct gsmd_atcmd *atcmd;
        char buffer[10];
 
-       atcmd = atcmd_fill("AT+CSMS=0", NULL, gu, 0);
+       atcmd = atcmd_fill("AT+CSMS=0", 9 + 1, NULL, gsmd, 0);
        if (!atcmd)
                return -ENOMEM;
        atcmd_submit(gsmd, atcmd);
 
+       /* Store and notify */
+       atcmd = atcmd_fill("AT+CNMI=1,1,1", 13 + 1, NULL, gsmd, 0);
+       if (!atcmd)
+               return -ENOMEM;
+       atcmd_submit(gsmd, atcmd);
+
+       /* Store into ME/TA and notify */
+       atcmd = atcmd_fill("AT+CSBS=1", 9 + 1, NULL, gsmd, 0);
+       if (!atcmd)
+               return -ENOMEM;
+       atcmd_submit(gsmd, atcmd);
+
+       /* Store into ME/TA and notify */
+       atcmd = atcmd_fill("AT+CSDS=2", 9 + 1, NULL, gsmd, 0);
+       if (!atcmd)
+               return -ENOMEM;
+       atcmd_submit(gsmd, atcmd);
+
        /* If text mode, set the encoding */
-       if (gu->gsmd->flags & GSMD_FLAG_SMS_FMT_TEXT) {
-               atcmd = atcmd_fill("AT+CSCS=\"IRA\"", 13, NULL, gu, 0);
+       if (gsmd->flags & GSMD_FLAG_SMS_FMT_TEXT) {
+               atcmd = atcmd_fill("AT+CSCS=\"IRA\"", 13 + 1, NULL, gsmd, 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_TEXT) ?
-                       GSMD_SMS_FMT_TEXT : GSMD_SMS_FMT_PDU);
-       atcmd = atcmd_fill(buffer, strlen(buffer) + 1, NULL, gu, 0);
+       atcmd = atcmd_fill(buffer, snprintf(buffer, sizeof(buffer),
+                               "AT+CMGF=%i",
+                               (gsmd->flags & GSMD_FLAG_SMS_FMT_TEXT) ?
+                               GSMD_SMS_FMT_TEXT : GSMD_SMS_FMT_PDU) + 1,
+                       NULL, gsmd, 0);
        if (!atcmd)
                return -ENOMEM;
 

Modified: trunk/src/target/gsm/src/gsmd/sms_pdu.c
===================================================================
--- trunk/src/target/gsm/src/gsmd/sms_pdu.c     2007-08-16 04:18:54 UTC (rev 
2710)
+++ trunk/src/target/gsm/src/gsmd/sms_pdu.c     2007-08-16 04:20:03 UTC (rev 
2711)
@@ -179,6 +179,8 @@
 
                memset(dst->time_stamp, 0, 7);
                break;
+       case GSMD_SMS_TP_MTI_STATUS_REPORT:
+               /* TODO */
        default:
                /* Unknown PDU type */
                return 1;

Modified: trunk/src/target/gsm/src/gsmd/usock.c
===================================================================
--- trunk/src/target/gsm/src/gsmd/usock.c       2007-08-16 04:18:54 UTC (rev 
2710)
+++ trunk/src/target/gsm/src/gsmd/usock.c       2007-08-16 04:20:03 UTC (rev 
2711)
@@ -532,7 +532,7 @@
        struct gsmd_ucmd *ucmd;
        int msgref;
 
-       if (cmd->ret == 0) {
+       if (cmd->ret == 0 || cmd->ret == -255) {
                if (sscanf(resp, "+CMGS: %i", &msgref) < 1)
                        return -EINVAL;
        } else

Modified: trunk/src/target/gsm/src/util/event.c
===================================================================
--- trunk/src/target/gsm/src/util/event.c       2007-08-16 04:18:54 UTC (rev 
2710)
+++ trunk/src/target/gsm/src/util/event.c       2007-08-16 04:20:03 UTC (rev 
2711)
@@ -34,6 +34,13 @@
        return 0;
 }
 
+static int insms_handler(struct lgsm_handle *lh, int evt, struct 
gsmd_evt_auxdata *aux)
+{
+       printf("EVENT: Incoming SMS stored at location %i\n", aux->u.sms.index);
+
+       return 0;
+}
+
 static int clip_handler(struct lgsm_handle *lh, int evt, struct 
gsmd_evt_auxdata *aux)
 {
        printf("EVENT: Incoming call clip = %s\n", aux->u.clip.addr.number);
@@ -131,6 +138,7 @@
 
        rc  = lgsm_evt_handler_register(lh, GSMD_EVT_IN_CALL, &incall_handler);
        rc |= lgsm_evt_handler_register(lh, GSMD_EVT_IN_CLIP, &clip_handler);
+       rc |= lgsm_evt_handler_register(lh, GSMD_EVT_IN_SMS, &insms_handler);
        rc |= lgsm_evt_handler_register(lh, GSMD_EVT_OUT_COLP, &colp_handler);
        rc |= lgsm_evt_handler_register(lh, GSMD_EVT_NETREG, &netreg_handler);
        rc |= lgsm_evt_handler_register(lh, GSMD_EVT_SIGNAL, &sigq_handler);




--- End Message ---
--- Begin Message ---
Author: laforge
Date: 2007-08-16 06:25:26 +0200 (Thu, 16 Aug 2007)
New Revision: 2712

Modified:
   trunk/src/target/gsm/include/gsmd/unsolicited.h
   trunk/src/target/gsm/src/gsmd/gsmd.c
   trunk/src/target/gsm/src/gsmd/sms_cb.c
   trunk/src/target/gsm/src/gsmd/unsolicited.c
Log:
Dynamic registration of unsolicited responses (Andrzej Zaborowski)


Modified: trunk/src/target/gsm/include/gsmd/unsolicited.h
===================================================================
--- trunk/src/target/gsm/include/gsmd/unsolicited.h     2007-08-16 04:20:03 UTC 
(rev 2711)
+++ trunk/src/target/gsm/include/gsmd/unsolicited.h     2007-08-16 04:25:26 UTC 
(rev 2712)
@@ -12,6 +12,9 @@
 
 extern int unsolicited_parse(struct gsmd *g, char *buf, int len, const char 
*param);
 extern int generate_event_from_cme(struct gsmd *g, unsigned int cme_error);
+extern void unsolicited_generic_init(struct gsmd *g);
+extern int unsolicited_register_array(const struct gsmd_unsolicit *arr,
+               int len);
 
 #endif /* __GSMD__ */
 

Modified: trunk/src/target/gsm/src/gsmd/gsmd.c
===================================================================
--- trunk/src/target/gsm/src/gsmd/gsmd.c        2007-08-16 04:20:03 UTC (rev 
2711)
+++ trunk/src/target/gsm/src/gsmd/gsmd.c        2007-08-16 04:25:26 UTC (rev 
2712)
@@ -477,6 +477,8 @@
        /* select a vendor plugin */
        gsmd_vendor_plugin_find(&g);
 
+       unsolicited_init(&g);
+
        if (g.interpreter_ready) {
                gsmd_initsettings(&g);
        

Modified: trunk/src/target/gsm/src/gsmd/sms_cb.c
===================================================================
--- trunk/src/target/gsm/src/gsmd/sms_cb.c      2007-08-16 04:20:03 UTC (rev 
2711)
+++ trunk/src/target/gsm/src/gsmd/sms_cb.c      2007-08-16 04:25:26 UTC (rev 
2712)
@@ -315,6 +315,9 @@
        struct gsmd_atcmd *atcmd;
        char buffer[10];
 
+       unsolicited_register_array(gsm0705_unsolicit,
+                       ARRAY_SIZE(gsm0705_unsolicit));
+
        atcmd = atcmd_fill("AT+CSMS=0", 9 + 1, NULL, gsmd, 0);
        if (!atcmd)
                return -ENOMEM;

Modified: trunk/src/target/gsm/src/gsmd/unsolicited.c
===================================================================
--- trunk/src/target/gsm/src/gsmd/unsolicited.c 2007-08-16 04:20:03 UTC (rev 
2711)
+++ trunk/src/target/gsm/src/gsmd/unsolicited.c 2007-08-16 04:25:26 UTC (rev 
2712)
@@ -358,49 +358,31 @@
        */
 };
 
+static struct gsmd_unsolicit unsolicit[256] = {{ 0, 0 }};
+
 /* called by midlevel parser if a response seems unsolicited */
 int unsolicited_parse(struct gsmd *g, char *buf, int len, const char *param)
 {
-       int i, rc;
+       struct gsmd_unsolicit *i;
+       int rc;
        struct gsmd_vendor_plugin *vpl = g->vendorpl;
 
-       /* call vendor-specific unsolicited code parser */
-       if (vpl && vpl->num_unsolicit) {
-               for (i = 0; i < vpl->num_unsolicit; i++) {
-                       const char *colon;
-                       if (strncmp(buf, vpl->unsolicit[i].prefix,
-                                    strlen(vpl->unsolicit[i].prefix)))
-                               continue;
-
-                       colon = strchr(buf, ':') + 2;
-                       if (colon > buf+len)
-                               colon = NULL;
-
-                       rc = vpl->unsolicit[i].parse(buf, len, colon, g);
-                       if (rc < 0) 
-                               gsmd_log(GSMD_ERROR, "error %d during parse of "
-                                        "vendor unsolicied response `%s'\n",
-                                        rc, buf);
-                       return rc;
-               }
-       }
-
-       /* call generic unsolicited code parser */
-       for (i = 0; i < ARRAY_SIZE(gsm0707_unsolicit); i++) {
+       /* call unsolicited code parser */
+       for (i = unsolicit; i->prefix; i ++) {
                const char *colon;
-               if (strncmp(buf, gsm0707_unsolicit[i].prefix,
-                            strlen(gsm0707_unsolicit[i].prefix)))
+               if (strncmp(buf, i->prefix, strlen(i->prefix)))
                        continue;
-               
+
                colon = strchr(buf, ':') + 2;
                if (colon > buf+len)
                        colon = NULL;
 
-               rc = gsm0707_unsolicit[i].parse(buf, len, colon, g);
+               rc = i->parse(buf, len, colon, g);
                if (rc < 0) 
-                       gsmd_log(GSMD_ERROR, "error %d during parse of "
-                                "unsolicied response `%s'\n", rc, buf);
-               return rc;
+                       gsmd_log(GSMD_ERROR, "error %d during parsing of "
+                                "an unsolicied response `%s'\n",
+                                rc, buf);
+                       return rc;
        }
 
        gsmd_log(GSMD_NOTICE, "no parser for unsolicited response `%s'\n", buf);
@@ -408,6 +390,39 @@
        return -ENOENT;
 }
 
+int unsolicited_register_array(const struct gsmd_unsolicit *arr, int len)
+{
+       int curlen = 0;
+
+       while (unsolicit[curlen ++].prefix);
+       if (len + curlen > ARRAY_SIZE(unsolicit))
+               return -ENOMEM;
+
+       /* Add at the beginning for overriding to be possible */
+       memmove(&unsolicit[len], unsolicit,
+                       sizeof(struct gsmd_unsolicit) * curlen);
+       memcpy(unsolicit, arr,
+                       sizeof(struct gsmd_unsolicit) * len);
+
+       return 0;
+}
+
+void unsolicited_init(struct gsmd *g)
+{
+       struct gsmd_vendor_plugin *vpl = g->vendorpl;
+
+       /* register generic unsolicited code parser */
+       unsolicited_register_array(gsm0707_unsolicit,
+                       ARRAY_SIZE(gsm0707_unsolicit));
+
+       /* register vendor-specific unsolicited code parser */
+       if (vpl && vpl->num_unsolicit)
+               if (unsolicited_register_array(vpl->unsolicit,
+                                       vpl->num_unsolicit))
+                       gsmd_log(GSMD_ERROR, "registering vendor-specific "
+                                       "unsolicited responses failed\n");
+}
+
 static unsigned int errors_creating_events[] = {
        GSM0707_CME_PHONE_FAILURE,
        GSM0707_CME_PHONE_NOCONNECT,




--- End Message ---
--- Begin Message ---
Author: laforge
Date: 2007-08-16 07:48:59 +0200 (Thu, 16 Aug 2007)
New Revision: 2713

Modified:
   trunk/src/target/gsm/include/gsmd/usock.h
   trunk/src/target/gsm/include/libgsmd/misc.h
   trunk/src/target/gsm/src/gsmd/usock.c
   trunk/src/target/gsm/src/libgsmd/lgsm_internals.h
   trunk/src/target/gsm/src/libgsmd/libgsmd_event.c
   trunk/src/target/gsm/src/libgsmd/libgsmd_network.c
   trunk/src/target/gsm/src/util/shell.c
Log:
Operator Selection (Andrzej Zaborowski)

This adds gsmd/libgsmd/libgmsd-tool commands to:
 * query available operators,
 * register to given operator,
 * register automatically (like gsmd did until now),
 * deregister,
 * get current operator name,
 * query signal quality,
 * query current connection state (a bit hacky, but it's the only way
   I found to satisfy the synchronous prototype in misc.h).

The operator cache is not used as it wouldn't give any benefit here. Retrieving
the list of present operators takes very long but there doesn't seem to exist
any way around it and all other phones I used also take that long.

The libgmsd call for registration to an automatically chosen operator now takes
a parameter of a different type so all libgsmd clients need to be updated (this
patch updates libgsmd-tool already, but not libmokogsmd which is not a part of
gsmd project).


Modified: trunk/src/target/gsm/include/gsmd/usock.h
===================================================================
--- trunk/src/target/gsm/include/gsmd/usock.h   2007-08-16 04:25:26 UTC (rev 
2712)
+++ trunk/src/target/gsm/include/gsmd/usock.h   2007-08-16 05:48:59 UTC (rev 
2713)
@@ -66,7 +66,9 @@
        GSMD_NETWORK_VMAIL_GET  = 3,
        GSMD_NETWORK_VMAIL_SET  = 4,
        GSMD_NETWORK_OPER_GET   = 5,
-       GSMD_NETWORK_CIND_GET   = 6,
+       GSMD_NETWORK_OPER_LIST  = 6,
+       GSMD_NETWORK_CIND_GET   = 7,
+       GSMD_NETWORK_DEREGISTER = 8,
 };
 
 enum gsmd_msg_sms {
@@ -358,6 +360,26 @@
        u_int8_t tlength;
 } __attribute__ ((packed));
 
+/* Operator status from 3GPP TS 07.07, Clause 7.3 */
+enum gsmd_oper_status {
+       GSMD_OPER_UNKNOWN,
+       GSMD_OPER_AVAILABLE,
+       GSMD_OPER_CURRENT,
+       GSMD_OPER_FORBIDDEN,
+};
+
+/* Theoretically numeric operator code is five digits long but some
+ * operators apparently use six digit codes.  */
+typedef char gsmd_oper_numeric[6];
+
+struct gsmd_msg_oper {
+       enum gsmd_oper_status stat;
+       int is_last;
+       char opname_longalpha[16];
+       char opname_shortalpha[8];
+       gsmd_oper_numeric opname_num;
+};
+
 struct gsmd_msg_hdr {
        u_int8_t version;
        u_int8_t msg_type;

Modified: trunk/src/target/gsm/include/libgsmd/misc.h
===================================================================
--- trunk/src/target/gsm/include/libgsmd/misc.h 2007-08-16 04:25:26 UTC (rev 
2712)
+++ trunk/src/target/gsm/include/libgsmd/misc.h 2007-08-16 05:48:59 UTC (rev 
2713)
@@ -10,21 +10,6 @@
 
 extern int lgsm_phone_power(struct lgsm_handle *lh, int power);
 
-enum lgsm_netreg_state {
-       LGSM_NETREG_ST_NOTREG           = 0,
-       LGSM_NETREG_ST_REG_HOME         = 1,
-       LGSM_NETREG_ST_NOTREG_SEARCH    = 2,
-       LGSM_NETREG_ST_DENIED           = 3,
-       LGSM_NETREG_ST_UNKNOWN          = 4,
-       LGSM_NETREG_ST_REG_ROAMING      = 5,
-};
-
-/* Get the current network registration status */
-extern int lgsm_get_netreg_state(struct lgsm_handle *lh,
-                                enum lgsm_netreg_state *state);
-
-extern int lgsm_netreg_register(struct lgsm_handle *lh, int oper);
-
 enum lgsm_info_type {
        LGSM_INFO_TYPE_NONE             = 0,
        LGSM_INFO_TYPE_MANUF            = 1,
@@ -58,9 +43,25 @@
                              struct lgsm_addr *addr);
 
 /* Operator Selection, Network Registration */
-/* TBD */
+extern int lgsm_oper_get(struct lgsm_handle *lh);
+extern int lgsm_opers_get(struct lgsm_handle *lh);
+extern int lgsm_netreg_register(struct lgsm_handle *lh,
+               gsmd_oper_numeric oper);
+extern int lgsm_netreg_deregister(struct lgsm_handle *lh);
 
+enum lgsm_netreg_state {
+       LGSM_NETREG_ST_NOTREG           = 0,
+       LGSM_NETREG_ST_REG_HOME         = 1,
+       LGSM_NETREG_ST_NOTREG_SEARCH    = 2,
+       LGSM_NETREG_ST_DENIED           = 3,
+       LGSM_NETREG_ST_UNKNOWN          = 4,
+       LGSM_NETREG_ST_REG_ROAMING      = 5,
+};
 
+/* Get the current network registration status */
+extern int lgsm_get_netreg_state(struct lgsm_handle *lh,
+                                enum lgsm_netreg_state *state);
+
 /* CLIP, CLIR, COLP, Call Forwarding, Call Waiting, Call Deflecting */
 /* TBD */
 

Modified: trunk/src/target/gsm/src/gsmd/usock.c
===================================================================
--- trunk/src/target/gsm/src/gsmd/usock.c       2007-08-16 04:25:26 UTC (rev 
2712)
+++ trunk/src/target/gsm/src/gsmd/usock.c       2007-08-16 05:48:59 UTC (rev 
2713)
@@ -349,7 +349,7 @@
                return -ENOMEM;
        
        gsq = (struct gsmd_signal_quality *) ucmd->buf;
-       gsq->rssi = atoi(resp);
+       gsq->rssi = atoi(resp + 6);
        comma = strchr(resp, ',');
        if (!comma) {
                talloc_free(ucmd);
@@ -362,42 +362,104 @@
        return 0;
 }
 
-#define GSMD_OPER_MAXLEN       16
 static int network_oper_cb(struct gsmd_atcmd *cmd, void *ctx, char *resp)
 {
        struct gsmd_user *gu = ctx;
        struct gsmd_ucmd *ucmd;
-       char *comma, *opname;
-       
-       ucmd = gsmd_ucmd_fill(GSMD_OPER_MAXLEN+1, GSMD_MSG_NETWORK,
-                             GSMD_NETWORK_OPER_GET, 0);
+       const char *end, *opname;
+       int format, s;
+
+       /* Format: <mode>[,<format>,<oper>] */
+       /* In case we're not registered, return an empty string.  */
+       if (sscanf(resp, "+COPS: %*i,%i,\"%n", &format, &s) <= 0)
+               end = opname = resp;
+       else {
+               /* If the phone returned the opname in a short or numeric
+                * format, then it probably doesn't know the operator's full
+                * name or doesn't support it.  Return any information we
+                * have in this case.  */
+               if (format != 0)
+                       gsmd_log(GSMD_NOTICE, "+COPS response in a format "
+                                       " different than long alphanumeric - "
+                                       " returning as is!\n");
+               opname = resp + s;
+               end = strchr(opname, '"');
+               if (!end)
+                       return -EINVAL;
+       }
+
+       ucmd = gsmd_ucmd_fill(end - opname + 1, GSMD_MSG_NETWORK,
+                       GSMD_NETWORK_OPER_GET, 0);
        if (!ucmd)
                return -ENOMEM;
 
-       /* Format: <mode>[, <format>, <oper>] */
-       comma = strchr(resp, ',');
-       if (!comma)
-               goto out_err;
+       memcpy(ucmd->buf, opname, end - opname);
+       ucmd->buf[end - opname] = '\0';
 
-       if (atoi(comma+1) != 0) {
-               gsmd_log(GSMD_NOTICE, "COPS format !=0 not supported yet!\n");
-               goto out_err;
+       usock_cmd_enqueue(ucmd, gu);
+
+       return 0;
+}
+
+static int network_opers_parse(const char *str, struct gsmd_msg_oper out[])
+{
+       int len = 0;
+       int stat, n;
+       if (strncmp(str, "+COPS: ", 7))
+               goto final;
+       str += 7;
+
+       while (*str == '(') {
+               if (out) {
+                       out->is_last = 0;
+                       if (sscanf(str,
+                                               "(%i,\"%16[^\"]\","
+                                               "\"%8[^\"]\",\"%6[0-9]\")%n",
+                                               &stat,
+                                               out->opname_longalpha,
+                                               out->opname_shortalpha,
+                                               out->opname_num,
+                                               &n) < 4)
+                               goto final;
+                       out->stat = stat;
+               } else
+                       if (sscanf(str,
+                                               "(%*i,\"%*[^\"]\","
+                                               "\"%*[^\"]\",\"%*[0-9]\")%n",
+                                               &n) < 0)
+                               goto final;
+               if (n < 10 || str[n - 1] != ')')
+                       goto final;
+               if (str[n] == ',')
+                       n ++;
+               str += n;
+               len ++;
+               if (out)
+                       out ++;
        }
-       comma = strchr(resp, ',');
-       if (!comma || *(comma+1) != '"')
-               goto out_err;
-       opname = comma+2;
+final:
+       if (out)
+               out->is_last = 1;
+       return len;
+}
 
-       memcpy(ucmd->buf, opname, strlen(opname-1));
-       ucmd->buf[strlen(opname)] = '\0';
+static int network_opers_cb(struct gsmd_atcmd *cmd, void *ctx, char *resp)
+{
+       struct gsmd_user *gu = ctx;
+       struct gsmd_ucmd *ucmd;
+       int len;
 
+       len = network_opers_parse(resp, 0);
+
+       ucmd = gsmd_ucmd_fill(sizeof(struct gsmd_msg_oper) * (len + 1),
+                       GSMD_MSG_NETWORK, GSMD_NETWORK_OPER_LIST, 0);
+       if (!ucmd)
+               return -ENOMEM;
+
+       network_opers_parse(resp, (struct gsmd_msg_oper *) ucmd->buf);
        usock_cmd_enqueue(ucmd, gu);
 
        return 0;
-
-out_err:
-       talloc_free(ucmd);
-       return -EIO;
 }
 
 static int usock_rcv_network(struct gsmd_user *gu, struct gsmd_msg_hdr *gph, 
@@ -405,12 +467,22 @@
 {
        struct gsmd_atcmd *cmd;
        struct gsmd_voicemail *vmail = (struct gsmd_voicemail *) gph->data;
+       gsmd_oper_numeric *oper = (gsmd_oper_numeric *) gph->data;
+       char buffer[15 + sizeof(gsmd_oper_numeric)];
+       int cmdlen;
 
        switch (gph->msg_subtype) {
        case GSMD_NETWORK_REGISTER:
-               cmd = atcmd_fill("AT+COPS=0", 9+1,
-                                &null_cmd_cb, gu, 0);
+               if ((*oper)[0])
+                       cmdlen = sprintf(buffer, "AT+COPS=1,2,\"%.*s\"",
+                                       sizeof(gsmd_oper_numeric), oper);
+               else
+                       cmdlen = sprintf(buffer, "AT+COPS=0");
+               cmd = atcmd_fill(buffer, cmdlen + 1, &null_cmd_cb, gu, 0);
                break;
+       case GSMD_NETWORK_DEREGISTER:
+               cmd = atcmd_fill("AT+COPS=2", 9+1, &null_cmd_cb, gu, 0);
+               break;
        case GSMD_NETWORK_VMAIL_GET:
                cmd = atcmd_fill("AT+CSVM?", 8+1, &network_vmail_cb, gu, 0);
                break;
@@ -421,8 +493,14 @@
                cmd = atcmd_fill("AT+CSQ", 6+1, &network_sigq_cb, gu, 0);
                break;
        case GSMD_NETWORK_OPER_GET:
+               /* Set long alphanumeric format */
+               atcmd_submit(gu->gsmd, atcmd_fill("AT+COPS=3,0", 11+1,
+                                       &null_cmd_cb, gu, 0));
                cmd = atcmd_fill("AT+COPS?", 8+1, &network_oper_cb, gu, 0);
                break;
+       case GSMD_NETWORK_OPER_LIST:
+               cmd = atcmd_fill("AT+COPS=?", 9+1, &network_opers_cb, gu, 0);
+               break;
        default:
                return -EINVAL;
        }

Modified: trunk/src/target/gsm/src/libgsmd/lgsm_internals.h
===================================================================
--- trunk/src/target/gsm/src/libgsmd/lgsm_internals.h   2007-08-16 04:25:26 UTC 
(rev 2712)
+++ trunk/src/target/gsm/src/libgsmd/lgsm_internals.h   2007-08-16 05:48:59 UTC 
(rev 2713)
@@ -2,10 +2,12 @@
 #define _LGSM_INTERNALS_H
 
 #include <gsmd/usock.h>
+#include <libgsmd/misc.h>
 
 struct lgsm_handle {
        int fd;
        lgsm_msg_handler *handler[__NUM_GSMD_MSGS];
+       enum lgsm_netreg_state netreg_state;
 };
 
 int lgsm_send(struct lgsm_handle *lh, struct gsmd_msg_hdr *gmh);

Modified: trunk/src/target/gsm/src/libgsmd/libgsmd_event.c
===================================================================
--- trunk/src/target/gsm/src/libgsmd/libgsmd_event.c    2007-08-16 04:25:26 UTC 
(rev 2712)
+++ trunk/src/target/gsm/src/libgsmd/libgsmd_event.c    2007-08-16 05:48:59 UTC 
(rev 2713)
@@ -63,6 +63,12 @@
            gmh->msg_subtype >= __NUM_GSMD_EVT)
                return -EINVAL;
 
+       switch (gmh->msg_subtype) {
+       case GSMD_EVT_NETREG:
+               lh->netreg_state = aux->u.netreg.state;
+               break;
+       }
+
        if (evt_handlers[gmh->msg_subtype])
                return evt_handlers[gmh->msg_subtype](lh, gmh->msg_subtype, 
aux);
        else
@@ -71,6 +77,7 @@
 
 int lgsm_evt_init(struct lgsm_handle *lh)
 {
+       lh->netreg_state = LGSM_NETREG_ST_NOTREG;
        return lgsm_register_handler(lh, GSMD_MSG_EVENT, &evt_demux_msghandler);
 }
 

Modified: trunk/src/target/gsm/src/libgsmd/libgsmd_network.c
===================================================================
--- trunk/src/target/gsm/src/libgsmd/libgsmd_network.c  2007-08-16 04:25:26 UTC 
(rev 2712)
+++ trunk/src/target/gsm/src/libgsmd/libgsmd_network.c  2007-08-16 05:48:59 UTC 
(rev 2713)
@@ -32,18 +32,49 @@
 
 #include "lgsm_internals.h"
 
-int lgsm_netreg_register(struct lgsm_handle *lh, int oper)
+/* Get the current network registration status */
+int lgsm_get_netreg_state(struct lgsm_handle *lh,
+               enum lgsm_netreg_state *state)
 {
-       /* FIXME: implement oper selection */
-       return lgsm_send_simple(lh, GSMD_MSG_NETWORK, GSMD_NETWORK_REGISTER);
+       *state = lh->netreg_state;
 }
 
-int lgsm_signal_quality(struct lgsm_handle *lh)
+int lgsm_oper_get(struct lgsm_handle *lh)
 {
-       return lgsm_send_simple(lh, GSMD_MSG_NETWORK, GSMD_NETWORK_SIGQ_GET);
+       return lgsm_send_simple(lh, GSMD_MSG_NETWORK, GSMD_NETWORK_OPER_GET);
 }
 
-int lgsmd_operator_name(struct lgsm_handle *lh)
+int lgsm_opers_get(struct lgsm_handle *lh)
 {
-       return lgsm_send_simple(lh, GSMD_MSG_NETWORK, GSMD_NETWORK_OPER_GET);
+       return lgsm_send_simple(lh, GSMD_MSG_NETWORK, GSMD_NETWORK_OPER_LIST);
 }
+
+int lgsm_netreg_register(struct lgsm_handle *lh, gsmd_oper_numeric oper)
+{
+       struct gsmd_msg_hdr *gmh;
+
+       gmh = lgsm_gmh_fill(GSMD_MSG_NETWORK, GSMD_NETWORK_REGISTER,
+                       sizeof(gsmd_oper_numeric));
+       if (!gmh)
+               return -ENOMEM;
+
+       memcpy(gmh->data, oper, sizeof(gsmd_oper_numeric));
+
+       if (lgsm_send(lh, gmh) < gmh->len + sizeof(*gmh)) {
+               lgsm_gmh_free(gmh);
+               return -EIO;
+       }
+
+       lgsm_gmh_free(gmh);
+       return 0;
+}
+
+int lgsm_netreg_deregister(struct lgsm_handle *lh)
+{
+       return lgsm_send_simple(lh, GSMD_MSG_NETWORK, GSMD_NETWORK_DEREGISTER);
+}
+
+int lgsm_signal_quality(struct lgsm_handle *lh)
+{
+       return lgsm_send_simple(lh, GSMD_MSG_NETWORK, GSMD_NETWORK_SIGQ_GET);
+}

Modified: trunk/src/target/gsm/src/util/shell.c
===================================================================
--- trunk/src/target/gsm/src/util/shell.c       2007-08-16 04:25:26 UTC (rev 
2712)
+++ trunk/src/target/gsm/src/util/shell.c       2007-08-16 05:48:59 UTC (rev 
2713)
@@ -171,6 +171,54 @@
        }
 }
 
+/* this is the handler for responses to network/operator commands */
+static int net_msghandler(struct lgsm_handle *lh, struct gsmd_msg_hdr *gmh)
+{
+       const struct gsmd_signal_quality *sq = (struct gsmd_signal_quality *)
+               ((void *) gmh + sizeof(*gmh));
+       const char *oper = (char *) gmh + sizeof(*gmh);
+       const struct gsmd_msg_oper *opers = (struct gsmd_msg_oper *)
+               ((void *) gmh + sizeof(*gmh));
+       static const char *oper_stat[] = {
+               [GSMD_OPER_UNKNOWN] = "of unknown status",
+               [GSMD_OPER_AVAILABLE] = "available",
+               [GSMD_OPER_CURRENT] = "our current operator",
+               [GSMD_OPER_FORBIDDEN] = "forbidden",
+       };
+
+       switch (gmh->msg_subtype) {
+       case GSMD_NETWORK_SIGQ_GET:
+               if (sq->rssi == 99)
+                       printf("Signal undetectable\n");
+               else
+                       printf("Signal quality %i dBm\n", -113 + sq->rssi * 2);
+               if (sq->ber == 99)
+                       printf("Error rate undetectable\n");
+               else
+                       printf("Bit error rate %i\n", sq->ber);
+               break;
+       case GSMD_NETWORK_OPER_GET:
+               if (oper[0])
+                       printf("Our current operator is %s\n", oper);
+               else
+                       printf("No current operator\n");
+               break;
+       case GSMD_NETWORK_OPER_LIST:
+               for (; !opers->is_last; opers ++)
+                       printf("%8.*s   %16.*s,   %.*s for short, is %s\n",
+                                       sizeof(opers->opname_num),
+                                       opers->opname_num,
+                                       sizeof(opers->opname_longalpha),
+                                       opers->opname_longalpha,
+                                       sizeof(opers->opname_shortalpha),
+                                       opers->opname_shortalpha,
+                                       oper_stat[opers->stat]);
+               break;
+       default:
+               return -EINVAL;
+       }
+}
+
 static int shell_help(void)
 {
        printf( "\tA\tAnswer incoming call\n"
@@ -178,8 +226,12 @@
                "\tH\tHangup call\n"
                "\tO\tPower On\n"
                "\to\tPower Off\n"
-               "\tR\tRegister Network\n"
+               "\tr\tRegister to network\n"
+               "\tR\tRegister to given operator (R=number)\n"
                "\tU\tUnregister from netowrk\n"
+               "\tP\tPrint current operator\n"
+               "\tL\tDetect available operators\n"
+               "\tQ\tRead signal quality\n"
                "\tT\tSend DTMF Tone\n"
                "\tpd\tPB Delete (pb=index)\n"
                "\tpr\tPB Read (pr=index)\n"
@@ -208,6 +260,7 @@
        lgsm_register_handler(lgsmh, GSMD_MSG_PASSTHROUGH, &pt_msghandler);
        lgsm_register_handler(lgsmh, GSMD_MSG_PHONEBOOK, &pb_msghandler);
        lgsm_register_handler(lgsmh, GSMD_MSG_SMS, &sms_msghandler);
+       lgsm_register_handler(lgsmh, GSMD_MSG_NETWORK, &net_msghandler);
 
        fcntl(0, F_SETFD, O_NONBLOCK);
        fcntl(lgsm_fd(lgsmh), F_SETFD, O_NONBLOCK);
@@ -272,12 +325,28 @@
                        } else if (!strcmp(buf, "o")) {
                                printf("Power-Off\n");
                                lgsm_phone_power(lgsmh, 0);
-                       } else if (!strcmp(buf, "R")) {
+                       } else if (!strcmp(buf, "r")) {
                                printf("Register\n");
-                               lgsm_netreg_register(lgsmh, 0);
+                               lgsm_netreg_register(lgsmh, "\0     ");
+                       } else if (buf[0] == 'R') {
+                               printf("Register to operator\n");
+                               ptr = strchr(buf, '=');
+                               if (!ptr || strlen(ptr) < 6)
+                                       printf("No.\n");
+                               else
+                                       lgsm_netreg_register(lgsmh, ptr + 1);
                        } else if (!strcmp(buf, "U")) {
                                printf("Unregister\n");
-                               lgsm_netreg_register(lgsmh, 2);
+                               lgsm_netreg_deregister(lgsmh);
+                       } else if (!strcmp(buf, "P")) {
+                               printf("Read current opername\n");
+                               lgsm_oper_get(lgsmh);
+                       } else if (!strcmp(buf, "L")) {
+                               printf("List operators\n");
+                               lgsm_opers_get(lgsmh);
+                       } else if (!strcmp(buf, "Q")) {
+                               printf("Signal strength\n");
+                               lgsm_signal_quality(lgsmh);
                        } else if (!strcmp(buf, "q")) {
                                exit(0);
                        } else if (buf[0] == 'T') {




--- End Message ---
_______________________________________________
commitlog mailing list
[email protected]
http://lists.openmoko.org/mailman/listinfo/commitlog

Reply via email to