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. r2723 - in trunk/src/target/gsm: include/gsmd include/libgsmd
src/gsmd src/libgsmd src/util ([EMAIL PROTECTED])
2. r2724 - trunk/src/target/gsm/src/libgsmd
([EMAIL PROTECTED])
3. r2725 - in trunk/src/target/gsm: include/gsmd include/libgsmd
src/gsmd src/libgsmd ([EMAIL PROTECTED])
4. r2726 - in trunk/src/target/gsm: include/gsmd include/libgsmd
src/gsmd src/libgsmd src/util ([EMAIL PROTECTED])
--- Begin Message ---
Author: laforge
Date: 2007-08-17 10:31:21 +0200 (Fri, 17 Aug 2007)
New Revision: 2723
Modified:
trunk/src/target/gsm/include/gsmd/sms.h
trunk/src/target/gsm/include/gsmd/usock.h
trunk/src/target/gsm/include/libgsmd/sms.h
trunk/src/target/gsm/src/gsmd/sms_cb.c
trunk/src/target/gsm/src/gsmd/sms_pdu.c
trunk/src/target/gsm/src/libgsmd/libgsmd_sms.c
trunk/src/target/gsm/src/util/event.c
Log:
From: Andrzej Zaborowski <[EMAIL PROTECTED]>
Date: Fri, 27 Jul 2007 19:39:15 +0200
Subject: [PATCH] Cell Broadcast message decoding and presentation in
libgsmd-tool.
This time Cell Broadcast is tested to work, I should have made tests earlier.
Now I'm correctly getting a CB message with the human readable name of the city
and district when I'm connecting. In the previous patches the CB PDU was not
being decoded at all.
Modified: trunk/src/target/gsm/include/gsmd/sms.h
===================================================================
--- trunk/src/target/gsm/include/gsmd/sms.h 2007-08-17 08:30:42 UTC (rev
2722)
+++ trunk/src/target/gsm/include/gsmd/sms.h 2007-08-17 08:31:21 UTC (rev
2723)
@@ -8,10 +8,13 @@
int sms_cb_init(struct gsmd *gsmd);
int sms_cb_network_init(struct gsmd *gsmd);
-#define MAX_PDU_SIZE 180
+#define SMS_MAX_PDU_SIZE 180
+#define CBM_MAX_PDU_SIZE 88
+#define CBM_MAX_PDU_PAGES 15
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);
+int cbs_pdu_to_msg(struct gsmd_cbm *dst, u_int8_t *src, int pdulen, int len);
int usock_rcv_sms(struct gsmd_user *gu, struct gsmd_msg_hdr *gph, int len);
int usock_rcv_cb(struct gsmd_user *gu, struct gsmd_msg_hdr *gph, int len);
Modified: trunk/src/target/gsm/include/gsmd/usock.h
===================================================================
--- trunk/src/target/gsm/include/gsmd/usock.h 2007-08-17 08:30:42 UTC (rev
2722)
+++ trunk/src/target/gsm/include/gsmd/usock.h 2007-08-17 08:31:21 UTC (rev
2723)
@@ -365,6 +365,48 @@
struct __gsmd_sms_storage mem[3];
} __attribute__ ((packed));
+/* Refer to GSM 03.41 subclause 9.3.1 - note: this indicates display mode too
*/
+enum gsmd_geographical_scope {
+ GSMD_SCOPE_CELL_WIDE_OPER = 0,
+ GSMD_SCOPE_PLMN_WIDE,
+ GSMD_SCOPE_LOC_AREA_WIDE,
+ GSMD_SCOPE_CELL_WIDE,
+};
+
+enum gsmd_language {
+ GSMD_LANG_GERMAN = 0,
+ GSMD_LANG_ENGLISH,
+ GSMD_LANG_ITALIAN,
+ GSMD_LANG_FRENCH,
+ GSMD_LANG_SPANISH,
+ GSMD_LANG_DUTCH,
+ GSMD_LANG_SWEDISH,
+ GSMD_LANG_DANISH,
+ GSMD_LANG_PORTUGUESE,
+ GSMD_LANG_FINNISH,
+ GSMD_LANG_NORWEGIAN,
+ GSMD_LANG_GREEK,
+ GSMD_LANG_TURKISH,
+ GSMD_LANG_HUNGARIAN,
+ GSMD_LANG_POLISH,
+ GSMD_LANG_UNSPECIFIED,
+};
+
+/* Refer to GSM 03.41 subclause 9.3 */
+struct gsmd_cbm {
+ struct {
+ enum gsmd_geographical_scope scope;
+ int msg_code;
+ int update_num;
+ } serial;
+ u_int16_t msg_id;
+ enum gsmd_language language;
+ u_int8_t coding_scheme;
+ int pages;
+ int page;
+ u_int8_t data[82];
+};
+
/* Refer to GSM 07.07 subclause 8.12 */
struct gsmd_phonebook_readrg {
u_int8_t index1;
Modified: trunk/src/target/gsm/include/libgsmd/sms.h
===================================================================
--- trunk/src/target/gsm/include/libgsmd/sms.h 2007-08-17 08:30:42 UTC (rev
2722)
+++ trunk/src/target/gsm/include/libgsmd/sms.h 2007-08-17 08:31:21 UTC (rev
2723)
@@ -90,6 +90,7 @@
/* Packing of 7-bit characters, refer to GSM 03.38 subclause 6.1.2.1.1 */
extern int unpacking_7bit_character(const struct gsmd_sms *src, char *dest);
+extern int cbm_unpacking_7bit_character(const char *src, char *dest);
/* Refer to 3GPP TS 11.11 Annex B */
extern int packing_UCS2_80(char *src, char *dest);
Modified: trunk/src/target/gsm/src/gsmd/sms_cb.c
===================================================================
--- trunk/src/target/gsm/src/gsmd/sms_cb.c 2007-08-17 08:30:42 UTC (rev
2722)
+++ trunk/src/target/gsm/src/gsmd/sms_cb.c 2007-08-17 08:31:21 UTC (rev
2723)
@@ -67,7 +67,7 @@
struct gsmd_ucmd *ucmd;
struct gsmd_sms_list msg;
int i, idx, stat, len, cr;
- u_int8_t pdu[MAX_PDU_SIZE];
+ u_int8_t pdu[SMS_MAX_PDU_SIZE];
if (cmd->ret && cmd->ret != -255)
return 0;
@@ -86,7 +86,7 @@
msg.stat = stat;
msg.is_last = (cmd->ret == 0);
for (i = 0; resp[cr] >= '0' && resp[cr + 1] >= '0' &&
- i < MAX_PDU_SIZE; i ++) {
+ i < SMS_MAX_PDU_SIZE; i ++) {
if (sscanf(resp + cr, "%2hhX", &pdu[i]) < 1) {
gsmd_log(GSMD_DEBUG, "malformed input (%i)\n", i);
return -EINVAL;
@@ -115,7 +115,7 @@
struct gsmd_ucmd *ucmd;
struct gsmd_sms_list msg;
int i, stat, len, cr;
- u_int8_t pdu[MAX_PDU_SIZE];
+ u_int8_t pdu[SMS_MAX_PDU_SIZE];
if (cmd->ret)
return 0;
@@ -134,7 +134,7 @@
msg.stat = stat;
msg.is_last = 1;
for (i = 0; resp[cr] >= '0' && resp[cr + 1] >= '0' &&
- i < MAX_PDU_SIZE; i ++) {
+ i < SMS_MAX_PDU_SIZE; i ++) {
if (sscanf(resp + cr, "%2hhX", &pdu[i]) < 1) {
gsmd_log(GSMD_DEBUG, "malformed input (%i)\n", i);
return -EINVAL;
@@ -475,7 +475,7 @@
static int cmt_parse(char *buf, int len, const char *param, struct gsmd *gsmd)
{
/* TODO: TEXT mode */
- u_int8_t pdu[MAX_PDU_SIZE];
+ u_int8_t pdu[SMS_MAX_PDU_SIZE];
const char *comma = strchr(param, ',');
char *cr;
int i;
@@ -502,7 +502,8 @@
}
cr ++;
- for (i = 0; cr[0] >= '0' && cr[1] >= '0' && i < MAX_PDU_SIZE; i ++) {
+ for (i = 0; cr[0] >= '0' && cr[1] >= '0' && i < SMS_MAX_PDU_SIZE;
+ i ++) {
if (sscanf(cr, "%2hhX", &pdu[i]) < 1) {
gsmd_log(GSMD_DEBUG, "malformed input (%i)\n", i);
talloc_free(ucmd);
@@ -531,11 +532,6 @@
if (!ucmd)
return -ENOMEM;
- ucmd->hdr.version = GSMD_PROTO_VERSION;
- ucmd->hdr.msg_type = GSMD_MSG_EVENT;
- ucmd->hdr.msg_subtype = GSMD_EVT_IN_CBM;
- ucmd->hdr.len = sizeof(*aux);
-
aux = (struct gsmd_evt_auxdata *) ucmd->buf;
if (sscanf(param, "\"%2[A-Z]\",%i", memstr, &aux->u.cbm.index) < 2) {
talloc_free(ucmd);
@@ -551,20 +547,20 @@
static int cbm_parse(char *buf, int len, const char *param, struct gsmd *gsmd)
{
/* TODO: TEXT mode */
- u_int8_t pdu[MAX_PDU_SIZE];
+ u_int8_t pdu[CBM_MAX_PDU_SIZE];
char *cr;
int i;
struct gsmd_evt_auxdata *aux;
- struct gsmd_sms_list *msg;
+ struct gsmd_cbm *msg;
struct gsmd_ucmd *ucmd = usock_build_event(GSMD_MSG_EVENT,
GSMD_EVT_IN_CBM, sizeof(struct gsmd_evt_auxdata) +
- sizeof(struct gsmd_sms_list));
+ sizeof(struct gsmd_cbm));
if (!ucmd)
return -ENOMEM;
aux = (struct gsmd_evt_auxdata *) ucmd->buf;
- msg = (struct gsmd_sms_list *) aux->data;
+ msg = (struct gsmd_cbm *) aux->data;
len = strtoul(param, &cr, 10);
if (cr[0] != '\n') {
@@ -573,7 +569,8 @@
}
cr ++;
- for (i = 0; cr[0] >= '0' && cr[1] >= '0' && i < MAX_PDU_SIZE; i ++) {
+ for (i = 0; cr[0] >= '0' && cr[1] >= '0' && i < CBM_MAX_PDU_SIZE;
+ i ++) {
if (sscanf(cr, "%2hhX", &pdu[i]) < 1) {
gsmd_log(GSMD_DEBUG, "malformed input (%i)\n", i);
talloc_free(ucmd);
@@ -583,7 +580,7 @@
}
aux->u.cbm.inlined = 1;
- if (sms_pdu_to_msg(msg, pdu, len, i)) {
+ if (cbs_pdu_to_msg(msg, pdu, len, i)) {
gsmd_log(GSMD_DEBUG, "malformed PDU\n");
talloc_free(ucmd);
return -EINVAL;
@@ -617,7 +614,7 @@
static int cds_parse(char *buf, int len, const char *param, struct gsmd *gsmd)
{
/* TODO: TEXT mode */
- u_int8_t pdu[MAX_PDU_SIZE];
+ u_int8_t pdu[SMS_MAX_PDU_SIZE];
char *cr;
int i;
struct gsmd_evt_auxdata *aux;
@@ -639,7 +636,8 @@
}
cr ++;
- for (i = 0; cr[0] >= '0' && cr[1] >= '0' && i < MAX_PDU_SIZE; i ++) {
+ for (i = 0; cr[0] >= '0' && cr[1] >= '0' && i < SMS_MAX_PDU_SIZE;
+ i ++) {
if (sscanf(cr, "%2hhX", &pdu[i]) < 1) {
gsmd_log(GSMD_DEBUG, "malformed input (%i)\n", i);
talloc_free(ucmd);
@@ -714,11 +712,5 @@
*/
ret |= gsmd_simplecmd(gsmd, "AT+CNMI=2,1,2,1,0");
- /* Store into ME/TA and notify */
- ret |= gsmd_simplecmd(gsmd, "AT+CSBS=1");
-
- /* Store into ME/TA and notify */
- ret |= gsmd_simplecmd(gsmd, "AT+CSDS=2");
-
return ret;
}
Modified: trunk/src/target/gsm/src/gsmd/sms_pdu.c
===================================================================
--- trunk/src/target/gsm/src/gsmd/sms_pdu.c 2007-08-17 08:30:42 UTC (rev
2722)
+++ trunk/src/target/gsm/src/gsmd/sms_pdu.c 2007-08-17 08:31:21 UTC (rev
2723)
@@ -26,6 +26,7 @@
#include <gsmd/gsmd.h>
#include <gsmd/usock.h>
+#include <gsmd/sms.h>
static int sms_number_bytelen(u_int8_t type, u_int8_t len)
{
@@ -50,7 +51,7 @@
return 0;
}
-static int sms_address2ascii(struct gsmd_addr *dst, u_int8_t *src)
+static int sms_address2ascii(struct gsmd_addr *dst, const u_int8_t *src)
{
int i;
@@ -80,7 +81,7 @@
}
int sms_pdu_to_msg(struct gsmd_sms_list *dst,
- u_int8_t *src, int pdulen, int len)
+ const u_int8_t *src, int pdulen, int len)
{
int i, vpf;
if (len < 1 || len < 1 + src[0] + pdulen || pdulen < 1)
@@ -200,7 +201,7 @@
}
/* Refer to GSM 03.40 subclause 9.2.3.3, for SMS-SUBMIT */
-int sms_pdu_make_smssubmit(char *dest, struct gsmd_sms_submit *src)
+int sms_pdu_make_smssubmit(char *dest, const struct gsmd_sms_submit *src)
{
/* FIXME: ALPHANUMERIC encoded addresses can be longer than 13B */
u_int8_t header[15 + GSMD_ADDR_MAXLEN];
@@ -259,3 +260,25 @@
return pos + len;
}
+
+/* Refer to GSM 03.41 subclause 9.3 */
+int cbs_pdu_to_msg(struct gsmd_cbm *dst, u_int8_t *src, int pdulen, int len)
+{
+ if (len != pdulen || len != CBM_MAX_PDU_SIZE)
+ return 1;
+
+ dst->serial.scope = (src[0] >> 6) & 3;
+ dst->serial.msg_code = ((src[0] << 4) | (src[1] >> 4)) & 0x3ff;
+ dst->serial.update_num = src[1] & 0xf;
+
+ dst->msg_id = (src[2] << 8) | src[3];
+
+ dst->language = src[4] & 0xf;
+ dst->coding_scheme = ((src[4] >> 4) & 3) << 2;
+
+ dst->pages = src[5] & 0xf;
+ dst->page = src[5] >> 4;
+
+ memcpy(dst->data, src + 6, len - 6);
+ return 0;
+}
Modified: trunk/src/target/gsm/src/libgsmd/libgsmd_sms.c
===================================================================
--- trunk/src/target/gsm/src/libgsmd/libgsmd_sms.c 2007-08-17 08:30:42 UTC
(rev 2722)
+++ trunk/src/target/gsm/src/libgsmd/libgsmd_sms.c 2007-08-17 08:31:21 UTC
(rev 2723)
@@ -283,6 +283,20 @@
return i;
}
+int cbm_unpacking_7bit_character(const char *src, char *dest)
+{
+ int i;
+ u_int8_t ch = 1;
+
+ for (i = 0; i < 93 && ch; i ++)
+ *(dest ++) = ch =
+ ((src[(i * 7 + 7) >> 3] << (7 - ((i * 7 + 7) & 7))) |
+ (src[(i * 7) >> 3] >> ((i * 7) & 7))) & 0x7f;
+ *dest = '\0';
+
+ return i;
+}
+
/* Refer to 3GPP TS 11.11 Annex B */
int packing_UCS2_80(char *src, char *dest)
{
Modified: trunk/src/target/gsm/src/util/event.c
===================================================================
--- trunk/src/target/gsm/src/util/event.c 2007-08-17 08:30:42 UTC (rev
2722)
+++ trunk/src/target/gsm/src/util/event.c 2007-08-17 08:31:21 UTC (rev
2723)
@@ -34,13 +34,107 @@
return 0;
}
-static int insms_handler(struct lgsm_handle *lh, int evt, struct
gsmd_evt_auxdata *aux)
+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);
+ struct gsmd_sms_list *sms;
+ char payload[GSMD_SMS_DATA_MAXLEN];
+ if (aux->u.sms.inlined) {
+ sms = (struct gsmd_sms_list *) aux->data;
+ printf("EVENT: Incoming SMS from/to %s%s, at %i%i-%i%i-%i%i "
+ "%i%i:%i%i:%i%i, GMT%c%i\n",
+ ((sms->addr.type & __GSMD_TOA_TON_MASK) ==
+ GSMD_TOA_TON_INTERNATIONAL) ? "+" : "",
+ sms->addr.number,
+ sms->time_stamp[0] & 0xf,
+ sms->time_stamp[0] >> 4,
+ sms->time_stamp[1] & 0xf,
+ sms->time_stamp[1] >> 4,
+ sms->time_stamp[2] & 0xf,
+ sms->time_stamp[2] >> 4,
+ sms->time_stamp[3] & 0xf,
+ sms->time_stamp[3] >> 4,
+ sms->time_stamp[4] & 0xf,
+ sms->time_stamp[4] >> 4,
+ sms->time_stamp[5] & 0xf,
+ sms->time_stamp[5] >> 4,
+ (sms->time_stamp[6] & 8) ? '-' : '+',
+ (((sms->time_stamp[6] << 4) |
+ (sms->time_stamp[6] >> 4)) & 0x3f) >> 2);
+ if (sms->payload.coding_scheme == ALPHABET_DEFAULT) {
+ unpacking_7bit_character(&sms->payload, payload);
+ printf("\"%s\"\n", payload);
+ } else if (sms->payload.coding_scheme == ALPHABET_8BIT)
+ printf("8-bit encoded data\n");
+ else if (sms->payload.coding_scheme == ALPHABET_UCS2)
+ printf("Unicode-16 encoded text\n");
+ } else
+ printf("EVENT: Incoming SMS stored at location %i\n",
+ aux->u.sms.index);
+ return 0;
+}
+static int incbm_handler(struct lgsm_handle *lh, int evt,
+ struct gsmd_evt_auxdata *aux)
+{
+ struct gsmd_cbm *msg;
+ char payload[95];
+ static const char *scope_name[] = {
+ [GSMD_SCOPE_CELL_WIDE_OPER] = "immediate-display cell",
+ [GSMD_SCOPE_PLMN_WIDE] = "PLMN",
+ [GSMD_SCOPE_LOC_AREA_WIDE] = "Location Area",
+ [GSMD_SCOPE_CELL_WIDE] = "cell",
+ };
+ static const char *lang_name[] = {
+ [GSMD_LANG_GERMAN] = "German",
+ [GSMD_LANG_ENGLISH] = "English",
+ [GSMD_LANG_ITALIAN] = "Italian",
+ [GSMD_LANG_FRENCH] = "French",
+ [GSMD_LANG_SPANISH] = "Spanish",
+ [GSMD_LANG_DUTCH] = "Dutch",
+ [GSMD_LANG_SWEDISH] = "Swedish",
+ [GSMD_LANG_DANISH] = "Danish",
+ [GSMD_LANG_PORTUGUESE] = "Portuguese",
+ [GSMD_LANG_FINNISH] = "Finnish",
+ [GSMD_LANG_NORWEGIAN] = "Norwegian",
+ [GSMD_LANG_GREEK] = "Greek",
+ [GSMD_LANG_TURKISH] = "Turkish",
+ [GSMD_LANG_HUNGARIAN] = "Hungarian",
+ [GSMD_LANG_POLISH] = "Polish",
+ [GSMD_LANG_UNSPECIFIED] = "an unspecified language",
+ };
+ if (aux->u.cbm.inlined) {
+ msg = (struct gsmd_cbm *) aux->data;
+ printf("EVENT: Incoming %s-wide Cell Broadcast message in "
+ "%s (page %i of %i)\n",
+ scope_name[msg->serial.scope],
+ lang_name[msg->language],
+ msg->page, msg->pages);
+
+ if (msg->coding_scheme == ALPHABET_DEFAULT) {
+ cbm_unpacking_7bit_character(msg->data, payload);
+ printf("\"%s\"\n", payload);
+ } else if (msg->coding_scheme == ALPHABET_8BIT)
+ printf("8-bit encoded data\n");
+ else if (msg->coding_scheme == ALPHABET_UCS2)
+ printf("Unicode-16 encoded text\n");
+ } else
+ printf("EVENT: Incoming Cell Broadcast message stored at "
+ "location %i\n", aux->u.cbm.index);
return 0;
}
+static int inds_handler(struct lgsm_handle *lh, int evt,
+ struct gsmd_evt_auxdata *aux)
+{
+ if (aux->u.ds.inlined)
+ printf("EVENT: Incoming Status Report\n");
+ else
+ printf("EVENT: Incoming Status Report stored at location %i\n",
+ aux->u.ds.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);
@@ -139,6 +233,8 @@
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_IN_CBM, &incbm_handler);
+ rc |= lgsm_evt_handler_register(lh, GSMD_EVT_IN_DS, &inds_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-17 10:31:49 +0200 (Fri, 17 Aug 2007)
New Revision: 2724
Modified:
trunk/src/target/gsm/src/libgsmd/libgsmd.c
Log:
From: Andrzej Zaborowski <[EMAIL PROTECTED]>
Date: Tue, 31 Jul 2007 22:28:28 +0200
Subject: [PATCH] Correctly split long usock reads into packets.
This is a patch for an unrelated to the above discussion timing issue in
libgsmd. In particular, when the modem responds fast enough, gsmd generates
usock packets fast enough for libgsmd to read multiple packets in a single read
and concatenate them thus discarding all packets but first. This happens on
Neo1973 when requesting for example the list of preferred operators or all
operators or, sometimes, list of short messages.
Modified: trunk/src/target/gsm/src/libgsmd/libgsmd.c
===================================================================
--- trunk/src/target/gsm/src/libgsmd/libgsmd.c 2007-08-17 08:31:21 UTC (rev
2723)
+++ trunk/src/target/gsm/src/libgsmd/libgsmd.c 2007-08-17 08:31:49 UTC (rev
2724)
@@ -88,26 +88,32 @@
/* handle a packet that was received on the gsmd socket */
int lgsm_handle_packet(struct lgsm_handle *lh, char *buf, int len)
{
- struct gsmd_msg_hdr *gmh = (struct gsmd_msg_hdr *)buf;
+ struct gsmd_msg_hdr *gmh;
lgsm_msg_handler *handler;
-
- if (len < sizeof(*gmh))
- return -EINVAL;
-
- if (len - sizeof(*gmh) < gmh->len)
- return -EINVAL;
-
- if (gmh->msg_type >= __NUM_GSMD_MSGS)
- return -EINVAL;
-
- handler = lh->handler[gmh->msg_type];
-
- if (handler)
- return handler(lh, gmh);
- else {
- fprintf(stderr, "unable to handle packet type=%u\n",
gmh->msg_type);
- return 0;
+ int rc = 0;
+
+ while (len) {
+ if (len < sizeof(*gmh))
+ return -EINVAL;
+ gmh = (struct gsmd_msg_hdr *) buf;
+
+ if (len - sizeof(*gmh) < gmh->len)
+ return -EINVAL;
+ len -= sizeof(*gmh) + gmh->len;
+ buf += sizeof(*gmh) + gmh->len;
+
+ if (gmh->msg_type >= __NUM_GSMD_MSGS)
+ return -EINVAL;
+
+ handler = lh->handler[gmh->msg_type];
+
+ if (handler)
+ rc |= handler(lh, gmh);
+ else
+ fprintf(stderr, "unable to handle packet type=%u\n",
+ gmh->msg_type);
}
+ return rc;
}
int lgsm_register_handler(struct lgsm_handle *lh, int type, lgsm_msg_handler
*handler)
--- End Message ---
--- Begin Message ---
Author: laforge
Date: 2007-08-17 10:32:14 +0200 (Fri, 17 Aug 2007)
New Revision: 2725
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/libgsmd_network.c
Log:
From: Andrzej Zaborowski <[EMAIL PROTECTED]>
Date: Tue, 31 Jul 2007 22:26:36 +0200
Subject: [PATCH] Operations on the preferred operators list.
This makes use of the AT+CPOL variants to add / delete / list entries in the
preferred operators list on the SIM. There's some inconsistency, similarly as
with operator selection, in that we return operator names in long
alphanumeric format but we take only operators in numeric format as
parameters. Either the client will have to convert between the formats or
we should always use for example the long alphanumeric format, or maybe
do something else.
Modified: trunk/src/target/gsm/include/gsmd/usock.h
===================================================================
--- trunk/src/target/gsm/include/gsmd/usock.h 2007-08-17 08:31:49 UTC (rev
2724)
+++ trunk/src/target/gsm/include/gsmd/usock.h 2007-08-17 08:32:14 UTC (rev
2725)
@@ -70,6 +70,11 @@
GSMD_NETWORK_OPER_LIST = 6,
GSMD_NETWORK_CIND_GET = 7,
GSMD_NETWORK_DEREGISTER = 8,
+ GSMD_NETWORK_GET_NUMBER = 9,
+ GSMD_NETWORK_PREF_LIST = 10,
+ GSMD_NETWORK_PREF_DEL = 11,
+ GSMD_NETWORK_PREF_ADD = 12,
+ GSMD_NETWORK_PREF_SPACE = 13,
};
enum gsmd_msg_sms {
@@ -458,6 +463,12 @@
gsmd_oper_numeric opname_num;
};
+struct gsmd_msg_prefoper {
+ int index;
+ int is_last;
+ char opname_longalpha[16];
+};
+
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-17 08:31:49 UTC (rev
2724)
+++ trunk/src/target/gsm/include/libgsmd/misc.h 2007-08-17 08:32:14 UTC (rev
2725)
@@ -62,6 +62,12 @@
extern int lgsm_get_netreg_state(struct lgsm_handle *lh,
enum lgsm_netreg_state *state);
+/* Preferred operator list management */
+extern int lgsm_prefoper_list(struct lgsm_handle *lh);
+extern int lgsm_prefoper_delete(struct lgsm_handle *lh, int index);
+extern int lgsm_prefoper_add(struct lgsm_handle *lh, gsmd_oper_numeric oper);
+extern int lgsm_prefoper_get_space(struct lgsm_handle *lh);
+
/* 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-17 08:31:49 UTC (rev
2724)
+++ trunk/src/target/gsm/src/gsmd/usock.c 2007-08-17 08:32:14 UTC (rev
2725)
@@ -423,6 +423,10 @@
{
int len = 0;
int stat, n;
+ char opname_longalpha[16 + 1];
+ char opname_shortalpha[8 + 1];
+ char opname_num[6 + 1];
+
if (strncmp(str, "+COPS: ", 7))
goto final;
str += 7;
@@ -434,12 +438,18 @@
"(%i,\"%16[^\"]\","
"\"%8[^\"]\",\"%6[0-9]\")%n",
&stat,
- out->opname_longalpha,
- out->opname_shortalpha,
- out->opname_num,
+ opname_longalpha,
+ opname_shortalpha,
+ opname_num,
&n) < 4)
goto final;
out->stat = stat;
+ memcpy(out->opname_longalpha, opname_longalpha,
+ sizeof(out->opname_longalpha));
+ memcpy(out->opname_shortalpha, opname_shortalpha,
+ sizeof(out->opname_shortalpha));
+ memcpy(out->opname_num, opname_num,
+ sizeof(out->opname_num));
} else
if (sscanf(str,
"(%*i,\"%*[^\"]\","
@@ -480,6 +490,64 @@
return 0;
}
+static int network_pref_opers_cb(struct gsmd_atcmd *cmd, void *ctx, char *resp)
+{
+ struct gsmd_user *gu = (struct gsmd_user *) ctx;
+ struct gsmd_ucmd *ucmd;
+ struct gsmd_msg_prefoper *entry;
+ int index;
+ char opname[17];
+
+ if (cmd->ret && cmd->ret != -255)
+ return 0;
+
+ if (sscanf(resp, "+CPOL: %i,0,\"%16[^\"]\"", &index, opname) < 2)
+ return -EINVAL;
+
+ ucmd = gsmd_ucmd_fill(sizeof(*entry), GSMD_MSG_NETWORK,
+ GSMD_NETWORK_PREF_LIST, cmd->id);
+ if (!ucmd)
+ return -ENOMEM;
+
+ entry = (struct gsmd_msg_prefoper *) ucmd->buf;
+ entry->index = index;
+ entry->is_last = (cmd->ret == 0);
+ memcpy(entry->opname_longalpha, opname,
+ sizeof(entry->opname_longalpha));
+
+ usock_cmd_enqueue(ucmd, gu);
+
+ return 0;
+}
+
+static int network_pref_num_cb(struct gsmd_atcmd *cmd, void *ctx, char *resp)
+{
+ struct gsmd_user *gu = (struct gsmd_user *) ctx;
+ struct gsmd_ucmd *ucmd;
+ int min_index, max_index, size;
+
+ if (cmd->ret)
+ return 0;
+
+ /* This is not a full general case, theoretically the range string
+ * can include commas and more dashes, but we have no full parser for
+ * ranges yet. */
+ if (sscanf(resp, "+CPOL: (%i-%i)", &min_index, &max_index) < 2)
+ return -EINVAL;
+
+ ucmd = gsmd_ucmd_fill(sizeof(int), GSMD_MSG_NETWORK,
+ GSMD_NETWORK_PREF_SPACE, cmd->id);
+ if (!ucmd)
+ return -ENOMEM;
+
+ size = max_index - min_index + 1;
+ memcpy(ucmd->buf, &size, sizeof(int));
+
+ usock_cmd_enqueue(ucmd, gu);
+
+ return 0;
+}
+
static int usock_rcv_network(struct gsmd_user *gu, struct gsmd_msg_hdr *gph,
int len)
{
@@ -519,6 +587,26 @@
case GSMD_NETWORK_OPER_LIST:
cmd = atcmd_fill("AT+COPS=?", 9+1, &network_opers_cb, gu, 0);
break;
+ case GSMD_NETWORK_PREF_LIST:
+ /* Set long alphanumeric format */
+ atcmd_submit(gu->gsmd, atcmd_fill("AT+CPOL=,0", 10 + 1,
+ &null_cmd_cb, gu, 0));
+ cmd = atcmd_fill("AT+CPOL?", 8 + 1,
+ &network_pref_opers_cb, gu, 0);
+ break;
+ case GSMD_NETWORK_PREF_DEL:
+ cmdlen = sprintf(buffer, "AT+CPOL=%i", *(int *) gph->data);
+ cmd = atcmd_fill(buffer, cmdlen + 1, &null_cmd_cb, gu, 0);
+ break;
+ case GSMD_NETWORK_PREF_ADD:
+ cmdlen = sprintf(buffer, "AT+CPOL=,2,\"%.*s\"",
+ sizeof(gsmd_oper_numeric), oper);
+ cmd = atcmd_fill(buffer, cmdlen + 1, &null_cmd_cb, gu, 0);
+ break;
+ case GSMD_NETWORK_PREF_SPACE:
+ cmd = atcmd_fill("AT+CPOL=?", 9 + 1,
+ &network_pref_num_cb, gu, 0);
+ break;
default:
return -EINVAL;
}
Modified: trunk/src/target/gsm/src/libgsmd/libgsmd_network.c
===================================================================
--- trunk/src/target/gsm/src/libgsmd/libgsmd_network.c 2007-08-17 08:31:49 UTC
(rev 2724)
+++ trunk/src/target/gsm/src/libgsmd/libgsmd_network.c 2007-08-17 08:32:14 UTC
(rev 2725)
@@ -78,3 +78,53 @@
{
return lgsm_send_simple(lh, GSMD_MSG_NETWORK, GSMD_NETWORK_SIGQ_GET);
}
+
+int lgsm_prefoper_list(struct lgsm_handle *lh)
+{
+ return lgsm_send_simple(lh, GSMD_MSG_NETWORK, GSMD_NETWORK_PREF_LIST);
+}
+
+int lgsm_prefoper_delete(struct lgsm_handle *lh, int index)
+{
+ struct gsmd_msg_hdr *gmh;
+
+ gmh = lgsm_gmh_fill(GSMD_MSG_NETWORK, GSMD_NETWORK_PREF_DEL,
+ sizeof(int));
+ if (!gmh)
+ return -ENOMEM;
+
+ memcpy(gmh->data, &index, sizeof(int));
+
+ if (lgsm_send(lh, gmh) < gmh->len + sizeof(*gmh)) {
+ lgsm_gmh_free(gmh);
+ return -EIO;
+ }
+
+ lgsm_gmh_free(gmh);
+ return 0;
+}
+
+int lgsm_prefoper_add(struct lgsm_handle *lh, gsmd_oper_numeric oper)
+{
+ struct gsmd_msg_hdr *gmh;
+
+ gmh = lgsm_gmh_fill(GSMD_MSG_NETWORK, GSMD_NETWORK_PREF_ADD,
+ 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_prefoper_get_space(struct lgsm_handle *lh)
+{
+ return lgsm_send_simple(lh, GSMD_MSG_NETWORK, GSMD_NETWORK_PREF_SPACE);
+}
--- End Message ---
--- Begin Message ---
Author: laforge
Date: 2007-08-17 10:32:50 +0200 (Fri, 17 Aug 2007)
New Revision: 2726
Modified:
trunk/src/target/gsm/include/gsmd/usock.h
trunk/src/target/gsm/include/libgsmd/phonebook.h
trunk/src/target/gsm/src/gsmd/usock.c
trunk/src/target/gsm/src/libgsmd/libgsmd_phonebook.c
trunk/src/target/gsm/src/util/Makefile.am
trunk/src/target/gsm/src/util/shell.c
Log:
SIM Phonebook access implementation.
This patch adds primitive-but-working support for SIM phonebook access,
including phonebook memory storage and entry read/write/delete. Also,
libgsmd-tools shell is modified to perform listing actions.
API changes:
lgsm_pb_read_entryies -> lgsm_pb_read_entries
lgsm_pb_list_storage (new):
List of supported phonebook memory storage.
lgsm_pb_set_storage (new);
Select phonebook memory storage.
lgsmd_pb_del_entry -> lgsm_pb_del_entry
lgsmd_pb_write_entry -> lgsm_pb_write_entry
Modified: trunk/src/target/gsm/include/gsmd/usock.h
===================================================================
--- trunk/src/target/gsm/include/gsmd/usock.h 2007-08-17 08:32:14 UTC (rev
2725)
+++ trunk/src/target/gsm/include/gsmd/usock.h 2007-08-17 08:32:50 UTC (rev
2726)
@@ -2,6 +2,7 @@
#define _GSMD_USOCK_H
#include <gsmd/event.h>
+#include <common/linux_list.h>
#define GSMD_UNIX_SOCKET "\0gsmd"
//#define GSMD_UNIX_SOCKET_TYPE SOCK_SEQPACKET
@@ -192,6 +193,8 @@
GSMD_PHONEBOOK_WRITE = 4,
GSMD_PHONEBOOK_DELETE = 5,
GSMD_PHONEBOOK_GET_SUPPORT = 6,
+ GSMD_PHONEBOOK_LIST_STORAGE = 7,
+ GSMD_PHONEBOOK_SET_STORAGE = 8,
};
/* Type-of-Address, Numbering-Plan-Identification field, GSM 03.40, 9.1.2.5 */
@@ -423,6 +426,7 @@
#define GSMD_PB_NUMB_MAXLEN 44
#define GSMD_PB_TEXT_MAXLEN 14
struct gsmd_phonebook {
+ struct llist_head list;
u_int8_t index;
char numb[GSMD_PB_NUMB_MAXLEN+1];
u_int8_t type;
@@ -469,6 +473,11 @@
char opname_longalpha[16];
};
+struct gsmd_phonebook_storage {
+ struct llist_head list;
+ char storage[3];
+} __attribute__ ((packed));
+
struct gsmd_msg_hdr {
u_int8_t version;
u_int8_t msg_type;
@@ -481,8 +490,6 @@
#ifdef __GSMD__
-#include <common/linux_list.h>
-
#include <gsmd/usock.h>
#include <gsmd/gsmd.h>
Modified: trunk/src/target/gsm/include/libgsmd/phonebook.h
===================================================================
--- trunk/src/target/gsm/include/libgsmd/phonebook.h 2007-08-17 08:32:14 UTC
(rev 2725)
+++ trunk/src/target/gsm/include/libgsmd/phonebook.h 2007-08-17 08:32:50 UTC
(rev 2726)
@@ -78,6 +78,12 @@
extern int lgsm_pb_set_entry(struct lgsm_handle *lh,
struct lgsm_pb_entry *pb);
+/* List of supported phonebook memory storage */
+extern int lgsm_pb_list_storage(struct lgsm_handle *lh);
+
+/* Select phonebook memory storage */
+extern int lgsm_pb_set_storage(struct lgsm_handle *lh, char *storage);
+
/* Find phonebook entires which alphanumeric filed start
* with string <findtext> */
extern int lgsm_pb_find_entry(struct lgsm_handle *lh,
@@ -87,14 +93,14 @@
extern int lgsm_pb_read_entry(struct lgsm_handle *lh, int index);
/* Read phonebook entries in location number range */
-extern int lgsm_pb_read_entryies(struct lgsm_handle *lh,
+extern int lgsm_pb_read_entries(struct lgsm_handle *lh,
const struct lgsm_phonebook_readrg *pb_readrg);
/* Delete phonebook entry in location index */
-extern int lgsmd_pb_del_entry(struct lgsm_handle *lh, int index);
+extern int lgsm_pb_del_entry(struct lgsm_handle *lh, int index);
/* Write phonebook entry in location */
-extern int lgsmd_pb_write_entry(struct lgsm_handle *lh,
+extern int lgsm_pb_write_entry(struct lgsm_handle *lh,
const struct lgsm_phonebook *pb);
/* Get the location range/nlength/tlength supported */
Modified: trunk/src/target/gsm/src/gsmd/usock.c
===================================================================
--- trunk/src/target/gsm/src/gsmd/usock.c 2007-08-17 08:32:14 UTC (rev
2725)
+++ trunk/src/target/gsm/src/gsmd/usock.c 2007-08-17 08:32:50 UTC (rev
2726)
@@ -984,14 +984,16 @@
}
#endif
-#if 0
static int phonebook_find_cb(struct gsmd_atcmd *cmd, void *ctx, char *resp)
{
struct gsmd_user *gu = ctx;
struct gsmd_ucmd *ucmd;
- /* FIXME: implementation */
- ucmd = gsmd_ucmd_fill(strlen(resp)+1, GSMD_MSG_PHONEBOOK,
+ DEBUGP("resp: %s\n", resp);
+
+ /* FIXME: using link list, also we need to handle the case of
+ * no query result */
+ ucmd = gsmd_ucmd_fill(strlen(resp) + 1, GSMD_MSG_PHONEBOOK,
GSMD_PHONEBOOK_FIND, 0);
if (!ucmd)
return -ENOMEM;
@@ -1009,42 +1011,58 @@
struct gsmd_ucmd *ucmd;
char *fcomma, *lcomma;
char *ptr;
- /* FIXME: We should check this case "When the entry is empty" */
+
+ DEBUGP("resp: %s\n", resp);
+
ucmd = gsmd_ucmd_fill(sizeof(*gp), GSMD_MSG_PHONEBOOK,
GSMD_PHONEBOOK_READ, 0);
if (!ucmd)
- return -ENOMEM;
+ return -ENOMEM;
+
gp = (struct gsmd_phonebook *) ucmd->buf;
- ptr = strchr(resp, ' ');
- gp->index = atoi(ptr+1);
- fcomma = strchr(resp, '"');
- lcomma = strchr(fcomma+1, '"');
- strncpy(gp->numb, fcomma+1, (lcomma-fcomma-1));
- gp->numb[(lcomma-fcomma)-1] = '\0';
+ /* check the record is empty or not */
+ if (!strncmp(resp, "+CPBR", 5)) {
+ ptr = strchr(resp, ' ');
+ gp->index = atoi(ptr + 1);
+
+ fcomma = strchr(resp, '"');
+ lcomma = strchr(fcomma + 1, '"');
+ strncpy(gp->numb, fcomma + 1, (lcomma - fcomma - 1));
+ gp->numb[(lcomma-fcomma) - 1] = '\0';
- gp->type = atoi(lcomma+2);
+ gp->type = atoi(lcomma + 2);
- ptr = strrchr(resp, ',');
- fcomma = ptr+1;
- lcomma = strchr(fcomma+1, '"');
- strncpy(gp->text, fcomma+1, (lcomma-fcomma-1));
- gp->text[(lcomma-fcomma)-1] = '\0';
-
+ ptr = strrchr(resp, ',');
+ fcomma = ptr + 1;
+ lcomma = strchr(fcomma + 1, '"');
+ strncpy(gp->text, fcomma + 1, (lcomma-fcomma - 1));
+ gp->text[(lcomma - fcomma) - 1] = '\0';
+ }
+ else
+ gp->index = 0;
+
usock_cmd_enqueue(ucmd, gu);
-
+
return 0;
}
static int phonebook_readrg_cb(struct gsmd_atcmd *cmd, void *ctx, char *resp)
{
struct gsmd_user *gu = ctx;
- struct gsmd_ucmd *ucmd;
-
- /* FIXME: implementation */
-
+ struct gsmd_ucmd *ucmd;
+
+ DEBUGP("resp: %s\n", resp);
+
+ /*
+ * +CPBR: 4,"1234",129,"6C5F745E7965"
+ * +CPBR: 5,"5678",129,"800062115BB6"
+ * +CPBR: 6,"7890",129,"810280AA591A"
+ * +CPBR: 8,"36874",129,"005300650061006E"
+ *
+ */
ucmd = gsmd_ucmd_fill(strlen(resp)+1, GSMD_MSG_PHONEBOOK,
GSMD_PHONEBOOK_READRG, 0);
if (!ucmd)
@@ -1059,9 +1077,11 @@
static int phonebook_write_cb(struct gsmd_atcmd *cmd, void *ctx, char *resp)
{
- struct gsmd_user *gu = ctx;
- struct gsmd_ucmd *ucmd;
-
+ struct gsmd_user *gu = ctx;
+ struct gsmd_ucmd *ucmd;
+
+ DEBUGP("resp: %s\n", resp);
+
ucmd = gsmd_ucmd_fill(strlen(resp)+1, GSMD_MSG_PHONEBOOK,
GSMD_PHONEBOOK_WRITE, 0);
if (!ucmd)
@@ -1076,9 +1096,11 @@
static int phonebook_delete_cb(struct gsmd_atcmd *cmd, void *ctx, char *resp)
{
- struct gsmd_user *gu = ctx;
- struct gsmd_ucmd *ucmd;
-
+ struct gsmd_user *gu = ctx;
+ struct gsmd_ucmd *ucmd;
+
+ DEBUGP("resp: %s\n", resp);
+
ucmd = gsmd_ucmd_fill(strlen(resp)+1, GSMD_MSG_PHONEBOOK,
GSMD_PHONEBOOK_DELETE, 0);
if (!ucmd)
@@ -1091,19 +1113,23 @@
return 0;
}
-static int phonebook_support_cb(struct gsmd_atcmd *cmd, void *ctx, char *resp)
+static int phonebook_get_support_cb(struct gsmd_atcmd *cmd, void *ctx, char
*resp)
{
+ /* TODO: Need to handle command error */
+ /* +CPBR: (1-100),44,16 */
struct gsmd_user *gu = ctx;
struct gsmd_phonebook_support *gps;
struct gsmd_ucmd *ucmd;
char *fcomma, *lcomma;
char *dash;
+
+ DEBUGP("resp: %s\n", resp);
ucmd = gsmd_ucmd_fill(sizeof(*gps), GSMD_MSG_PHONEBOOK,
GSMD_PHONEBOOK_GET_SUPPORT, 0);
if (!ucmd)
return -ENOMEM;
-
+
gps = (struct gsmd_phonebook_support *) ucmd->buf;
dash = strchr(resp, '-');
@@ -1111,7 +1137,7 @@
talloc_free(ucmd);
return -EIO;
}
- gps->index = atoi(dash+1);
+ gps->index = atoi(dash + 1);
fcomma = strchr(resp, ',');
if (!fcomma) {
@@ -1131,8 +1157,33 @@
return 0;
}
-static int usock_rcv_phonebook(struct gsmd_user *gu, struct gsmd_msg_hdr *gph,
- int len)
+static int phonebook_list_storage_cb(struct gsmd_atcmd *cmd,
+ void *ctx, char *resp)
+{
+ /* +CPBS: ("EN","BD","FD","DC","LD","RC","LR","MT","AD",
+ * "SM","SD","MC","LM","AF","ON","UD") */
+ /* TODO; using link list ; need to handle command error */
+ struct gsmd_user *gu = ctx;
+ struct gsmd_ucmd *ucmd;
+
+ DEBUGP("resp: %s\n", resp);
+
+ ucmd = gsmd_ucmd_fill(strlen(resp) + 1,
+ GSMD_MSG_PHONEBOOK,
+ GSMD_PHONEBOOK_LIST_STORAGE, 0);
+
+ if (!ucmd)
+ return -ENOMEM;
+
+ strcpy(ucmd->buf, resp);
+
+ usock_cmd_enqueue(ucmd, gu);
+
+ return 0;
+}
+
+static int usock_rcv_phonebook(struct gsmd_user *gu,
+ struct gsmd_msg_hdr *gph,int len)
{
struct gsmd_atcmd *cmd = NULL;
struct gsmd_phonebook_readrg *gpr;
@@ -1140,15 +1191,38 @@
struct gsmd_phonebook_find *gpf;
int *index;
int atcmd_len;
+ char *storage;
char buf[1024];
-
+
switch (gph->msg_subtype) {
+ case GSMD_PHONEBOOK_LIST_STORAGE:
+ cmd = atcmd_fill("AT+CPBS=?", 9 + 1,
+ &phonebook_list_storage_cb,
+ gu, gph->id);
+ break;
+ case GSMD_PHONEBOOK_SET_STORAGE:
+ if (len < sizeof(*gph) + 3)
+ return -EINVAL;
+
+ storage = (char*) ((void *)gph + sizeof(*gph));
+
+ /* ex. AT+CPBS="ME" */
+ atcmd_len = 1 + strlen("AT+CPBS=\"") + 2 + strlen("\"");
+ cmd = atcmd_fill("AT+CPBS=\"", atcmd_len,
+ &usock_cmd_cb, gu, gph->id);
+
+ if (!cmd)
+ return -ENOMEM;
+
+ sprintf(cmd->buf, "AT+CPBS=\"%s\"", storage);
+ break;
case GSMD_PHONEBOOK_FIND:
if(len < sizeof(*gph) + sizeof(*gpf))
return -EINVAL;
- gpf = (struct gsmd_phonebook_find *) ((void *)gph +
sizeof(*gph));
-
- atcmd_len = 1 + strlen("AT+CPBF=\"") + strlen(gpf->findtext) +
strlen("\"");
+ gpf = (struct gsmd_phonebook_find *) ((void *)gph +
sizeof(*gph));
+
+ atcmd_len = 1 + strlen("AT+CPBF=\"") +
+ strlen(gpf->findtext) + strlen("\"");
cmd = atcmd_fill("AT+CPBF=\"", atcmd_len,
&phonebook_find_cb, gu, gph->id);
if (!cmd)
@@ -1158,10 +1232,12 @@
case GSMD_PHONEBOOK_READ:
if(len < sizeof(*gph) + sizeof(int))
return -EINVAL;
+
index = (int *) ((void *)gph + sizeof(*gph));
-
- sprintf(buf, "%d", *index);
+ sprintf(buf, "%d", *index);
+
+ /* ex, AT+CPBR=23 */
atcmd_len = 1 + strlen("AT+CPBR=") + strlen(buf);
cmd = atcmd_fill("AT+CPBR=", atcmd_len,
&phonebook_read_cb, gu, gph->id);
@@ -1176,6 +1252,7 @@
sprintf(buf, "%d,%d", gpr->index1, gpr->index2);
+ /* ex, AT+CPBR=1,100 */
atcmd_len = 1 + strlen("AT+CPBR=") + strlen(buf);
cmd = atcmd_fill("AT+CPBR=", atcmd_len,
&phonebook_readrg_cb, gu, gph->id);
@@ -1188,8 +1265,9 @@
return -EINVAL;
gp = (struct gsmd_phonebook *) ((void *)gph + sizeof(*gph));
- sprintf(buf, "%d,\"%s\",%d,\"%s\"", gp->index, gp->numb,
gp->type, gp->text);
-
+ sprintf(buf, "%d,\"%s\",%d,\"%s\"",
+ gp->index, gp->numb, gp->type, gp->text);
+
atcmd_len = 1 + strlen("AT+CPBW=") + strlen(buf);
cmd = atcmd_fill("AT+CPBW=", atcmd_len,
&phonebook_write_cb, gu, gph->id);
@@ -1204,6 +1282,7 @@
sprintf(buf, "%d", *index);
+ /* ex, AT+CPBW=3*/
atcmd_len = 1 + strlen("AT+CPBW=") + strlen(buf);
cmd = atcmd_fill("AT+CPBW=", atcmd_len,
&phonebook_delete_cb, gu, gph->id);
@@ -1213,7 +1292,7 @@
break;
case GSMD_PHONEBOOK_GET_SUPPORT:
cmd = atcmd_fill("AT+CPBR=?", 9+1,
- &phonebook_support_cb, gu, gph->id);
+ &phonebook_get_support_cb, gu, gph->id);
break;
default:
return -EINVAL;
@@ -1224,7 +1303,6 @@
else
return 0;
}
-#endif
static usock_msg_handler *pcmd_type_handlers[__NUM_GSMD_MSGS] = {
[GSMD_MSG_PASSTHROUGH] = &usock_rcv_passthrough,
@@ -1235,7 +1313,7 @@
[GSMD_MSG_NETWORK] = &usock_rcv_network,
[GSMD_MSG_SMS] = &usock_rcv_sms,
[GSMD_MSG_CB] = &usock_rcv_cb,
- //[GSMD_MSG_PHONEBOOK] = &usock_rcv_phonebook,
+ [GSMD_MSG_PHONEBOOK] = &usock_rcv_phonebook,
};
static int usock_rcv_pcmd(struct gsmd_user *gu, char *buf, int len)
Modified: trunk/src/target/gsm/src/libgsmd/libgsmd_phonebook.c
===================================================================
--- trunk/src/target/gsm/src/libgsmd/libgsmd_phonebook.c 2007-08-17
08:32:14 UTC (rev 2725)
+++ trunk/src/target/gsm/src/libgsmd/libgsmd_phonebook.c 2007-08-17
08:32:50 UTC (rev 2726)
@@ -11,6 +11,38 @@
#include "lgsm_internals.h"
+
+int lgsm_pb_list_storage(struct lgsm_handle *lh)
+{
+ return lgsm_send_simple(lh, GSMD_MSG_PHONEBOOK,
+ GSMD_PHONEBOOK_LIST_STORAGE);
+}
+
+int lgsm_pb_set_storage(struct lgsm_handle *lh, char *storage)
+{
+ struct gsmd_msg_hdr *gmh;
+ int rc;
+
+ gmh = lgsm_gmh_fill(GSMD_MSG_PHONEBOOK,
+ GSMD_PHONEBOOK_SET_STORAGE, 3);
+
+ if (!gmh)
+ return -ENOMEM;
+
+ strncpy((char*)gmh->data, storage, 2);
+ gmh->data[2] = '\0';
+
+ rc = lgsm_send(lh, gmh);
+ if (rc < gmh->len + 3) {
+ lgsm_gmh_free(gmh);
+ return -EIO;
+ }
+
+ lgsm_gmh_free(gmh);
+
+ return 0;
+}
+
int lgsm_pb_find_entry(struct lgsm_handle *lh,
const struct lgsm_phonebook_find *pb_find)
{
@@ -37,6 +69,7 @@
return 0;
}
+
int lgsm_pb_read_entry(struct lgsm_handle *lh, int index)
{
struct gsmd_msg_hdr *gmh;
@@ -46,6 +79,7 @@
GSMD_PHONEBOOK_READ, sizeof(int));
if (!gmh)
return -ENOMEM;
+
*(int *) gmh->data = index;
rc = lgsm_send(lh, gmh);
@@ -59,7 +93,7 @@
return 0;
}
-int lgsm_pb_read_entryies(struct lgsm_handle *lh,
+int lgsm_pb_read_entries(struct lgsm_handle *lh,
const struct lgsm_phonebook_readrg *pb_readrg)
{
struct gsmd_msg_hdr *gmh;
@@ -85,7 +119,7 @@
return 0;
}
-int lgsmd_pb_del_entry(struct lgsm_handle *lh, int index)
+int lgsm_pb_del_entry(struct lgsm_handle *lh, int index)
{
struct gsmd_msg_hdr *gmh;
int rc;
@@ -108,7 +142,7 @@
return 0;
}
-int lgsmd_pb_write_entry(struct lgsm_handle *lh,
+int lgsm_pb_write_entry(struct lgsm_handle *lh,
const struct lgsm_phonebook *pb)
{
/* FIXME: only support alphabet now */
@@ -139,7 +173,6 @@
return 0;
}
-
int lgsm_pb_get_support(struct lgsm_handle *lh)
{
return lgsm_send_simple(lh, GSMD_MSG_PHONEBOOK,
GSMD_PHONEBOOK_GET_SUPPORT);
Modified: trunk/src/target/gsm/src/util/Makefile.am
===================================================================
--- trunk/src/target/gsm/src/util/Makefile.am 2007-08-17 08:32:14 UTC (rev
2725)
+++ trunk/src/target/gsm/src/util/Makefile.am 2007-08-17 08:32:50 UTC (rev
2726)
@@ -3,8 +3,9 @@
bin_PROGRAMS = libgsmd-tool
-libgsmd_tool_SOURCES = libgsmd-tool.c shell.c event.c pin.c atcmd.c
-libgsmd_tool_LDADD = ../libgsmd/libgsmd.la
+libgsmd_tool_SOURCES = libgsmd-tool.c shell.c event.c pin.c atcmd.c \
+ $(top_srcdir)/src/gsmd/talloc.c
+libgsmd_tool_LDADD = $(top_builddir)/src/libgsmd/libgsmd.la
libgsmd_tool_LDFLAGS = -dynamic
noinst_HEADERS = atcmd.h event.h pin.h shell.h
Modified: trunk/src/target/gsm/src/util/shell.c
===================================================================
--- trunk/src/target/gsm/src/util/shell.c 2007-08-17 08:32:14 UTC (rev
2725)
+++ trunk/src/target/gsm/src/util/shell.c 2007-08-17 08:32:50 UTC (rev
2726)
@@ -34,8 +34,17 @@
#include <gsmd/usock.h>
#include <gsmd/ts0705.h>
+#ifndef __GSMD__
+#define __GSMD__
+#include <gsmd/talloc.h>
+#undef __GSMD__
+#endif
+
#define STDIN_BUF_SIZE 1024
+static LLIST_HEAD(storage_list);
+static LLIST_HEAD(phonebook_list);
+
/* this is the handler for receiving passthrough responses */
static int pt_msghandler(struct lgsm_handle *lh, struct gsmd_msg_hdr *gmh)
{
@@ -48,28 +57,107 @@
{
struct gsmd_phonebook *gp;
struct gsmd_phonebook_support *gps;
+ struct gsmd_phonebook_storage *gpst;
char *payload;
+ char *fcomma, *lcomma, *ptr = NULL;
+ char buf[128];
switch (gmh->msg_subtype) {
case GSMD_PHONEBOOK_FIND:
- break;
case GSMD_PHONEBOOK_READRG:
payload = (char *)gmh + sizeof(*gmh);
- printf("%s\n", payload);
+
+ if (!strncmp(payload, "+CPBR", 5) ||
+ !strncmp(payload, "+CPBF", 5)) {
+ gp = (struct gsmd_phonebook *) malloc(sizeof(struct
gsmd_phonebook));
+ ptr = strchr(payload, ' ');
+ gp->index = atoi(ptr+1);
+
+ fcomma = strchr(payload, '"');
+ lcomma = strchr(fcomma+1, '"');
+ strncpy(gp->numb, fcomma + 1, (lcomma-fcomma-1));
+ gp->numb[(lcomma - fcomma) - 1] = '\0';
+
+ gp->type = atoi(lcomma + 2);
+
+ ptr = strrchr(payload, ',');
+ fcomma = ptr + 1;
+ lcomma = strchr(fcomma + 1, '"');
+ strncpy(gp->text, fcomma + 1, (lcomma - fcomma - 1));
+ gp->text[(lcomma - fcomma) - 1] = '\0';
+
+ llist_add_tail(&gp->list, &phonebook_list);
+
+#if 0
+ llist_for_each_entry(gp, &phonebook_list, list) {
+ printf("%d, %s, %d, %s\n", gp->index, gp->numb,
gp->type, gp->text);
+ }
+#endif
+ printf("%d, %s, %d, %s\n", gp->index, gp->numb,
gp->type, gp->text);
+ }
+ else
+ printf("%s\n", payload);
break;
case GSMD_PHONEBOOK_READ:
gp = (struct gsmd_phonebook *) ((char *)gmh + sizeof(*gmh));
- printf("%d, %s, %d, %s\n", gp->index, gp->numb, gp->type,
gp->text);
+ if (gp->index)
+ printf("%d, %s, %d, %s\n",
+ gp->index, gp->numb,
+ gp->type, gp->text);
+ else
+ printf("Empty\n");
break;
- case GSMD_PHONEBOOK_WRITE:
- case GSMD_PHONEBOOK_DELETE:
- payload = (char *)gmh + sizeof(*gmh);
- printf("%s\n", payload);
- break;
case GSMD_PHONEBOOK_GET_SUPPORT:
gps = (struct gsmd_phonebook_support *) ((char *)gmh +
sizeof(*gmh));
printf("(1-%d), %d, %d\n", gps->index, gps->nlength,
gps->tlength);
break;
+ case GSMD_PHONEBOOK_LIST_STORAGE:
+ payload = (char *)gmh + sizeof(*gmh);
+
+ if (!strncmp(payload, "+CPBS", 5)) {
+ char* delim = "(,";
+ struct gsmd_phonebook_storage *cur, *cur2;
+
+ /* Remove previous record */
+ if (!llist_empty(&storage_list)) {
+ llist_for_each_entry_safe(cur, cur2,
+ &storage_list, list) {
+ llist_del(&cur->list);
+ talloc_free(cur);
+ }
+ }
+
+ ptr = strpbrk(payload, delim);
+
+ while ( ptr ) {
+ gpst = (struct gsmd_phonebook_storage *)
malloc(sizeof(struct gsmd_phonebook_storage));
+ strncpy(gpst->storage, ptr+2, 2);
+ gpst->storage[2] = '\0';
+
+ ptr = strpbrk(ptr+2, delim);
+
+ llist_add_tail(&gpst->list, &storage_list);
+ }
+
+ if (llist_empty(&storage_list))
+ return 0;
+
+ llist_for_each_entry(cur, &storage_list, list) {
+ printf("\n%s",cur->storage);
+ }
+
+ printf("\n");
+ }
+ else
+ printf("%s\n", payload);
+ break;
+ case GSMD_PHONEBOOK_WRITE:
+ case GSMD_PHONEBOOK_DELETE:
+ case GSMD_PHONEBOOK_SET_STORAGE:
+ /* TODO: Need to handle error */
+ payload = (char *)gmh + sizeof(*gmh);
+ printf("%s\n", payload);
+ break;
default:
return -EINVAL;
}
@@ -270,6 +358,8 @@
"\tpf\tPB Find (pff=indtext)\n"
"\tpw\tPB Write (pw=index,number,text)\n"
"\tps\tPB Support\n"
+ "\tpm\tPB Memory\n"
+ "\tpp\tPB Set Memory (pp=storage)\n"
"\tsd\tSMS Delete (sd=index,delflg)\n"
"\tsl\tSMS List (sl=stat)\n"
"\tsr\tSMS Read (sr=index)\n"
@@ -392,27 +482,51 @@
} else if ( !strncmp(buf, "pd", 2)) {
printf("Delete Phonebook Entry\n");
ptr = strchr(buf, '=');
- lgsmd_pb_del_entry(lgsmh, atoi(ptr+1));
+ lgsm_pb_del_entry(lgsmh, atoi(ptr+1));
} else if ( !strncmp(buf, "prr", 3)) {
printf("Read Phonebook Entries\n");
struct lgsm_phonebook_readrg pb_readrg;
+ struct gsmd_phonebook *gp_cur, *gp_cur2;
+ /* Remove records */
+ if (!llist_empty(&phonebook_list)) {
+ llist_for_each_entry_safe(gp_cur,
+ gp_cur2,
+ &phonebook_list,
+ list) {
+ llist_del(&gp_cur->list);
+ talloc_free(gp_cur);
+ }
+ }
+
ptr = strchr(buf, '=');
pb_readrg.index1 = atoi(ptr+1);
ptr = strchr(buf, ',');
- pb_readrg.index2 = atoi(ptr+1);
-
- lgsm_pb_read_entryies(lgsmh, &pb_readrg);
- } else if ( !strncmp(buf, "pr", 2)) {
- printf("Read Phonebook Entry\n");
- ptr = strchr(buf, '=');
+ pb_readrg.index2 = atoi(ptr+1);
+ lgsm_pb_read_entries(lgsmh, &pb_readrg);
+ } else if ( !strncmp(buf, "pr", 2)) {
+ ptr = strchr(buf, '=');
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;
+ struct gsmd_phonebook *gp_cur, *gp_cur2;
+ /* Remove records */
+ if (!llist_empty(&phonebook_list)) {
+ llist_for_each_entry_safe(gp_cur,
+ gp_cur2,
+ &phonebook_list,
+ list) {
+ llist_del(&gp_cur->list);
+ talloc_free(gp_cur);
+ }
+ }
+
ptr = strchr(buf, '=');
- strncpy(pb_find.findtext, ptr+1,
sizeof(pb_find.findtext)-1);
+ strncpy(pb_find.findtext,
+ ptr + 1,
+ sizeof(pb_find.findtext) - 1);
pb_find.findtext[strlen(ptr+1)] = '\0';
lgsm_pb_find_entry(lgsmh, &pb_find);
@@ -425,16 +539,25 @@
fcomma = strchr(buf, ',');
lcomma = strchr(fcomma+1, ',');
- strncpy(pb.numb, fcomma+1, (lcomma-fcomma-1));
- pb.numb[(lcomma-fcomma-1)] = '\0';
- if ( '+' == pb.numb[0] )
+ strncpy(pb.numb, fcomma + 1, (lcomma - fcomma -
1));
+ pb.numb[(lcomma - fcomma - 1)] = '\0';
+ if ('+' == pb.numb[0])
pb.type = LGSM_PB_ATYPE_INTL;
else
pb.type = LGSM_PB_ATYPE_OTHE;
- strncpy(pb.text, lcomma+1, strlen(lcomma+1));
- pb.text[strlen(lcomma+1)] = '\0';
-
- lgsmd_pb_write_entry(lgsmh, &pb);
+ strncpy(pb.text, lcomma + 1, strlen(lcomma +
1));
+ pb.text[strlen(lcomma + 1)] = '\0';
+
+ lgsm_pb_write_entry(lgsmh, &pb);
+ } else if ( !strncmp(buf, "pm", 2)) {
+ lgsm_pb_list_storage(lgsmh);
+ } else if ( !strncmp(buf, "pp", 2)) {
+ char storage[3];
+
+ ptr = strchr(buf, '=');
+ strncpy(storage, (ptr+1), 2);
+
+ lgsm_pb_set_storage(lgsmh, storage);
} else if ( !strncmp(buf, "ps", 2)) {
printf("Get Phonebook Support\n");
lgsm_pb_get_support(lgsmh);
--- End Message ---
_______________________________________________
commitlog mailing list
[email protected]
http://lists.openmoko.org/mailman/listinfo/commitlog