summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorlaforge <laforge@99fdad57-331a-0410-800a-d7fa5415bdb3>2007-08-17 08:29:08 +0000
committerlaforge <laforge@99fdad57-331a-0410-800a-d7fa5415bdb3>2007-08-17 08:29:08 +0000
commit348c9af2fce8d0d53341d9861494b5c13f9796f1 (patch)
treedbd6253c09e77e9c72ff082f2284ed0b6ba9165b
parent1c4526b52edc7c245cb76ba801bbbe9da1a3b5ae (diff)
From: Andrzej Zaborowski <balrog@zabor.org>
Date: Thu, 26 Jul 2007 00:32:38 +0200 Subject: [PATCH] SMSC and Preferred Storage operations. This adds setting and retrieval of SMS storage stats (memory type, used entries, all entries), and of the default service centre (SMSC) number for outgoing messages. The operation of setting a new SMSC number is untested because my SIM doesn't seem to allow this (that or I did something wrong). New "libgmsd-tool -m shell" commands for testing are also added. Other changes in this patch: * The third, optional, parameter to +CMGL: is a string, not an integer as I wrongly assumed earlier, this is now corrected. * Rename libgsmd API functions starting with lgsmd_.. to lgsm_.. for consistency with all other identifiers. * Move lgsm_send_simple() to libgsmd.c and add a prototype in lgsm_internals.h, this eliminates some compile-time warnings. git-svn-id: http://svn.openmoko.org/trunk/src/target/gsm@2720 99fdad57-331a-0410-800a-d7fa5415bdb3
-rw-r--r--include/gsmd/sms.h3
-rw-r--r--include/gsmd/usock.h23
-rw-r--r--include/libgsmd/misc.h5
-rw-r--r--include/libgsmd/sms.h20
-rw-r--r--src/gsmd/sms_cb.c84
-rw-r--r--src/gsmd/usock.c119
-rw-r--r--src/libgsmd/lgsm_internals.h1
-rw-r--r--src/libgsmd/libgsmd.c17
-rw-r--r--src/libgsmd/libgsmd_sms.c68
-rw-r--r--src/libgsmd/libgsmd_voicecall.c18
-rw-r--r--src/util/shell.c76
11 files changed, 291 insertions, 143 deletions
diff --git a/include/gsmd/sms.h b/include/gsmd/sms.h
index ac16509..3192472 100644
--- a/include/gsmd/sms.h
+++ b/include/gsmd/sms.h
@@ -11,6 +11,9 @@ 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);
+extern const char *ts0705_memtype_name[];
+int parse_memtype(char *memtype);
+
#endif /* __GSMD__ */
#endif
diff --git a/include/gsmd/usock.h b/include/gsmd/usock.h
index b60e28e..bcff129 100644
--- a/include/gsmd/usock.h
+++ b/include/gsmd/usock.h
@@ -329,6 +329,29 @@ struct gsmd_sms_list {
int is_last;
};
+/* Refer to GSM 07.05 subclause 3.1 */
+enum ts0705_mem_type {
+ GSM0705_MEMTYPE_NONE,
+ GSM0705_MEMTYPE_BROADCAST,
+ GSM0705_MEMTYPE_ME_MESSAGE,
+ GSM0705_MEMTYPE_MT,
+ GSM0705_MEMTYPE_SIM,
+ GSM0705_MEMTYPE_TA,
+ GSM0705_MEMTYPE_SR,
+};
+
+/* Refer to GSM 07.05 subclause 3.2.2 */
+struct __gsmd_sms_storage {
+ u_int8_t memtype;
+ u_int8_t pad[3];
+ u_int16_t used;
+ u_int16_t total;
+} __attribute__ ((packed));
+
+struct gsmd_sms_storage {
+ struct __gsmd_sms_storage mem[3];
+} __attribute__ ((packed));
+
/* Refer to GSM 07.07 subclause 8.12 */
struct gsmd_phonebook_readrg {
u_int8_t index1;
diff --git a/include/libgsmd/misc.h b/include/libgsmd/misc.h
index 672b980..9988518 100644
--- a/include/libgsmd/misc.h
+++ b/include/libgsmd/misc.h
@@ -65,11 +65,6 @@ extern int lgsm_get_netreg_state(struct lgsm_handle *lh,
/* CLIP, CLIR, COLP, Call Forwarding, Call Waiting, Call Deflecting */
/* TBD */
-
-/* SMS related functions */
-/* TBD */
-
-
/* GPRS related functions */
/* TBD */
diff --git a/include/libgsmd/sms.h b/include/libgsmd/sms.h
index 6a62c38..d389b21 100644
--- a/include/libgsmd/sms.h
+++ b/include/libgsmd/sms.h
@@ -61,16 +61,30 @@ extern int lgsm_sms_list(struct lgsm_handle *lh, enum gsmd_msg_sms_type stat);
extern int lgsm_sms_read(struct lgsm_handle *lh, int index);
/* Delete Message */
-extern int lgsmd_sms_delete(struct lgsm_handle *lh,
+extern int lgsm_sms_delete(struct lgsm_handle *lh,
const struct lgsm_sms_delete *sms_del);
/* Send Message */
-extern int lgsmd_sms_send(struct lgsm_handle *lh, const struct lgsm_sms *sms);
+extern int lgsm_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 lgsm_sms_write(struct lgsm_handle *lh,
const struct lgsm_sms_write *sms_write);
+/* Retrieve SMS storage information */
+extern int lgsm_sms_get_storage(struct lgsm_handle *lh);
+
+/* Set preferred SMS storage */
+extern int lgsm_sms_set_storage(struct lgsm_handle *lh,
+ enum ts0705_mem_type mem1, enum ts0705_mem_type mem2,
+ enum ts0705_mem_type mem3);
+
+/* Retrieve current default service centre address */
+extern int lgsm_sms_get_smsc(struct lgsm_handle *lh);
+
+/* Set new default service centre address */
+extern int lgsm_sms_set_smsc(struct lgsm_handle *lh, const char *number);
+
/* Packing of 7-bit characters, refer to GSM 03.38 subclause 6.1.2.1.1 */
extern int packing_7bit_character(const char *src, struct lgsm_sms *dest);
diff --git a/src/gsmd/sms_cb.c b/src/gsmd/sms_cb.c
index 630518f..97141c1 100644
--- a/src/gsmd/sms_cb.c
+++ b/src/gsmd/sms_cb.c
@@ -38,17 +38,7 @@
#include <gsmd/usock.h>
#include <gsmd/unsolicited.h>
-enum ts0705_mem_type {
- GSM0705_MEMTYPE_NONE,
- GSM0705_MEMTYPE_BROADCAST,
- GSM0705_MEMTYPE_ME_MESSAGE,
- GSM0705_MEMTYPE_MT,
- GSM0705_MEMTYPE_SIM,
- GSM0705_MEMTYPE_TA,
- GSM0705_MEMTYPE_SR,
-};
-
-static const char *ts0705_memtype_name[] = {
+const char *ts0705_memtype_name[] = {
[GSM0705_MEMTYPE_NONE] = "NONE",
[GSM0705_MEMTYPE_BROADCAST] = "BM",
[GSM0705_MEMTYPE_ME_MESSAGE] = "ME",
@@ -58,7 +48,7 @@ static const char *ts0705_memtype_name[] = {
[GSM0705_MEMTYPE_SR] = "SR",
};
-static inline int parse_memtype(char *memtype)
+inline int parse_memtype(char *memtype)
{
int i;
@@ -70,76 +60,6 @@ static inline int parse_memtype(char *memtype)
return GSM0705_MEMTYPE_NONE;
}
-/* TODO: move to headers */
-struct __gsmd_sms_storage {
- u_int8_t memtype;
- u_int8_t pad[3];
- u_int16_t used;
- u_int16_t total;
-} __attribute__ ((packed));
-
-struct gsmd_sms_storage {
- struct __gsmd_sms_storage mem[3];
-} __attribute__ ((packed));
-
-static int usock_cpms_cb(struct gsmd_atcmd *cmd, void *ctx, char *resp)
-{
- 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_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;
-}
-
-/* main unix socket SMS receiver */
-static int usock_rcv_sms(struct gsmd_user *gu, struct gsmd_msg_hdr *gph,
- int len)
-{
- struct gsmd_atcmd *cmd;
-
- switch (gph->msg_subtype) {
- case GSMD_SMS_GET_SERVICE_CENTRE:
- return;
- case GSMD_SMS_SET_SERVICE_CENTRE:
- return;
- case GSMD_SMS_SET_MSG_STORAGE:
- return;
- case GSMD_SMS_GET_MSG_STORAGE:
- cmd = atcmd_fill("AT+CPMS?", 8 + 1, usock_cpms_cb, gu, 0);
- break;
- }
-
- return atcmd_submit(gu->gsmd, cmd);
-}
-
/* main unix socket Cell Broadcast receiver */
static int usock_rcv_cb(struct gsmd_user *gu, struct gsmd_msg_hdr *gph,
int len)
diff --git a/src/gsmd/usock.c b/src/gsmd/usock.c
index bd5bc31..543c3cf 100644
--- a/src/gsmd/usock.c
+++ b/src/gsmd/usock.c
@@ -39,6 +39,7 @@
#include <gsmd/usock.h>
#include <gsmd/talloc.h>
#include <gsmd/ts0707.h>
+#include <gsmd/sms.h>
static void *__ucmd_ctx, *__gu_ctx;
@@ -525,7 +526,7 @@ static int sms_list_cb(struct gsmd_atcmd *cmd, void *ctx, char *resp)
if (
sscanf(resp, "+CMGL: %i,%i,,%i\n%n",
&idx, &stat, &len, &cr) < 3 &&
- sscanf(resp, "+CMGL: %i,%i,%*i,%i\n%n",
+ sscanf(resp, "+CMGL: %i,%i,\"%*[^\"]\",%i\n%n",
&idx, &stat, &len, &cr) < 3)
return -EINVAL;
if (len > 164)
@@ -669,6 +670,65 @@ static int sms_delete_cb(struct gsmd_atcmd *cmd, void *ctx, char *resp)
return 0;
}
+static int usock_cpms_cb(struct gsmd_atcmd *cmd, void *ctx, char *resp)
+{
+ 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_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;
+}
+
+static int usock_get_smsc_cb(struct gsmd_atcmd *cmd, void *ctx, char *resp)
+{
+ struct gsmd_user *gu = ctx;
+ struct gsmd_ucmd *ucmd;
+ struct gsmd_addr *ga;
+
+ ucmd = gsmd_ucmd_fill(sizeof(struct gsmd_addr), GSMD_MSG_SMS,
+ GSMD_SMS_GET_SERVICE_CENTRE, cmd->id);
+ if (!ucmd)
+ return -ENOMEM;
+
+ ga = (struct gsmd_addr *) ucmd->buf;
+ if (sscanf(resp, "+CSCA: \"%31[^\"]\",%hhi",
+ ga->number, &ga->type) < 2) {
+ talloc_free(ucmd);
+ return -EINVAL;
+ }
+
+ usock_cmd_enqueue(ucmd, gu);
+ return 0;
+}
+
static const char *gsmd_cmgl_stat[] = {
"REC UNREAD", "REC READ", "STO UNSENT", "STO SENT", "ALL",
};
@@ -681,6 +741,8 @@ static int usock_rcv_sms(struct gsmd_user *gu, struct gsmd_msg_hdr *gph,
struct gsmd_sms_delete *gsd;
struct gsmd_sms_submit *gss;
struct gsmd_sms_write *gsw;
+ struct gsmd_addr *ga;
+ enum ts0705_mem_type *storage;
int *stat, *index;
int atcmd_len;
char buf[1024];
@@ -693,7 +755,6 @@ static int usock_rcv_sms(struct gsmd_user *gu, struct gsmd_msg_hdr *gph,
if (*stat < 0 || *stat > 4)
return -EINVAL;
- /* FIXME: should we set <mem1> to "SM"/"ME" before that? */
if (gu->gsmd->flags & GSMD_FLAG_SMS_FMT_TEXT)
atcmd_len = sprintf(buf, "AT+CMGL=\"%s\"",
gsmd_cmgl_stat[*stat]);
@@ -702,8 +763,6 @@ static int usock_rcv_sms(struct gsmd_user *gu, struct gsmd_msg_hdr *gph,
cmd = atcmd_fill(buf, atcmd_len + 1,
&sms_list_cb, gu, gph->id);
- if (!cmd)
- return -ENOMEM;
break;
case GSMD_SMS_READ:
@@ -711,13 +770,10 @@ static int usock_rcv_sms(struct gsmd_user *gu, struct gsmd_msg_hdr *gph,
return -EINVAL;
index = (int *) ((void *)gph + sizeof(*gph));
- /* FIXME: should we set <mem1> to "SM"/"ME" before that? */
atcmd_len = sprintf(buf, "AT+CMGR=%i", *index);
cmd = atcmd_fill(buf, atcmd_len + 1,
&sms_read_cb, gu, gph->id);
- if (!cmd)
- return -ENOMEM;
break;
case GSMD_SMS_SEND:
@@ -740,8 +796,6 @@ static int usock_rcv_sms(struct gsmd_user *gu, struct gsmd_msg_hdr *gph,
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:
@@ -751,7 +805,6 @@ static int usock_rcv_sms(struct gsmd_user *gu, struct gsmd_msg_hdr *gph,
if (gsw->stat > 4)
return -EINVAL;
- /* FIXME: should we set <mem2> to "SM"/"ME" before that? */
if (gu->gsmd->flags & GSMD_FLAG_SMS_FMT_TEXT) {
atcmd_len = sprintf(buf, "AT+CMGW=\"%s\"\n%.*s",
gsw->sms.addr.number,
@@ -768,8 +821,6 @@ static int usock_rcv_sms(struct gsmd_user *gu, struct gsmd_msg_hdr *gph,
buf[atcmd_len ++] = 0;
cmd = atcmd_fill(buf, atcmd_len, &sms_write_cb, gu, gph->id);
- if (!cmd)
- return -ENOMEM;
break;
case GSMD_SMS_DELETE:
@@ -781,19 +832,49 @@ static int usock_rcv_sms(struct gsmd_user *gu, struct gsmd_msg_hdr *gph,
gsd->index, gsd->delflg);
cmd = atcmd_fill(buf, atcmd_len + 1,
- &sms_delete_cb, gu, gph->id);
- if (!cmd)
- return -ENOMEM;
+ &sms_delete_cb, gu, gph->id);
+ break;
+
+ case GSMD_SMS_GET_MSG_STORAGE:
+ cmd = atcmd_fill("AT+CPMS?", 8 + 1, usock_cpms_cb, gu, 0);
+ break;
+
+ case GSMD_SMS_SET_MSG_STORAGE:
+ if (len < sizeof(*gph) + 3 * sizeof(enum ts0705_mem_type))
+ return -EINVAL;
+ storage = (enum ts0705_mem_type *)
+ ((void *) gph + sizeof(*gph));
+ atcmd_len = sprintf(buf, "AT+CPMS=\"%s\",\"%s\",\"%s\"",
+ ts0705_memtype_name[storage[0]],
+ ts0705_memtype_name[storage[1]],
+ ts0705_memtype_name[storage[2]]);
+ cmd = atcmd_fill(buf, atcmd_len + 1,
+ &null_cmd_cb, gu, gph->id);
break;
+
+ case GSMD_SMS_GET_SERVICE_CENTRE:
+ cmd = atcmd_fill("AT+CSCA?", 8 + 1, &usock_get_smsc_cb, gu, 0);
+ break;
+
+ case GSMD_SMS_SET_SERVICE_CENTRE:
+ if (len < sizeof(*gph) + sizeof(struct gsmd_addr))
+ return -EINVAL;
+ ga = (struct gsmd_addr *) ((void *) gph + sizeof(*gph));
+ atcmd_len = sprintf(buf, "AT+CSCA=\"%s\",%i",
+ ga->number, ga->type);
+ cmd = atcmd_fill(buf, atcmd_len + 1,
+ &null_cmd_cb, gu, gph->id);
+ break;
+
default:
return -EINVAL;
}
+ if (!cmd)
+ return -ENOMEM;
+
gsmd_log(GSMD_DEBUG, "%s\n", cmd ? cmd->buf : 0);
- if (cmd)
- return atcmd_submit(gu->gsmd, cmd);
- else
- return 0;
+ return atcmd_submit(gu->gsmd, cmd);
}
#if 0
diff --git a/src/libgsmd/lgsm_internals.h b/src/libgsmd/lgsm_internals.h
index 94421fa..c826723 100644
--- a/src/libgsmd/lgsm_internals.h
+++ b/src/libgsmd/lgsm_internals.h
@@ -11,6 +11,7 @@ struct lgsm_handle {
};
int lgsm_send(struct lgsm_handle *lh, struct gsmd_msg_hdr *gmh);
+int lgsm_send_simple(struct lgsm_handle *lh, int type, int sub_type);
struct gsmd_msg_hdr *lgsm_gmh_fill(int type, int subtype, int payload_len);
#define lgsm_gmh_free(x) free(x)
diff --git a/src/libgsmd/libgsmd.c b/src/libgsmd/libgsmd.c
index 11760b4..37a50e6 100644
--- a/src/libgsmd/libgsmd.c
+++ b/src/libgsmd/libgsmd.c
@@ -207,3 +207,20 @@ struct gsmd_msg_hdr *lgsm_gmh_fill(int type, int subtype, int payload_len)
return gmh;
}
+int lgsm_send_simple(struct lgsm_handle *lh, int type, int sub_type)
+{
+ struct gsmd_msg_hdr *gmh;
+ int rc;
+
+ gmh = lgsm_gmh_fill(type, sub_type, 0);
+ if (!gmh)
+ return -ENOMEM;
+ rc = lgsm_send(lh, gmh);
+ if (rc < gmh->len + sizeof(*gmh)) {
+ lgsm_gmh_free(gmh);
+ return -EIO;
+ }
+ lgsm_gmh_free(gmh);
+
+ return 0;
+}
diff --git a/src/libgsmd/libgsmd_sms.c b/src/libgsmd/libgsmd_sms.c
index 9ac9bf2..29b92fb 100644
--- a/src/libgsmd/libgsmd_sms.c
+++ b/src/libgsmd/libgsmd_sms.c
@@ -57,7 +57,7 @@ int lgsm_sms_read(struct lgsm_handle *lh, int index)
return 0;
}
-int lgsmd_sms_delete(struct lgsm_handle *lh,
+int lgsm_sms_delete(struct lgsm_handle *lh,
const struct lgsm_sms_delete *sms_del)
{
struct gsmd_msg_hdr *gmh;
@@ -83,7 +83,7 @@ int lgsmd_sms_delete(struct lgsm_handle *lh,
return 0;
}
-int lgsmd_number2addr(struct gsmd_addr *dst, const char *src)
+int lgsm_number2addr(struct gsmd_addr *dst, const char *src, int skipplus)
{
char *ch;
@@ -94,7 +94,7 @@ int lgsmd_number2addr(struct gsmd_addr *dst, const char *src)
GSMD_TOA_NPI_ISDN |
GSMD_TOA_TON_INTERNATIONAL |
GSMD_TOA_RESERVED;
- strcpy(dst->number, src + 1);
+ strcpy(dst->number, src + skipplus);
} else {
dst->type =
GSMD_TOA_NPI_ISDN |
@@ -109,7 +109,7 @@ int lgsmd_number2addr(struct gsmd_addr *dst, const char *src)
return 0;
}
-int lgsmd_sms_send(struct lgsm_handle *lh,
+int lgsm_sms_send(struct lgsm_handle *lh,
const struct lgsm_sms *sms)
{
/* FIXME: only support PDU mode */
@@ -123,7 +123,7 @@ int lgsmd_sms_send(struct lgsm_handle *lh,
return -ENOMEM;
gss = (struct gsmd_sms_submit *) gmh->data;
- if (lgsmd_number2addr(&gss->addr, sms->addr))
+ if (lgsm_number2addr(&gss->addr, sms->addr, 1))
return -EINVAL;
gss->payload.has_header = 0;
@@ -142,7 +142,7 @@ int lgsmd_sms_send(struct lgsm_handle *lh,
return 0;
}
-int lgsmd_sms_write(struct lgsm_handle *lh,
+int lgsm_sms_write(struct lgsm_handle *lh,
const struct lgsm_sms_write *sms_write)
{
/* FIXME: only support PDU mode */
@@ -158,7 +158,7 @@ int lgsmd_sms_write(struct lgsm_handle *lh,
gsw->stat = sms_write->stat;
- if (lgsmd_number2addr(&gsw->sms.addr, sms_write->sms.addr))
+ if (lgsm_number2addr(&gsw->sms.addr, sms_write->sms.addr, 1))
return -EINVAL;
gsw->sms.payload.has_header = 0;
@@ -178,6 +178,60 @@ int lgsmd_sms_write(struct lgsm_handle *lh,
return 0;
}
+int lgsm_sms_get_storage(struct lgsm_handle *lh)
+{
+ return lgsm_send_simple(lh, GSMD_MSG_SMS, GSMD_SMS_GET_MSG_STORAGE);
+}
+
+int lgsm_sms_set_storage(struct lgsm_handle *lh, enum ts0705_mem_type mem1,
+ enum ts0705_mem_type mem2, enum ts0705_mem_type mem3)
+{
+ struct gsmd_msg_hdr *gmh =
+ lgsm_gmh_fill(GSMD_MSG_SMS, GSMD_SMS_SET_MSG_STORAGE,
+ 3 * sizeof(enum ts0705_mem_type));
+ if (!gmh)
+ return -ENOMEM;
+
+ ((enum ts0705_mem_type *) gmh->data)[0] = mem1;
+ ((enum ts0705_mem_type *) gmh->data)[1] = mem2;
+ ((enum ts0705_mem_type *) gmh->data)[2] = mem3;
+
+ if (lgsm_send(lh, gmh) < gmh->len + sizeof(*gmh)) {
+ lgsm_gmh_free(gmh);
+ return -EIO;
+ }
+
+ lgsm_gmh_free(gmh);
+ return 0;
+}
+
+int lgsm_sms_get_smsc(struct lgsm_handle *lh)
+{
+ return lgsm_send_simple(lh, GSMD_MSG_SMS, GSMD_SMS_GET_SERVICE_CENTRE);
+}
+
+int lgsm_sms_set_smsc(struct lgsm_handle *lh, const char *number)
+{
+ struct gsmd_msg_hdr *gmh =
+ lgsm_gmh_fill(GSMD_MSG_SMS, GSMD_SMS_SET_SERVICE_CENTRE,
+ sizeof(struct gsmd_addr));
+ if (!gmh)
+ return -ENOMEM;
+
+ if (lgsm_number2addr((struct gsmd_addr *) gmh->data, number, 0)) {
+ lgsm_gmh_free(gmh);
+ return -EINVAL;
+ }
+
+ if (lgsm_send(lh, gmh) < gmh->len + sizeof(*gmh)) {
+ lgsm_gmh_free(gmh);
+ return -EIO;
+ }
+
+ lgsm_gmh_free(gmh);
+ return 0;
+}
+
int packing_7bit_character(const char *src, struct lgsm_sms *dest)
{
int i,j = 0;
diff --git a/src/libgsmd/libgsmd_voicecall.c b/src/libgsmd/libgsmd_voicecall.c
index d6965fa..d78fb3d 100644
--- a/src/libgsmd/libgsmd_voicecall.c
+++ b/src/libgsmd/libgsmd_voicecall.c
@@ -28,24 +28,6 @@
#include "lgsm_internals.h"
-int lgsm_send_simple(struct lgsm_handle *lh, int type, int sub_type)
-{
- struct gsmd_msg_hdr *gmh;
- int rc;
-
- gmh = lgsm_gmh_fill(type, sub_type, 0);
- if (!gmh)
- return -ENOMEM;
- rc = lgsm_send(lh, gmh);
- if (rc < gmh->len + sizeof(*gmh)) {
- lgsm_gmh_free(gmh);
- return -EIO;
- }
- lgsm_gmh_free(gmh);
-
- return 0;
-}
-
int lgsm_voice_out_init(struct lgsm_handle *lh,
const struct lgsm_addr *number)
{
diff --git a/src/util/shell.c b/src/util/shell.c
index b2ebfd8..31c2d99 100644
--- a/src/util/shell.c
+++ b/src/util/shell.c
@@ -81,15 +81,22 @@ static int sms_msghandler(struct lgsm_handle *lh, struct gsmd_msg_hdr *gmh)
char payload[GSMD_SMS_DATA_MAXLEN];
int *result;
struct gsmd_sms_list *sms;
- static const char *type[] = { "Unread", "Received", "Unsent", "Sent" };
+ struct gsmd_addr *addr;
+ struct gsmd_sms_storage *mem;
+ static const char *msgtype[] = {
+ "Unread", "Received", "Unsent", "Sent"
+ };
+ static const char *memtype[] = {
+ "Unknown", "Broadcast", "Me message", "MT", "SIM", "TA", "SR"
+ };
switch (gmh->msg_subtype) {
case GSMD_SMS_LIST:
case GSMD_SMS_READ:
sms = (struct gsmd_sms_list *) ((void *) gmh + sizeof(*gmh));
printf("%s message %i from/to %s%s, at %i%i-%i%i-%i%i "
- "%i%i:%i%i:%i%i, GMT%c%i\n", type[sms->stat],
- sms->index,
+ "%i%i:%i%i:%i%i, GMT%c%i\n",
+ msgtype[sms->stat], sms->index,
((sms->addr.type & __GSMD_TOA_TON_MASK) ==
GSMD_TOA_TON_INTERNATIONAL) ? "+" : "",
sms->addr.number,
@@ -166,6 +173,30 @@ static int sms_msghandler(struct lgsm_handle *lh, struct gsmd_msg_hdr *gmh)
break;
}
break;
+ case GSMD_SMS_GET_MSG_STORAGE:
+ mem = (struct gsmd_sms_storage *)
+ ((void *) gmh + sizeof(*gmh));
+ printf("mem1: %s (%i) Occupied: %i / %i\n",
+ memtype[mem->mem[0].memtype],
+ mem->mem[0].memtype,
+ mem->mem[0].used,
+ mem->mem[0].total);
+ printf("mem2: %s (%i) Occupied: %i / %i\n",
+ memtype[mem->mem[1].memtype],
+ mem->mem[1].memtype,
+ mem->mem[1].used,
+ mem->mem[1].total);
+ printf("mem3: %s (%i) Occupied: %i / %i\n",
+ memtype[mem->mem[2].memtype],
+ mem->mem[2].memtype,
+ mem->mem[2].used,
+ mem->mem[2].total);
+ break;
+ case GSMD_SMS_GET_SERVICE_CENTRE:
+ addr = (struct gsmd_addr *) ((void *) gmh + sizeof(*gmh));
+ printf("Number of the default Service Centre is %s\n",
+ addr->number);
+ break;
default:
return -EINVAL;
}
@@ -244,6 +275,10 @@ static int shell_help(void)
"\tsr\tSMS Read (sr=index)\n"
"\tss\tSMS Send (ss=number,text)\n"
"\tsw\tSMS Write (sw=stat,number,text)\n"
+ "\tsm\tSMS Storage stats\n"
+ "\tsM\tSMS Set preferred storage (sM=mem1,mem2,mem3)\n"
+ "\tsc\tSMS Show Service Centre\n"
+ "\tsC\tSMS Set Service Centre (sC=number)\n"
"\tq\tQuit\n"
);
}
@@ -357,7 +392,7 @@ int shell_main(struct lgsm_handle *lgsmh)
} else if ( !strncmp(buf, "pd", 2)) {
printf("Delete Phonebook Entry\n");
ptr = strchr(buf, '=');
- lgsmd_pb_del_entry(lgsmh, atoi(ptr+1));
+ lgsmd_pb_del_entry(lgsmh, atoi(ptr+1));
} else if ( !strncmp(buf, "prr", 3)) {
printf("Read Phonebook Entries\n");
struct lgsm_phonebook_readrg pb_readrg;
@@ -371,7 +406,7 @@ int shell_main(struct lgsm_handle *lgsmh)
} else if ( !strncmp(buf, "pr", 2)) {
printf("Read Phonebook Entry\n");
ptr = strchr(buf, '=');
- lgsm_pb_read_entry(lgsmh, atoi(ptr+1));
+ lgsm_pb_read_entry(lgsmh, atoi(ptr+1));
} else if ( !strncmp(buf, "pf", 2)) {
printf("Find Phonebook Entry\n");
struct lgsm_phonebook_find pb_find;
@@ -402,7 +437,7 @@ int shell_main(struct lgsm_handle *lgsmh)
lgsmd_pb_write_entry(lgsmh, &pb);
} else if ( !strncmp(buf, "ps", 2)) {
printf("Get Phonebook Support\n");
- lgsm_pb_get_support(lgsmh);
+ lgsm_pb_get_support(lgsmh);
} else if ( !strncmp(buf, "sd", 2)) {
printf("Delete SMS\n");
struct lgsm_sms_delete sms_del;
@@ -412,7 +447,7 @@ int shell_main(struct lgsm_handle *lgsmh)
ptr = strchr(buf, ',');
sms_del.delflg = atoi(ptr+1);
- lgsmd_sms_delete(lgsmh, &sms_del);
+ lgsm_sms_delete(lgsmh, &sms_del);
} else if ( !strncmp(buf, "sl", 2)) {
printf("List SMS\n");
ptr = strchr(buf, '=');
@@ -433,7 +468,7 @@ int shell_main(struct lgsm_handle *lgsmh)
sms.addr[fcomma-ptr-1] = '\0';
packing_7bit_character(fcomma+1, &sms);
- lgsmd_sms_send(lgsmh, &sms);
+ lgsm_sms_send(lgsmh, &sms);
} else if ( !strncmp(buf, "sw", 2)) {
printf("Write SMS\n");
struct lgsm_sms_write sms_write;
@@ -448,7 +483,30 @@ int shell_main(struct lgsm_handle *lgsmh)
packing_7bit_character(
lcomma+1, &sms_write.sms);
- lgsmd_sms_write(lgsmh, &sms_write);
+ lgsm_sms_write(lgsmh, &sms_write);
+ } else if (!strncmp(buf, "sm", 2)) {
+ printf("Get SMS storage preferences\n");
+ lgsm_sms_get_storage(lgsmh);
+ } else if (!strncmp(buf, "sM", 2)) {
+ int mem[3];
+
+ printf("Set SMS storage preferences\n");
+ if (sscanf(buf, "sM=%i,%i,%i", mem, mem + 1,
+ mem + 2) < 3)
+ printf("No.\n");
+ else
+ lgsm_sms_set_storage(lgsmh, mem[0],
+ mem[1], mem[2]);
+ } else if (!strncmp(buf, "sc", 2)) {
+ printf("Get the default SMSC\n");
+ lgsm_sms_get_smsc(lgsmh);
+ } else if (!strncmp(buf, "sC", 2)) {
+ printf("Set the default SMSC\n");
+ ptr = strchr(buf, '=');
+ if (!ptr || strlen(ptr) < 6)
+ printf("No.\n");
+ else
+ lgsm_sms_set_smsc(lgsmh, ptr + 1);
} else {
printf("Unknown command `%s'\n", buf);
}
personal git repositories of Harald Welte. Your mileage may vary