Changeset 2721


Ignore:
Timestamp:
08/17/07 10:30:04 (6 years ago)
Author:
laforge
Message:

From: Andrzej Zaborowski <balrog@…>
Date: Thu, 26 Jul 2007 16:00:52 +0200
Subject: [PATCH] Cell Broadcast messages enabling/disabling and notifications.

This adds GSMD_CB_SUBSCRIBE and GSMD_CB_UNSIBSCRIBE commands handling and
proper handling of th +CMTI, +CMT, +CBMI, +CBM, +CDSI, +CDS unsolicited codes.
It's also an overhaul of sms_cb.c which I first though stood for sms
*callbacks* :) rather than "cell broadcast" so all SMS and CB related code now
sits in this file. The Neo1973 modem doesn't seem to support storing CB
messages and delivery status messages into memory, so the default is now set to
output them directly to TE when they're enabled. None of the CB code is tested
on real CBs, but I think it's a good start.

Location:
trunk/src/target/gsm
Files:
8 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/target/gsm/include/gsmd/event.h

    r1282 r2721  
    1717        GSMD_EVT_SUBSCRIPTIONS  = 12,   /* To which events are we subscribed to */ 
    1818        GSMD_EVT_CIPHER         = 13,   /* Chiphering Information */ 
     19        GSMD_EVT_IN_CBM         = 14,   /* Incoming Cell Broadcat message */ 
     20        GSMD_EVT_IN_DS          = 15,   /* SMS Status Report */ 
    1921        __NUM_GSMD_EVT 
    2022}; 
  • trunk/src/target/gsm/include/gsmd/sms.h

    r2720 r2721  
    88int sms_cb_init(struct gsmd *gsmd); 
    99 
     10#define MAX_PDU_SIZE    180 
    1011int sms_pdu_make_smssubmit(char *dest, const struct gsmd_sms_submit *src); 
    1112int sms_pdu_to_msg(struct gsmd_sms_list *dst, const u_int8_t *src, 
    1213                int pdulen, int len); 
    1314 
    14 extern const char *ts0705_memtype_name[]; 
    15 int parse_memtype(char *memtype); 
     15int usock_rcv_sms(struct gsmd_user *gu, struct gsmd_msg_hdr *gph, int len); 
     16int usock_rcv_cb(struct gsmd_user *gu, struct gsmd_msg_hdr *gph, int len); 
    1617 
    1718#endif /* __GSMD__ */ 
  • trunk/src/target/gsm/include/gsmd/usock.h

    r2720 r2721  
    2323        GSMD_MSG_PIN            = 8, 
    2424        GSMD_MSG_SMS            = 9, 
     25        GSMD_MSG_CB             = 10, 
    2526        __NUM_GSMD_MSGS 
    2627}; 
     
    260261                } colp; 
    261262                struct { 
     263                        int inlined; 
    262264                        u_int8_t memtype; 
    263265                        int index; 
    264266                } sms; 
     267                struct { 
     268                        int inlined; 
     269                        u_int8_t memtype; 
     270                        int index; 
     271                } cbm; 
     272                struct { 
     273                        int inlined; 
     274                        u_int8_t memtype; 
     275                        int index; 
     276                } ds; 
    265277                struct { 
    266278                        enum gsmd_pin_type type; 
     
    290302                } cipher; 
    291303        } u; 
    292 } __attribute__((packed)); 
     304        u_int8_t data[0]; 
     305} __attribute__ ((packed)); 
    293306 
    294307/* Refer to GSM 07.05 subclause 3.5.4 */ 
     
    432445extern int usock_init(struct gsmd *g); 
    433446extern void usock_cmd_enqueue(struct gsmd_ucmd *ucmd, struct gsmd_user *gu); 
    434 extern struct gsmd_ucmd *usock_build_event(u_int8_t type, u_int8_t subtype, u_int8_t len); 
     447extern struct gsmd_ucmd *usock_build_event(u_int8_t type, u_int8_t subtype, u_int16_t len); 
    435448extern int usock_evt_send(struct gsmd *gsmd, struct gsmd_ucmd *ucmd, u_int32_t evt); 
     449extern struct gsmd_ucmd *gsmd_ucmd_fill(int len, u_int8_t msg_type, 
     450                u_int8_t msg_subtype, u_int16_t id); 
    436451 
    437452#endif /* __GSMD__ */ 
  • trunk/src/target/gsm/include/libgsmd/sms.h

    r2720 r2721  
    110110extern int unpacking_UCS2_82(char *src, char *dest); 
    111111 
     112/* This phone wants to receive Cell Broadcast Messages */ 
     113extern int lgsm_cb_subscribe(struct lgsm_handle *lh); 
     114 
     115/* This phone wants no more Cell Broadcast Messages */ 
     116extern int lgsm_cb_unsubscribe(struct lgsm_handle *lh); 
     117 
    112118#endif 
    113  
  • trunk/src/target/gsm/src/gsmd/sms_cb.c

    r2720 r2721  
    1919 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 
    2020 * 
    21  */  
     21 */ 
    2222 
    2323#include <stdlib.h> 
     
    3838#include <gsmd/usock.h> 
    3939#include <gsmd/unsolicited.h> 
    40  
    41 const char *ts0705_memtype_name[] = { 
     40#include <gsmd/sms.h> 
     41 
     42static const char *ts0705_memtype_name[] = { 
    4243        [GSM0705_MEMTYPE_NONE]          = "NONE", 
    4344        [GSM0705_MEMTYPE_BROADCAST]     = "BM", 
     
    4950}; 
    5051 
    51 inline int parse_memtype(char *memtype) 
     52static inline int parse_memtype(char *memtype) 
    5253{ 
    5354        int i; 
     
    6162} 
    6263 
     64static int sms_list_cb(struct gsmd_atcmd *cmd, void *ctx, char *resp) 
     65{ 
     66        struct gsmd_user *gu = ctx; 
     67        struct gsmd_ucmd *ucmd; 
     68        struct gsmd_sms_list msg; 
     69        int i, idx, stat, len, cr; 
     70        u_int8_t pdu[MAX_PDU_SIZE]; 
     71 
     72        if (cmd->ret && cmd->ret != -255) 
     73                return 0; 
     74 
     75        /* FIXME: TEXT mode */ 
     76        if ( 
     77                        sscanf(resp, "+CMGL: %i,%i,,%i\n%n", 
     78                                &idx, &stat, &len, &cr) < 3 && 
     79                        sscanf(resp, "+CMGL: %i,%i,\"%*[^\"]\",%i\n%n", 
     80                                &idx, &stat, &len, &cr) < 3) 
     81                return -EINVAL; 
     82        if (len > 164) 
     83                return -EINVAL; 
     84 
     85        msg.index = idx; 
     86        msg.stat = stat; 
     87        msg.is_last = (cmd->ret == 0); 
     88        for (i = 0; resp[cr] >= '0' && resp[cr + 1] >= '0' && 
     89                        i < MAX_PDU_SIZE; i ++) { 
     90                if (sscanf(resp + cr, "%2hhX", &pdu[i]) < 1) { 
     91                        gsmd_log(GSMD_DEBUG, "malformed input (%i)\n", i); 
     92                        return -EINVAL; 
     93                } 
     94                cr += 2; 
     95        } 
     96        if (sms_pdu_to_msg(&msg, pdu, len, i)) { 
     97                gsmd_log(GSMD_DEBUG, "malformed PDU\n"); 
     98                return -EINVAL; 
     99        } 
     100 
     101        ucmd = gsmd_ucmd_fill(sizeof(msg), GSMD_MSG_SMS, 
     102                        GSMD_SMS_LIST, cmd->id); 
     103        if (!ucmd) 
     104                return -ENOMEM; 
     105        memcpy(ucmd->buf, &msg, sizeof(msg)); 
     106 
     107        usock_cmd_enqueue(ucmd, gu); 
     108 
     109        return 0; 
     110} 
     111 
     112static int sms_read_cb(struct gsmd_atcmd *cmd, void *ctx, char *resp) 
     113{ 
     114        struct gsmd_user *gu = ctx; 
     115        struct gsmd_ucmd *ucmd; 
     116        struct gsmd_sms_list msg; 
     117        int i, stat, len, cr; 
     118        u_int8_t pdu[MAX_PDU_SIZE]; 
     119 
     120        if (cmd->ret) 
     121                return 0; 
     122 
     123        /* FIXME: TEXT mode */ 
     124        if ( 
     125                        sscanf(resp, "+CMGR: %i,,%i\n%n", 
     126                                &stat, &len, &cr) < 2 && 
     127                        sscanf(resp, "+CMGR: %i,%*i,%i\n%n", 
     128                                &stat, &len, &cr) < 2) 
     129                return -EINVAL; 
     130        if (len > 164) 
     131                return -EINVAL; 
     132 
     133        msg.index = 0; 
     134        msg.stat = stat; 
     135        msg.is_last = 1; 
     136        for (i = 0; resp[cr] >= '0' && resp[cr + 1] >= '0' && 
     137                        i < MAX_PDU_SIZE; i ++) { 
     138                if (sscanf(resp + cr, "%2hhX", &pdu[i]) < 1) { 
     139                        gsmd_log(GSMD_DEBUG, "malformed input (%i)\n", i); 
     140                        return -EINVAL; 
     141                } 
     142                cr += 2; 
     143        } 
     144        if (sms_pdu_to_msg(&msg, pdu, len, i)) { 
     145                gsmd_log(GSMD_DEBUG, "malformed PDU\n"); 
     146                return -EINVAL; 
     147        } 
     148 
     149        ucmd = gsmd_ucmd_fill(sizeof(msg), GSMD_MSG_SMS, 
     150                        GSMD_SMS_READ, cmd->id); 
     151        if (!ucmd) 
     152                return -ENOMEM; 
     153        memcpy(ucmd->buf, &msg, sizeof(msg)); 
     154 
     155        usock_cmd_enqueue(ucmd, gu); 
     156 
     157        return 0; 
     158} 
     159 
     160static int sms_send_cb(struct gsmd_atcmd *cmd, void *ctx, char *resp) 
     161{ 
     162        struct gsmd_user *gu = ctx; 
     163        struct gsmd_ucmd *ucmd; 
     164        int msgref; 
     165 
     166        if (cmd->ret == 0 || cmd->ret == -255) { 
     167                if (sscanf(resp, "+CMGS: %i", &msgref) < 1) 
     168                        return -EINVAL; 
     169        } else 
     170                msgref = -cmd->ret; 
     171 
     172        ucmd = gsmd_ucmd_fill(sizeof(int), GSMD_MSG_SMS, 
     173                        GSMD_SMS_SEND, cmd->id); 
     174        if (!ucmd) 
     175                return -ENOMEM; 
     176        *(int *) ucmd->buf = msgref; 
     177 
     178        usock_cmd_enqueue(ucmd, gu); 
     179 
     180        return 0; 
     181} 
     182 
     183static int sms_write_cb(struct gsmd_atcmd *cmd, void *ctx, char *resp) 
     184{ 
     185        struct gsmd_user *gu = ctx; 
     186        struct gsmd_ucmd *ucmd; 
     187        int result; 
     188 
     189        if (cmd->ret == 0) { 
     190                if (sscanf(resp, "+CMGW: %i", &result) < 1) 
     191                        return -EINVAL; 
     192        } else 
     193                result = -cmd->ret; 
     194 
     195        ucmd = gsmd_ucmd_fill(sizeof(int), GSMD_MSG_SMS, 
     196                        GSMD_SMS_WRITE, cmd->id); 
     197        if (!ucmd) 
     198                return -ENOMEM; 
     199        *(int *) ucmd->buf = result; 
     200 
     201        usock_cmd_enqueue(ucmd, gu); 
     202 
     203        return 0; 
     204} 
     205 
     206static int sms_delete_cb(struct gsmd_atcmd *cmd, void *ctx, char *resp) 
     207{ 
     208        struct gsmd_user *gu = ctx; 
     209        struct gsmd_ucmd *ucmd; 
     210        int *result; 
     211 
     212        ucmd = gsmd_ucmd_fill(sizeof(int), GSMD_MSG_SMS, 
     213                        GSMD_SMS_DELETE, cmd->id); 
     214        if (!ucmd) 
     215                return -ENOMEM; 
     216 
     217        result = (int *) ucmd->buf; 
     218        *result = cmd->ret; 
     219 
     220        usock_cmd_enqueue(ucmd, gu); 
     221 
     222        return 0; 
     223} 
     224 
     225static int usock_cpms_cb(struct gsmd_atcmd *cmd, void *ctx, char *resp) 
     226{ 
     227        struct gsmd_user *gu = ctx; 
     228        struct gsmd_ucmd *ucmd = ucmd_alloc(sizeof(struct gsmd_sms_storage)); 
     229        struct gsmd_sms_storage *gss = (typeof(gss)) ucmd->buf; 
     230        char buf[3][3]; 
     231 
     232        DEBUGP("entering(cmd=%p, gu=%p)\n", cmd, gu); 
     233 
     234        if (!ucmd) 
     235                return -ENOMEM; 
     236 
     237        ucmd->hdr.version = GSMD_PROTO_VERSION; 
     238        ucmd->hdr.msg_type = GSMD_MSG_SMS; 
     239        ucmd->hdr.msg_subtype = GSMD_SMS_GET_MSG_STORAGE; 
     240        ucmd->hdr.len = sizeof(struct gsmd_sms_storage); 
     241        ucmd->hdr.id = cmd->id; 
     242 
     243        if (sscanf(resp, "+CPMS: \"%2[A-Z]\",%hi,%hi," 
     244                                "\"%2[A-Z]\",%hi,%hi,\"%2[A-Z]\",%hi,%hi", 
     245                                buf[0], &gss->mem[0].used, &gss->mem[0].total, 
     246                                buf[1], &gss->mem[1].used, &gss->mem[1].total, 
     247                                buf[2], &gss->mem[2].used, &gss->mem[2].total) 
     248                        < 9) { 
     249                talloc_free(ucmd); 
     250                return -EINVAL; 
     251        } 
     252 
     253        gss->mem[0].memtype = parse_memtype(buf[0]); 
     254        gss->mem[1].memtype = parse_memtype(buf[1]); 
     255        gss->mem[2].memtype = parse_memtype(buf[2]); 
     256 
     257        usock_cmd_enqueue(ucmd, gu); 
     258 
     259        return 0; 
     260} 
     261 
     262static int usock_get_smsc_cb(struct gsmd_atcmd *cmd, void *ctx, char *resp) 
     263{ 
     264        struct gsmd_user *gu = ctx; 
     265        struct gsmd_ucmd *ucmd; 
     266        struct gsmd_addr *ga; 
     267 
     268        ucmd = gsmd_ucmd_fill(sizeof(struct gsmd_addr), GSMD_MSG_SMS, 
     269                        GSMD_SMS_GET_SERVICE_CENTRE, cmd->id); 
     270        if (!ucmd) 
     271                return -ENOMEM; 
     272 
     273        ga = (struct gsmd_addr *) ucmd->buf; 
     274        if (sscanf(resp, "+CSCA: \"%31[^\"]\",%hhi", 
     275                                ga->number, &ga->type) < 2) { 
     276                talloc_free(ucmd); 
     277                return -EINVAL; 
     278        } 
     279 
     280        usock_cmd_enqueue(ucmd, gu); 
     281        return 0; 
     282} 
     283 
     284static const char *gsmd_cmgl_stat[] = { 
     285        "REC UNREAD", "REC READ", "STO UNSENT", "STO SENT", "ALL", 
     286}; 
     287 
     288/* main unix socket Short Message receiver */ 
     289int usock_rcv_sms(struct gsmd_user *gu, struct gsmd_msg_hdr *gph, int len) 
     290{ 
     291        /* FIXME: TEXT mode support!!  */ 
     292        struct gsmd_atcmd *cmd = NULL; 
     293        struct gsmd_sms_delete *gsd; 
     294        struct gsmd_sms_submit *gss; 
     295        struct gsmd_sms_write *gsw; 
     296        struct gsmd_addr *ga; 
     297        enum ts0705_mem_type *storage; 
     298        int *stat, *index; 
     299        int atcmd_len; 
     300        char buf[1024]; 
     301 
     302        switch (gph->msg_subtype) { 
     303        case GSMD_SMS_LIST: 
     304                if(len < sizeof(*gph) + sizeof(int)) 
     305                        return -EINVAL; 
     306                stat = (int *) ((void *)gph + sizeof(*gph)); 
     307                if (*stat < 0 || *stat > 4) 
     308                        return -EINVAL; 
     309 
     310                if (gu->gsmd->flags & GSMD_FLAG_SMS_FMT_TEXT) 
     311                        atcmd_len = sprintf(buf, "AT+CMGL=\"%s\"", 
     312                                        gsmd_cmgl_stat[*stat]); 
     313                else 
     314                        atcmd_len = sprintf(buf, "AT+CMGL=%i", *stat); 
     315 
     316                cmd = atcmd_fill(buf, atcmd_len + 1, 
     317                                &sms_list_cb, gu, gph->id); 
     318                break; 
     319 
     320        case GSMD_SMS_READ: 
     321                if(len < sizeof(*gph) + sizeof(int)) 
     322                        return -EINVAL; 
     323                index = (int *) ((void *)gph + sizeof(*gph)); 
     324 
     325                atcmd_len = sprintf(buf, "AT+CMGR=%i", *index); 
     326 
     327                cmd = atcmd_fill(buf, atcmd_len + 1, 
     328                                &sms_read_cb, gu, gph->id); 
     329                break; 
     330 
     331        case GSMD_SMS_SEND: 
     332                if (len < sizeof(*gph) + sizeof(*gss)) 
     333                        return -EINVAL; 
     334                gss = (struct gsmd_sms_submit *) ((void *) gph + sizeof(*gph)); 
     335 
     336                if (gu->gsmd->flags & GSMD_FLAG_SMS_FMT_TEXT) { 
     337                        atcmd_len = sprintf(buf, "AT+CMGS=\"%s\"\n%.*s", 
     338                                        gss->addr.number, 
     339                                        gss->payload.length, 
     340                                        gss->payload.data);     /* FIXME */ 
     341                } else { 
     342                        atcmd_len = sprintf(buf, "AT+CMGS=%i\n", 
     343                                        sms_pdu_make_smssubmit(NULL, gss) - 1); 
     344                        atcmd_len += sms_pdu_make_smssubmit(buf + atcmd_len, 
     345                                        gss) * 2; 
     346                } 
     347                buf[atcmd_len ++] = 26; /* ^Z ends the message */ 
     348                buf[atcmd_len ++] = 0; 
     349 
     350                cmd = atcmd_fill(buf, atcmd_len, &sms_send_cb, gu, gph->id); 
     351                break; 
     352 
     353        case GSMD_SMS_WRITE: 
     354                if (len < sizeof(*gph) + sizeof(*gsw)) 
     355                        return -EINVAL; 
     356                gsw = (struct gsmd_sms_write *) ((void *) gph + sizeof(*gph)); 
     357                if (gsw->stat > 4) 
     358                        return -EINVAL; 
     359 
     360                if (gu->gsmd->flags & GSMD_FLAG_SMS_FMT_TEXT) { 
     361                        atcmd_len = sprintf(buf, "AT+CMGW=\"%s\"\n%.*s", 
     362                                        gsw->sms.addr.number, 
     363                                        gsw->sms.payload.length, 
     364                                        gsw->sms.payload.data); /* FIXME */ 
     365                } else { 
     366                        atcmd_len = sprintf(buf, "AT+CMGW=%i,%i\n", 
     367                                        sms_pdu_make_smssubmit(NULL, 
     368                                                &gsw->sms) - 1, gsw->stat); 
     369                        atcmd_len += sms_pdu_make_smssubmit(buf + atcmd_len, 
     370                                        &gsw->sms) * 2; 
     371                } 
     372                buf[atcmd_len ++] = 26; /* ^Z ends the message */ 
     373                buf[atcmd_len ++] = 0; 
     374 
     375                cmd = atcmd_fill(buf, atcmd_len, &sms_write_cb, gu, gph->id); 
     376                break; 
     377 
     378        case GSMD_SMS_DELETE: 
     379                if(len < sizeof(*gph) + sizeof(*gsd)) 
     380                        return -EINVAL; 
     381                gsd = (struct gsmd_sms_delete *) ((void *)gph + sizeof(*gph)); 
     382 
     383                atcmd_len = sprintf(buf, "AT+CMGD=%d,%d", 
     384                                gsd->index, gsd->delflg); 
     385 
     386                cmd = atcmd_fill(buf, atcmd_len + 1, 
     387                                &sms_delete_cb, gu, gph->id); 
     388                break; 
     389 
     390        case GSMD_SMS_GET_MSG_STORAGE: 
     391                cmd = atcmd_fill("AT+CPMS?", 8 + 1, usock_cpms_cb, gu, 0); 
     392                break; 
     393 
     394        case GSMD_SMS_SET_MSG_STORAGE: 
     395                if (len < sizeof(*gph) + 3 * sizeof(enum ts0705_mem_type)) 
     396                        return -EINVAL; 
     397                storage = (enum ts0705_mem_type *) 
     398                        ((void *) gph + sizeof(*gph)); 
     399                atcmd_len = sprintf(buf, "AT+CPMS=\"%s\",\"%s\",\"%s\"", 
     400                                ts0705_memtype_name[storage[0]], 
     401                                ts0705_memtype_name[storage[1]], 
     402                                ts0705_memtype_name[storage[2]]); 
     403                cmd = atcmd_fill(buf, atcmd_len + 1, NULL, gu, gph->id); 
     404                break; 
     405 
     406        case GSMD_SMS_GET_SERVICE_CENTRE: 
     407                cmd = atcmd_fill("AT+CSCA?", 8 + 1, &usock_get_smsc_cb, gu, 0); 
     408                break; 
     409 
     410        case GSMD_SMS_SET_SERVICE_CENTRE: 
     411                if (len < sizeof(*gph) + sizeof(struct gsmd_addr)) 
     412                        return -EINVAL; 
     413                ga = (struct gsmd_addr *) ((void *) gph + sizeof(*gph)); 
     414                atcmd_len = sprintf(buf, "AT+CSCA=\"%s\",%i", 
     415                                ga->number, ga->type); 
     416                cmd = atcmd_fill(buf, atcmd_len + 1, NULL, gu, gph->id); 
     417                break; 
     418 
     419        default: 
     420                return -ENOSYS; 
     421        } 
     422 
     423        if (!cmd) 
     424                return -ENOMEM; 
     425 
     426        gsmd_log(GSMD_DEBUG, "%s\n", cmd ? cmd->buf : 0); 
     427        return atcmd_submit(gu->gsmd, cmd); 
     428} 
     429 
    63430/* main unix socket Cell Broadcast receiver */ 
    64 static int usock_rcv_cb(struct gsmd_user *gu, struct gsmd_msg_hdr *gph, 
    65                         int len) 
    66 { 
     431int usock_rcv_cb(struct gsmd_user *gu, struct gsmd_msg_hdr *gph, int len) 
     432{ 
     433        struct gsmd_atcmd *cmd; 
     434 
    67435        switch (gph->msg_subtype) { 
    68436        case GSMD_CB_SUBSCRIBE: 
     437                cmd = atcmd_fill("AT+CSCB=1", 9 + 1, NULL, gu->gsmd, 0); 
    69438                break; 
    70439        case GSMD_CB_UNSUBSCRIBE: 
    71                 break; 
    72         } 
    73  
    74         return -ENOSYS; 
     440                cmd = atcmd_fill("AT+CSCB=0", 9 + 1, NULL, gu->gsmd, 0); 
     441                break; 
     442        default: 
     443                return -ENOSYS; 
     444        } 
     445 
     446        if (!cmd) 
     447                return -ENOMEM; 
     448 
     449        return atcmd_submit(gu->gsmd, cmd); 
    75450} 
    76451 
    77452/* Unsolicited messages related to SMS / CB */ 
    78 static int cmti_parse(char *buf, int len, const char *param, 
    79                       struct gsmd *gsmd) 
     453static int cmti_parse(char *buf, int len, const char *param, struct gsmd *gsmd) 
    80454{ 
    81455        char memstr[3]; 
    82         struct gsmd_ucmd *ucmd = ucmd_alloc(sizeof(struct gsmd_evt_auxdata)); 
    83         struct gsmd_evt_auxdata *aux = (struct gsmd_evt_auxdata *) ucmd->buf; 
    84  
    85         if (!ucmd) 
    86                 return -ENOMEM; 
    87  
    88         ucmd->hdr.version = GSMD_PROTO_VERSION; 
    89         ucmd->hdr.msg_type = GSMD_MSG_EVENT; 
    90         ucmd->hdr.msg_subtype = GSMD_EVT_IN_SMS; 
    91         ucmd->hdr.len = sizeof(*aux); 
    92  
     456        struct gsmd_evt_auxdata *aux; 
     457        struct gsmd_ucmd *ucmd = usock_build_event(GSMD_MSG_EVENT, 
     458                        GSMD_EVT_IN_SMS, sizeof(struct gsmd_evt_auxdata)); 
     459 
     460        if (!ucmd) 
     461                return -ENOMEM; 
     462 
     463        aux = (struct gsmd_evt_auxdata *) ucmd->buf; 
    93464        if (sscanf(param, "\"%2[A-Z]\",%i", memstr, &aux->u.sms.index) < 2) { 
    94465                talloc_free(ucmd); 
     
    96467        } 
    97468 
     469        aux->u.sms.inlined = 0; 
    98470        aux->u.sms.memtype = parse_memtype(memstr); 
    99471 
     
    101473} 
    102474 
    103 static int cmt_parse(char *buf, int len, const char *param, 
    104                      struct gsmd *gsmd) 
     475static int cmt_parse(char *buf, int len, const char *param, struct gsmd *gsmd) 
    105476{ 
    106477        /* TODO: TEXT mode */ 
    107         u_int8_t pdu[180]; 
     478        u_int8_t pdu[MAX_PDU_SIZE]; 
    108479        const char *comma = strchr(param, ','); 
    109480        char *cr; 
    110481        int i; 
    111         struct gsmd_sms_list msg; 
    112  
    113         if (!comma) 
    114                 return -EINVAL; 
     482        struct gsmd_evt_auxdata *aux; 
     483        struct gsmd_sms_list *msg; 
     484        struct gsmd_ucmd *ucmd = usock_build_event(GSMD_MSG_EVENT, 
     485                        GSMD_EVT_IN_SMS, sizeof(struct gsmd_evt_auxdata) + 
     486                        sizeof(struct gsmd_sms_list)); 
     487 
     488        if (!ucmd) 
     489                return -ENOMEM; 
     490 
     491        aux = (struct gsmd_evt_auxdata *) ucmd->buf; 
     492        msg = (struct gsmd_sms_list *) aux->data; 
     493 
     494        if (!comma) { 
     495                talloc_free(ucmd); 
     496                return -EINVAL; 
     497        } 
    115498        len = strtoul(comma + 1, &cr, 10); 
    116         if (cr[0] != '\n') 
    117                 return -EINVAL; 
     499        if (cr[0] != '\n') { 
     500                talloc_free(ucmd); 
     501                return -EINVAL; 
     502        } 
    118503 
    119504        cr ++; 
    120         for (i = 0; cr[0] >= '0' && cr[1] >= '0' && i < 180; i ++) { 
     505        for (i = 0; cr[0] >= '0' && cr[1] >= '0' && i < MAX_PDU_SIZE; i ++) { 
    121506                if (sscanf(cr, "%2hhX", &pdu[i]) < 1) { 
    122507                        gsmd_log(GSMD_DEBUG, "malformed input (%i)\n", i); 
     508                        talloc_free(ucmd); 
    123509                        return -EINVAL; 
    124510                } 
    125511                cr += 2; 
    126512        } 
    127         if (sms_pdu_to_msg(&msg, pdu, len, i)) { 
     513 
     514        aux->u.sms.inlined = 1; 
     515        if (sms_pdu_to_msg(msg, pdu, len, i)) { 
    128516                gsmd_log(GSMD_DEBUG, "malformed PDU\n"); 
    129                 return -EINVAL; 
    130         } 
    131  
    132         /* FIXME: generate some kind of event */ 
    133         return -ENOSYS; 
    134 } 
    135  
    136 static int cbmi_parse(char *buf, int len, const char *param, 
    137                       struct gsmd *gsmd) 
     517                talloc_free(ucmd); 
     518                return -EINVAL; 
     519        } 
     520 
     521        return usock_evt_send(gsmd, ucmd, GSMD_EVT_IN_SMS); 
     522} 
     523 
     524static int cbmi_parse(char *buf, int len, const char *param, struct gsmd *gsmd) 
    138525{ 
    139526        char memstr[3]; 
    140         int memtype, index; 
    141  
    142         if (sscanf(param, "\"%2[A-Z]\",%i", memstr, &index) < 2) 
    143                 return -EINVAL; 
    144  
    145         memtype = parse_memtype(memstr); 
    146         /* FIXME: generate some kind of event */ 
    147         return -ENOSYS; 
    148 } 
    149  
    150 static int cbm_parse(char *buf, int len, const char *param, 
    151                      struct gsmd *gsmd) 
     527        struct gsmd_evt_auxdata *aux; 
     528        struct gsmd_ucmd *ucmd = usock_build_event(GSMD_MSG_EVENT, 
     529                        GSMD_EVT_IN_CBM, sizeof(struct gsmd_evt_auxdata)); 
     530 
     531        if (!ucmd) 
     532                return -ENOMEM; 
     533 
     534        ucmd->hdr.version = GSMD_PROTO_VERSION; 
     535        ucmd->hdr.msg_type = GSMD_MSG_EVENT; 
     536        ucmd->hdr.msg_subtype = GSMD_EVT_IN_CBM; 
     537        ucmd->hdr.len = sizeof(*aux); 
     538 
     539        aux = (struct gsmd_evt_auxdata *) ucmd->buf; 
     540        if (sscanf(param, "\"%2[A-Z]\",%i", memstr, &aux->u.cbm.index) < 2) { 
     541                talloc_free(ucmd); 
     542                return -EINVAL; 
     543        } 
     544 
     545        aux->u.cbm.inlined = 0; 
     546        aux->u.cbm.memtype = parse_memtype(memstr); 
     547 
     548        return usock_evt_send(gsmd, ucmd, GSMD_EVT_IN_CBM); 
     549} 
     550 
     551static int cbm_parse(char *buf, int len, const char *param, struct gsmd *gsmd) 
    152552{ 
    153553        /* TODO: TEXT mode */ 
    154         u_int8_t pdu[180]; 
     554        u_int8_t pdu[MAX_PDU_SIZE]; 
    155555        char *cr; 
    156556        int i; 
    157         struct gsmd_sms_list msg; 
     557        struct gsmd_evt_auxdata *aux; 
     558        struct gsmd_sms_list *msg; 
     559        struct gsmd_ucmd *ucmd = usock_build_event(GSMD_MSG_EVENT, 
     560                        GSMD_EVT_IN_CBM, sizeof(struct gsmd_evt_auxdata) + 
     561                        sizeof(struct gsmd_sms_list)); 
     562 
     563        if (!ucmd) 
     564                return -ENOMEM; 
     565 
     566        aux = (struct gsmd_evt_auxdata *) ucmd->buf; 
     567        msg = (struct gsmd_sms_list *) aux->data; 
    158568 
    159569        len = strtoul(param, &cr, 10); 
     
    162572 
    163573        cr ++; 
    164         for (i = 0; cr[0] >= '0' && cr[1] >= '0' && i < 180; i ++) { 
     574        for (i = 0; cr[0] >= '0' && cr[1] >= '0' && i < MAX_PDU_SIZE; i ++) { 
    165575                if (sscanf(cr, "%2hhX", &pdu[i]) < 1) { 
    166576                        gsmd_log(GSMD_DEBUG, "malformed input (%i)\n", i); 
     577                        talloc_free(ucmd); 
    167578                        return -EINVAL; 
    168579                } 
    169580                cr += 2; 
    170581        } 
    171         if (sms_pdu_to_msg(&msg, pdu, len, i)) { 
     582 
     583        aux->u.cbm.inlined = 1; 
     584        if (sms_pdu_to_msg(msg, pdu, len, i)) { 
    172585                gsmd_log(GSMD_DEBUG, "malformed PDU\n"); 
    173                 return -EINVAL; 
    174         } 
    175  
    176         /* FIXME: generate some kind of event */ 
    177         return -ENOSYS; 
    178 } 
    179  
    180 static int cdsi_parse(char *buf, int len, const char *param, 
    181                       struct gsmd *gsmd) 
     586                talloc_free(ucmd); 
     587                return -EINVAL; 
     588        } 
     589 
     590        return usock_evt_send(gsmd, ucmd, GSMD_EVT_IN_CBM); 
     591} 
     592 
     593static int cdsi_parse(char *buf, int len, const char *param, struct gsmd *gsmd) 
    182594{ 
    183595        char memstr[3]; 
    184         int memtype, index; 
    185  
    186         if (sscanf(param, "\"%2[A-Z]\",%i", memstr, &index) < 2) 
    187                 return -EINVAL; 
    188  
    189         memtype = parse_memtype(memstr); 
    190         /* FIXME: generate some kind of event */ 
    191         return -ENOSYS; 
    192 } 
    193  
    194 static int cds_parse(char *buf, int len, const char *param, 
    195                      struct gsmd *gsmd) 
     596        struct gsmd_evt_auxdata *aux; 
     597        struct gsmd_ucmd *ucmd = usock_build_event(GSMD_MSG_EVENT, 
     598                        GSMD_EVT_IN_DS, sizeof(struct gsmd_evt_auxdata)); 
     599 
     600        if (!ucmd) 
     601                return -ENOMEM; 
     602 
     603        aux = (struct gsmd_evt_auxdata *) ucmd->buf; 
     604        if (sscanf(param, "\"%2[A-Z]\",%i", memstr, &aux->u.ds.index) < 2) { 
     605                talloc_free(ucmd); 
     606                return -EINVAL; 
     607        } 
     608 
     609        aux->u.ds.inlined = 0; 
     610        aux->u.ds.memtype = parse_memtype(memstr); 
     611 
     612        return usock_evt_send(gsmd, ucmd, GSMD_EVT_IN_DS); 
     613} 
     614 
     615static int cds_parse(char *buf, int len, const char *param, struct gsmd *gsmd) 
    196616{ 
    197617        /* TODO: TEXT mode */ 
    198         u_int8_t pdu[180]; 
     618        u_int8_t pdu[MAX_PDU_SIZE]; 
    199619        char *cr; 
    200620        int i; 
    201         struct gsmd_sms_list msg; 
     621        struct gsmd_evt_auxdata *aux; 
     622        struct gsmd_sms_list *msg; 
     623        struct gsmd_ucmd *ucmd = usock_build_event(GSMD_MSG_EVENT, 
     624                        GSMD_EVT_IN_DS, sizeof(struct gsmd_evt_auxdata) + 
     625                        sizeof(struct gsmd_sms_list)); 
     626 
     627        if (!ucmd) 
     628                return -ENOMEM; 
     629 
     630        aux = (struct gsmd_evt_auxdata *) ucmd->buf; 
     631        msg = (struct gsmd_sms_list *) aux->data; 
    202632 
    203633        len = strtoul(param, &cr, 10); 
     
    206636 
    207637        cr ++; 
    208         for (i = 0; cr[0] >= '0' && cr[1] >= '0' && i < 180; i ++) { 
     638        for (i = 0; cr[0] >= '0' && cr[1] >= '0' && i < MAX_PDU_SIZE; i ++) { 
    209639                if (sscanf(cr, "%2hhX", &pdu[i]) < 1) { 
    210640                        gsmd_log(GSMD_DEBUG, "malformed input (%i)\n", i); 
     641                        talloc_free(ucmd); 
    211642                        return -EINVAL; 
    212643                } 
    213644                cr += 2; 
    214645        } 
    215         if (sms_pdu_to_msg(&msg, pdu, len, i)) { 
     646 
     647        aux->u.ds.inlined = 1; 
     648        if (sms_pdu_to_msg(msg, pdu, len, i)) { 
    216649                gsmd_log(GSMD_DEBUG, "malformed PDU\n"); 
    217                 return -EINVAL; 
    218         } 
    219  
    220         /* FIXME: generate some kind of event */ 
    221         return -ENOSYS; 
     650                talloc_free(ucmd); 
     651                return -EINVAL; 
     652        } 
     653 
     654        return usock_evt_send(gsmd, ucmd, GSMD_EVT_IN_DS); 
    222655} 
    223656 
     
    244677        atcmd_submit(gsmd, atcmd); 
    245678 
    246         /* Store and notify */ 
    247         atcmd = atcmd_fill("AT+CNMI=1,1,1", 13 + 1, NULL, gsmd, 0); 
     679        /* 
     680         * Set the New Message Indications properties to values that are 
     681         * likely supported.  We will get a: 
     682         * +CMTI on a new incoming SMS, 
     683         * +CBM on a new incoming CB, 
     684         * +CDS on an SMS status report. 
     685         * 
     686         * FIXME: ask for supported +CNMI values first. 
     687         */ 
     688        atcmd = atcmd_fill("AT+CNMI=2,1,2,1,0", 17 + 1, NULL, gsmd, 0); 
    248689        if (!atcmd) 
    249690                return -ENOMEM; 
  • trunk/src/target/gsm/src/gsmd/unsolicited.c

    r2712 r2721  
    3737#include <gsmd/talloc.h> 
    3838 
    39 struct gsmd_ucmd *usock_build_event(u_int8_t type, u_int8_t subtype, u_int8_t len) 
     39struct gsmd_ucmd *usock_build_event(u_int8_t type, u_int8_t subtype, u_int16_t len) 
    4040{ 
    4141        struct gsmd_ucmd *ucmd = ucmd_alloc(len); 
  • trunk/src/target/gsm/src/gsmd/usock.c

    r2720 r2721  
    320320} 
    321321 
    322 static struct gsmd_ucmd *gsmd_ucmd_fill(int len, u_int8_t msg_type, u_int8_t msg_subtype, 
    323                                         u_int16_t id) 
     322struct gsmd_ucmd *gsmd_ucmd_fill(int len, u_int8_t msg_type, 
     323                u_int8_t msg_subtype, u_int16_t id) 
    324324{ 
    325325        struct gsmd_ucmd *ucmd; 
     
    512512} 
    513513 
     514#if 0 
    514515static int sms_list_cb(struct gsmd_atcmd *cmd, void *ctx, char *resp) 
    515516{ 
     
    877878        return atcmd_submit(gu->gsmd, cmd); 
    878879} 
     880#endif 
    879881 
    880882#if 0 
     
    11281130        [GSMD_MSG_NETWORK]      = &usock_rcv_network, 
    11291131        [GSMD_MSG_SMS]          = &usock_rcv_sms, 
     1132        [GSMD_MSG_CB]           = &usock_rcv_cb, 
    11301133        //[GSMD_MSG_PHONEBOOK]  = &usock_rcv_phonebook, 
    11311134}; 
  • trunk/src/target/gsm/src/libgsmd/libgsmd_sms.c

    r2720 r2721  
    319319        return 0; 
    320320} 
     321 
     322int lgsm_cb_subscribe(struct lgsm_handle *lh) 
     323{ 
     324        return lgsm_send_simple(lh, GSMD_MSG_CB, GSMD_CB_SUBSCRIBE); 
     325} 
     326 
     327int lgsm_cb_unsubscribe(struct lgsm_handle *lh) 
     328{ 
     329        return lgsm_send_simple(lh, GSMD_MSG_CB, GSMD_CB_UNSUBSCRIBE); 
     330} 
Note: See TracChangeset for help on using the changeset viewer.