From 929473af86307cb76dcb75183094c56c9fce2939 Mon Sep 17 00:00:00 2001 From: laforge Date: Thu, 16 Aug 2007 04:25:26 +0000 Subject: Dynamic registration of unsolicited responses (Andrzej Zaborowski) git-svn-id: http://svn.openmoko.org/trunk/src/target/gsm@2712 99fdad57-331a-0410-800a-d7fa5415bdb3 --- include/gsmd/unsolicited.h | 3 ++ src/gsmd/gsmd.c | 2 ++ src/gsmd/sms_cb.c | 3 ++ src/gsmd/unsolicited.c | 77 +++++++++++++++++++++++++++------------------- 4 files changed, 54 insertions(+), 31 deletions(-) diff --git a/include/gsmd/unsolicited.h b/include/gsmd/unsolicited.h index e7f17c5..544c1ce 100644 --- a/include/gsmd/unsolicited.h +++ b/include/gsmd/unsolicited.h @@ -12,6 +12,9 @@ struct gsmd_unsolicit { extern int unsolicited_parse(struct gsmd *g, char *buf, int len, const char *param); extern int generate_event_from_cme(struct gsmd *g, unsigned int cme_error); +extern void unsolicited_generic_init(struct gsmd *g); +extern int unsolicited_register_array(const struct gsmd_unsolicit *arr, + int len); #endif /* __GSMD__ */ diff --git a/src/gsmd/gsmd.c b/src/gsmd/gsmd.c index 5e9b046..3d52eeb 100644 --- a/src/gsmd/gsmd.c +++ b/src/gsmd/gsmd.c @@ -477,6 +477,8 @@ int main(int argc, char **argv) /* select a vendor plugin */ gsmd_vendor_plugin_find(&g); + unsolicited_init(&g); + if (g.interpreter_ready) { gsmd_initsettings(&g); diff --git a/src/gsmd/sms_cb.c b/src/gsmd/sms_cb.c index 9884bfb..630518f 100644 --- a/src/gsmd/sms_cb.c +++ b/src/gsmd/sms_cb.c @@ -315,6 +315,9 @@ int sms_cb_init(struct gsmd *gsmd) struct gsmd_atcmd *atcmd; char buffer[10]; + unsolicited_register_array(gsm0705_unsolicit, + ARRAY_SIZE(gsm0705_unsolicit)); + atcmd = atcmd_fill("AT+CSMS=0", 9 + 1, NULL, gsmd, 0); if (!atcmd) return -ENOMEM; diff --git a/src/gsmd/unsolicited.c b/src/gsmd/unsolicited.c index f9351d2..4bf4833 100644 --- a/src/gsmd/unsolicited.c +++ b/src/gsmd/unsolicited.c @@ -358,49 +358,31 @@ static const struct gsmd_unsolicit gsm0707_unsolicit[] = { */ }; +static struct gsmd_unsolicit unsolicit[256] = {{ 0, 0 }}; + /* called by midlevel parser if a response seems unsolicited */ int unsolicited_parse(struct gsmd *g, char *buf, int len, const char *param) { - int i, rc; + struct gsmd_unsolicit *i; + int rc; struct gsmd_vendor_plugin *vpl = g->vendorpl; - /* call vendor-specific unsolicited code parser */ - if (vpl && vpl->num_unsolicit) { - for (i = 0; i < vpl->num_unsolicit; i++) { - const char *colon; - if (strncmp(buf, vpl->unsolicit[i].prefix, - strlen(vpl->unsolicit[i].prefix))) - continue; - - colon = strchr(buf, ':') + 2; - if (colon > buf+len) - colon = NULL; - - rc = vpl->unsolicit[i].parse(buf, len, colon, g); - if (rc < 0) - gsmd_log(GSMD_ERROR, "error %d during parse of " - "vendor unsolicied response `%s'\n", - rc, buf); - return rc; - } - } - - /* call generic unsolicited code parser */ - for (i = 0; i < ARRAY_SIZE(gsm0707_unsolicit); i++) { + /* call unsolicited code parser */ + for (i = unsolicit; i->prefix; i ++) { const char *colon; - if (strncmp(buf, gsm0707_unsolicit[i].prefix, - strlen(gsm0707_unsolicit[i].prefix))) + if (strncmp(buf, i->prefix, strlen(i->prefix))) continue; - + colon = strchr(buf, ':') + 2; if (colon > buf+len) colon = NULL; - rc = gsm0707_unsolicit[i].parse(buf, len, colon, g); + rc = i->parse(buf, len, colon, g); if (rc < 0) - gsmd_log(GSMD_ERROR, "error %d during parse of " - "unsolicied response `%s'\n", rc, buf); - return rc; + gsmd_log(GSMD_ERROR, "error %d during parsing of " + "an unsolicied response `%s'\n", + rc, buf); + return rc; } gsmd_log(GSMD_NOTICE, "no parser for unsolicited response `%s'\n", buf); @@ -408,6 +390,39 @@ int unsolicited_parse(struct gsmd *g, char *buf, int len, const char *param) return -ENOENT; } +int unsolicited_register_array(const struct gsmd_unsolicit *arr, int len) +{ + int curlen = 0; + + while (unsolicit[curlen ++].prefix); + if (len + curlen > ARRAY_SIZE(unsolicit)) + return -ENOMEM; + + /* Add at the beginning for overriding to be possible */ + memmove(&unsolicit[len], unsolicit, + sizeof(struct gsmd_unsolicit) * curlen); + memcpy(unsolicit, arr, + sizeof(struct gsmd_unsolicit) * len); + + return 0; +} + +void unsolicited_init(struct gsmd *g) +{ + struct gsmd_vendor_plugin *vpl = g->vendorpl; + + /* register generic unsolicited code parser */ + unsolicited_register_array(gsm0707_unsolicit, + ARRAY_SIZE(gsm0707_unsolicit)); + + /* register vendor-specific unsolicited code parser */ + if (vpl && vpl->num_unsolicit) + if (unsolicited_register_array(vpl->unsolicit, + vpl->num_unsolicit)) + gsmd_log(GSMD_ERROR, "registering vendor-specific " + "unsolicited responses failed\n"); +} + static unsigned int errors_creating_events[] = { GSM0707_CME_PHONE_FAILURE, GSM0707_CME_PHONE_NOCONNECT, -- cgit v1.2.3