summaryrefslogtreecommitdiff
path: root/src/gsmd
diff options
context:
space:
mode:
Diffstat (limited to 'src/gsmd')
-rw-r--r--src/gsmd/atcmd.c11
-rw-r--r--src/gsmd/gsmd.c30
-rw-r--r--src/gsmd/usock.c48
3 files changed, 67 insertions, 22 deletions
diff --git a/src/gsmd/atcmd.c b/src/gsmd/atcmd.c
index 2647192..53120f4 100644
--- a/src/gsmd/atcmd.c
+++ b/src/gsmd/atcmd.c
@@ -156,6 +156,11 @@ static int ml_parse(const char *buf, int len, void *ctx)
DEBUGP("buf=`%s'(%d)\n", buf, len);
+ if (!strcmp(buf, "AT-Command Interpreter ready")) {
+ gsmd_initsettings(g);
+ return 0;
+ }
+
/* responses come in order, so first response has to be for first
* command we sent, i.e. first entry in list */
cmd = llist_entry(g->busy_atcmds.next, struct gsmd_atcmd, list);
@@ -248,13 +253,15 @@ static int ml_parse(const char *buf, int len, void *ctx)
/* FIXME: handling of those special commands in response to
* ATD / ATA */
- if (!strncmp(buf, "NO CARRIER", 10)) {
+ if (!strncmp(buf, "NO CARRIER", 11)) {
/* Part of Case 'D' */
+ final = 1;
goto final_cb;
}
if (!strncmp(buf, "BUSY", 4)) {
/* Part of Case 'D' */
+ final = 1;
goto final_cb;
}
}
@@ -388,6 +395,8 @@ struct gsmd_atcmd *atcmd_fill(const char *cmd, int rlen,
/* submit an atcmd in the global queue of pending atcmds */
int atcmd_submit(struct gsmd *g, struct gsmd_atcmd *cmd)
{
+ DEBUGP("submitting command `%s'\n", cmd->buf);
+
llist_add_tail(&cmd->list, &g->pending_atcmds);
g->gfd_uart.when |= GSMD_FD_WRITE;
diff --git a/src/gsmd/gsmd.c b/src/gsmd/gsmd.c
index c8a3b3f..9595d4b 100644
--- a/src/gsmd/gsmd.c
+++ b/src/gsmd/gsmd.c
@@ -26,32 +26,24 @@ static int gsmd_test_atcb(struct gsmd_atcmd *cmd, void *ctx, char *resp)
return 0;
}
-static int gsmd_test(struct gsmd *gsmd)
+static int gsmd_simplecmd(struct gsmd *gsmd, char *cmdtxt)
{
struct gsmd_atcmd *cmd;
- cmd = atcmd_fill("AT+CRC?", 255, &gsmd_test_atcb, NULL, 0);
- return atcmd_submit(gsmd, cmd);
-}
-
-static int atcmd_test(struct gsmd *gsmd)
-{
- struct gsmd_atcmd *cmd;
- cmd = atcmd_fill("ATE0", 255, &gsmd_test_atcb, NULL, 0);
+ cmd = atcmd_fill(cmdtxt, strlen(cmdtxt)+1, &gsmd_test_atcb, NULL, 0);
+ if (!cmd)
+ return -ENOMEM;
+
return atcmd_submit(gsmd, cmd);
}
-static int gsmd_initsettings(struct gsmd *gsmd)
+int gsmd_initsettings(struct gsmd *gsmd)
{
int rc;
- struct gsmd_atcmd *cmd;
-
- cmd = atcmd_fill("ATV1", 255, &gsmd_test_atcb, NULL, 0);
- rc = atcmd_submit(gsmd, cmd);
- if (rc < 0)
- return rc;
+
+ rc |= gsmd_simplecmd(gsmd, "ATE0V1");
+ rc |= gsmd_simplecmd(gsmd, "AT+CRC=1;+CREG=2;+CMEE=1;+CLIP=1;+COLP=1;+CTZR=1;+CFUN=1");
- cmd = atcmd_fill("+CRC=1;+CREG=2;+CMEE=2;+CLIP=1;+COLP=1;+CTZR=1", 255, &gsmd_test_atcb, NULL, 0);
- return atcmd_submit(gsmd, cmd);
+ return rc;
}
struct bdrt {
@@ -207,8 +199,6 @@ int main(int argc, char **argv)
setsid();
}
- atcmd_test(&g);
- gsmd_test(&g);
gsmd_initsettings(&g);
while (1) {
diff --git a/src/gsmd/usock.c b/src/gsmd/usock.c
index 93e9751..76be1aa 100644
--- a/src/gsmd/usock.c
+++ b/src/gsmd/usock.c
@@ -88,7 +88,7 @@ static int usock_rcv_voicecall(struct gsmd_user *gu, struct gsmd_msg_hdr *gph,
case GSMD_VOICECALL_DIAL:
if (len < sizeof(*gph) + sizeof(*ga))
return -EINVAL;
- ga = (struct gsmd_addr *) (void *)gph + sizeof(*gph);
+ ga = (struct gsmd_addr *) ((void *)gph + sizeof(*gph));
ga->number[GSMD_ADDR_MAXLEN] = '\0';
cmd = atcmd_fill("ATD", 5 + strlen(ga->number),
&usock_cmd_cb, gu, gph->id);
@@ -145,11 +145,57 @@ static int usock_rcv_pin(struct gsmd_user *gu, struct gsmd_msg_hdr *gph,
return atcmd_submit(gu->gsmd, cmd);
}
+static int usock_rcv_phone(struct gsmd_user *gu, struct gsmd_msg_hdr *gph,
+ int len)
+{
+ struct gsmd_atcmd *cmd;
+
+ switch (gph->msg_subtype) {
+ case GSMD_PHONE_POWERUP:
+ cmd = atcmd_fill("AT+CFUN=1", 9+1,
+ &null_cmd_cb, gu, 0);
+ break;
+
+ case GSMD_PHONE_POWERDOWN:
+ cmd = atcmd_fill("AT+CFUN=0", 9+1,
+ &null_cmd_cb, gu, 0);
+ break;
+ default:
+ return -EINVAL;
+ }
+ if (!cmd)
+ return -ENOMEM;
+
+ return atcmd_submit(gu->gsmd, cmd);
+}
+
+static int usock_rcv_network(struct gsmd_user *gu, struct gsmd_msg_hdr *gph,
+ int len)
+{
+ struct gsmd_atcmd *cmd;
+
+ switch (gph->msg_subtype) {
+ case GSMD_NETWORK_REGISTER:
+ cmd = atcmd_fill("AT+COPS", 9+1,
+ &null_cmd_cb, gu, 0);
+ break;
+ default:
+ return -EINVAL;
+ }
+ if (!cmd)
+ return -ENOMEM;
+
+ return atcmd_submit(gu->gsmd, cmd);
+}
+
+
static usock_msg_handler *pcmd_type_handlers[__NUM_GSMD_MSGS] = {
[GSMD_MSG_PASSTHROUGH] = &usock_rcv_passthrough,
[GSMD_MSG_EVENT] = &usock_rcv_event,
[GSMD_MSG_VOICECALL] = &usock_rcv_voicecall,
[GSMD_MSG_PIN] = &usock_rcv_pin,
+ [GSMD_MSG_PHONE] = &usock_rcv_phone,
+ [GSMD_MSG_NETWORK] = &usock_rcv_network,
};
static int usock_rcv_pcmd(struct gsmd_user *gu, char *buf, int len)
personal git repositories of Harald Welte. Your mileage may vary