summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/gsmd/usock.h1
-rw-r--r--src/gsmd/usock.c32
-rw-r--r--src/libgsmd/libgsmd_network.c5
-rw-r--r--src/util/shell.c27
4 files changed, 65 insertions, 0 deletions
diff --git a/include/gsmd/usock.h b/include/gsmd/usock.h
index 6b2bc4a..cfff571 100644
--- a/include/gsmd/usock.h
+++ b/include/gsmd/usock.h
@@ -162,6 +162,7 @@ enum gsmd_msg_network {
GSMD_NETWORK_PREF_DEL = 12,
GSMD_NETWORK_PREF_ADD = 13,
GSMD_NETWORK_PREF_SPACE = 14,
+ GSMD_NETWORK_QUERY_REG = 15,
};
enum gsmd_msg_sms {
diff --git a/src/gsmd/usock.c b/src/gsmd/usock.c
index 0164c1c..b6f42dd 100644
--- a/src/gsmd/usock.c
+++ b/src/gsmd/usock.c
@@ -664,6 +664,33 @@ static int usock_rcv_modem(struct gsmd_user *gu, struct gsmd_msg_hdr *gph,
return 0;
}
+static int network_query_reg_cb(struct gsmd_atcmd *cmd, void *ctx, char *resp)
+{
+ struct gsmd_user *gu = ctx;
+ struct gsm_extrsp *er;
+ enum gsmd_netreg_state state;
+
+ DEBUGP("cmd = '%s', resp: '%s'\n", cmd->buf, resp);
+
+ if (strncmp(resp, "+CREG: ", 7))
+ return -EINVAL;
+ resp += 7;
+ er = extrsp_parse(gsmd_tallocs, resp);
+ if(!er)
+ return -ENOMEM;
+ //extrsp_dump(er);
+ /* +CREG: <n>,<stat>[,<lac>,<ci>] */
+ if((er->num_tokens == 4 || er->num_tokens == 2 ) &&
+ er->tokens[0].type == GSMD_ECMD_RTT_NUMERIC &&
+ er->tokens[1].type == GSMD_ECMD_RTT_NUMERIC ) {
+ state = er->tokens[1].u.numeric;
+ }
+
+ talloc_free(er);
+ return gsmd_ucmd_submit(gu, GSMD_MSG_NETWORK, GSMD_NETWORK_QUERY_REG,
+ cmd->id, sizeof(state), &state);
+}
+
static int network_vmail_cb(struct gsmd_atcmd *cmd, void *ctx, char *resp)
{
struct gsmd_user *gu = ctx;
@@ -735,6 +762,8 @@ static int network_sigq_cb(struct gsmd_atcmd *cmd, void *ctx, char *resp)
cmd->id, sizeof(gsq), &gsq);
}
+
+
static int network_oper_cb(struct gsmd_atcmd *cmd, void *ctx, char *resp)
{
struct gsmd_user *gu = ctx;
@@ -1004,6 +1033,9 @@ static int usock_rcv_network(struct gsmd_user *gu, struct gsmd_msg_hdr *gph,
case GSMD_NETWORK_DEREGISTER:
cmd = atcmd_fill("AT+COPS=2", 9+1, &null_cmd_cb, gu, 0, NULL);
break;
+ case GSMD_NETWORK_QUERY_REG:
+ cmd = atcmd_fill("AT+CREG?", 8+1, &network_query_reg_cb, gu, 0, NULL);
+ break;
case GSMD_NETWORK_VMAIL_GET:
cmd = atcmd_fill("AT+CSVM?", 8+1, &network_vmail_cb, gu, 0, NULL);
break;
diff --git a/src/libgsmd/libgsmd_network.c b/src/libgsmd/libgsmd_network.c
index 7f459c5..1c3c39c 100644
--- a/src/libgsmd/libgsmd_network.c
+++ b/src/libgsmd/libgsmd_network.c
@@ -81,6 +81,11 @@ int lgsm_netreg_deregister(struct lgsm_handle *lh)
return lgsm_send_simple(lh, GSMD_MSG_NETWORK, GSMD_NETWORK_DEREGISTER);
}
+int lgsm_netreg_query(struct lgsm_handle *lh)
+{
+ return lgsm_send_simple(lh, GSMD_MSG_NETWORK, GSMD_NETWORK_QUERY_REG);
+}
+
int lgsm_signal_quality(struct lgsm_handle *lh)
{
return lgsm_send_simple(lh, GSMD_MSG_NETWORK, GSMD_NETWORK_SIGQ_GET);
diff --git a/src/util/shell.c b/src/util/shell.c
index e9aae1c..0507be5 100644
--- a/src/util/shell.c
+++ b/src/util/shell.c
@@ -291,6 +291,7 @@ static int net_msghandler(struct lgsm_handle *lh, struct gsmd_msg_hdr *gmh)
((void *) gmh + sizeof(*gmh));
const struct gsmd_voicemail *vmail = (struct gsmd_voicemail *)
((void *) gmh + sizeof(*gmh));
+ enum gsmd_netreg_state state = *(enum gsmd_netreg_state *) gmh->data;
int result = *(int *) gmh->data;
static const char *oper_stat[] = {
[GSMD_OPER_UNKNOWN] = "of unknown status",
@@ -361,6 +362,28 @@ static int net_msghandler(struct lgsm_handle *lh, struct gsmd_msg_hdr *gmh)
printf ("voicemail number is %s \n",vmail->addr.number);
pending_responses --;
break;
+ case GSMD_NETWORK_QUERY_REG:
+ switch (state) {
+ case GSMD_NETREG_UNREG:
+ printf("not searching for network \n");
+ break;
+ case GSMD_NETREG_REG_HOME:
+ printf("registered (home network) \n");
+ break;
+ case GSMD_NETREG_UNREG_BUSY:
+ printf("searching for network \n");
+ break;
+ case GSMD_NETREG_DENIED:
+ printf("registration denied \n");
+ break;
+ case GSMD_NETREG_REG_ROAMING:
+ printf("registered (roaming) \n");
+ break;
+ default:
+ break;
+ }
+ pending_responses --;
+ break;
default:
return -EINVAL;
}
@@ -648,6 +671,10 @@ int shell_main(struct lgsm_handle *lgsmh, int sync)
printf("Signal strength\n");
lgsm_signal_quality(lgsmh);
pending_responses ++;
+ } else if (!strcmp(buf, "nr")) {
+ printf("Query network registration\n");
+ lgsm_netreg_query(lgsmh);
+ pending_responses ++;
} else if (!strcmp(buf, "q")) {
exit(0);
} else if (buf[0] == 'S' ) {
personal git repositories of Harald Welte. Your mileage may vary