summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/gsmd/unsolicited.h3
-rw-r--r--src/gsmd/gsmd.c2
-rw-r--r--src/gsmd/sms_cb.c3
-rw-r--r--src/gsmd/unsolicited.c77
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,
personal git repositories of Harald Welte. Your mileage may vary