From f243da86ed3c515740870ce0a817f2e768b420fe Mon Sep 17 00:00:00 2001 From: laforge Date: Sun, 15 Apr 2007 09:47:23 +0000 Subject: * add (still incomplete) SMS and phonebook support from Sean Chiang git-svn-id: http://svn.openmoko.org/trunk/src/target/gsm@1765 99fdad57-331a-0410-800a-d7fa5415bdb3 --- src/gsmd/gsmd.c | 7 + src/gsmd/usock.c | 429 ++++++++++++++++++++++++++++++++++++++++ src/libgsmd/Makefile.am | 2 +- src/libgsmd/libgsmd_phonebook.c | 146 ++++++++++++++ src/libgsmd/libgsmd_sms.c | 231 ++++++++++++++++++++++ src/util/shell.c | 164 +++++++++++++++ 6 files changed, 978 insertions(+), 1 deletion(-) create mode 100644 src/libgsmd/libgsmd_phonebook.c create mode 100644 src/libgsmd/libgsmd_sms.c (limited to 'src') diff --git a/src/gsmd/gsmd.c b/src/gsmd/gsmd.c index 8254ae0..e2ecaa7 100644 --- a/src/gsmd/gsmd.c +++ b/src/gsmd/gsmd.c @@ -78,6 +78,13 @@ int gsmd_initsettings(struct gsmd *gsmd) rc |= gsmd_simplecmd(gsmd, "AT+COLP=1"); /* power on the phone */ rc |= gsmd_simplecmd(gsmd, "AT+CFUN=1"); + /* configure message format as PDU mode*/ + /* FIXME: TEXT mode support!! */ + rc |= gsmd_simplecmd(gsmd, "AT+CMGF=0"); +#if 0 + /* Select TE character set */ + rc |= gsmd_simplecmd(gsmd, "AT+CSCS=\"UCS2\""); +#endif if (gsmd->vendorpl && gsmd->vendorpl->initsettings) return gsmd->vendorpl->initsettings(gsmd); diff --git a/src/gsmd/usock.c b/src/gsmd/usock.c index 31292e8..2f678dd 100644 --- a/src/gsmd/usock.c +++ b/src/gsmd/usock.c @@ -412,6 +412,433 @@ static int usock_rcv_network(struct gsmd_user *gu, struct gsmd_msg_hdr *gph, return atcmd_submit(gu->gsmd, cmd); } +static int sms_list_cb(struct gsmd_atcmd *cmd, void *ctx, char *resp) +{ + struct gsmd_user *gu = ctx; + struct gsmd_ucmd *ucmd; + + ucmd = gsmd_ucmd_fill(strlen(resp)+1, GSMD_MSG_SMS, + GSMD_SMS_LIST, 0); + if (!ucmd) + return -ENOMEM; + + /* FIXME: implementation */ + strcpy(ucmd->buf, resp); + + usock_cmd_enqueue(ucmd, gu); + + return 0; +} + +static int sms_read_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_SMS, + GSMD_SMS_READ, 0); + if (!ucmd) + return -ENOMEM; + + strcpy(ucmd->buf, resp); + + usock_cmd_enqueue(ucmd, gu); + + return 0; +} + +static int sms_send_cb(struct gsmd_atcmd *cmd, void *ctx, char *resp) +{ + struct gsmd_user *gu = ctx; + struct gsmd_ucmd *ucmd; + + ucmd = gsmd_ucmd_fill(strlen(resp)+1, GSMD_MSG_SMS, + GSMD_SMS_SEND, 0); + if (!ucmd) + return -ENOMEM; + + strcpy(ucmd->buf, resp); + + usock_cmd_enqueue(ucmd, gu); + + return 0; +} + +static int sms_write_cb(struct gsmd_atcmd *cmd, void *ctx, char *resp) +{ + struct gsmd_user *gu = ctx; + struct gsmd_ucmd *ucmd; + + ucmd = gsmd_ucmd_fill(strlen(resp)+1, GSMD_MSG_SMS, + GSMD_SMS_WRITE, 0); + if (!ucmd) + return -ENOMEM; + + strcpy(ucmd->buf, resp); + + usock_cmd_enqueue(ucmd, gu); + + return 0; +} + +static int sms_delete_cb(struct gsmd_atcmd *cmd, void *ctx, char *resp) +{ + struct gsmd_user *gu = ctx; + struct gsmd_ucmd *ucmd; + + ucmd = gsmd_ucmd_fill(strlen(resp)+1, GSMD_MSG_SMS, + GSMD_SMS_DELETE, 0); + if (!ucmd) + return -ENOMEM; + + strcpy(ucmd->buf, resp); + + usock_cmd_enqueue(ucmd, gu); + + return 0; +} + +static int usock_rcv_sms(struct gsmd_user *gu, struct gsmd_msg_hdr *gph, + int len) +{ + /* FIXME: TEXT mode support!! */ + struct gsmd_atcmd *cmd = NULL; + struct gsmd_sms_delete *gsd; + struct gsmd_sms *gs; + struct gsmd_sms_write *gsw; + int *stat, *index; + int atcmd_len; + char buf[1024]; + + switch (gph->msg_subtype) { + case GSMD_SMS_LIST: + /* FIXME: only support PDU mode!! */ + if(len < sizeof(*gph) + sizeof(int)) + return -EINVAL; + stat = (int *) ((void *)gph + sizeof(*gph)); + + sprintf(buf, "%d", *stat); + + atcmd_len = 1 + strlen("AT+CMGL=") + strlen(buf); + cmd = atcmd_fill("AT+CMGL=", atcmd_len, + &sms_list_cb, gu, gph->id); + if (!cmd) + return -ENOMEM; + sprintf(cmd->buf, "AT+CMGL=%s", buf); + break; + case GSMD_SMS_READ: + /* FIXME: only support PDU mode!! */ + if(len < sizeof(*gph) + sizeof(int)) + return -EINVAL; + index = (int *) ((void *)gph + sizeof(*gph)); + + sprintf(buf, "%d", *index); + + atcmd_len = 1 + strlen("AT+CMGR=") + strlen(buf); + cmd = atcmd_fill("AT+CMGR=", atcmd_len, + &sms_read_cb, gu, gph->id); + if (!cmd) + return -ENOMEM; + sprintf(cmd->buf, "AT+CMGR=%s", buf); + break; +#if 0 + case GSMD_SMS_SEND: + /* FIXME: only support PDU mode!! */ + if(len < sizeof(*gph) + sizeof(*gs)) + return -EINVAL; + gs = (struct gsmd_sms *) ((void *)gph + sizeof(*gph)); + + sprintf(buf, "%d", *index); + + atcmd_len = 1 + strlen("AT+CMGR=") + 1; + cmd = atcmd_fill("AT+CMGR=", atcmd_len, + &sms_send_cb, gu, gph->id); + if (!cmd)GSMD_SMS_WRITE + return -ENOMEM; + sprintf(cmd->buf, "AT+CMGR=%d", index); + break; + case GSMD_SMS_WRITE: + /* FIXME: only support PDU mode!! */ + if(len < sizeof(*gph) + sizeof(*gsw)) + return -EINVAL; + &index = (int *) ((void *)gph + sizeof(*gph)); + + atcmd_len = 1 + strlen("AT+CMGR=") + 1; + cmd = atcmd_fill("AT+CMGR=", atcmd_len, + &sms_write_cb, gu, gph->id); + if (!cmd) + return -ENOMEM; + sprintf(cmd->buf, "AT+CMGR=%d", index); + break; +#endif + case GSMD_SMS_DELETE: + if(len < sizeof(*gph) + sizeof(*gsd)) + return -EINVAL; + gsd = (struct gsmd_sms_delete *) ((void *)gph + sizeof(*gph)); + + sprintf(buf, "%d,%d", gsd->index, gsd->delflg); + + atcmd_len = 1 + strlen("AT+CMGR=") + strlen(buf); + cmd = atcmd_fill("AT+CMGD=", atcmd_len, + &sms_delete_cb, gu, gph->id); + if (!cmd) + return -ENOMEM; + sprintf(cmd->buf, "AT+CMGD=%s", buf); + break; + default: + return -EINVAL; + } + + gsmd_log(GSMD_DEBUG, "%s\n", cmd->buf); + if (cmd) + return atcmd_submit(gu->gsmd, cmd); + else + return 0; +} + +#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, + GSMD_PHONEBOOK_FIND, 0); + if (!ucmd) + return -ENOMEM; + + strcpy(ucmd->buf, resp); + + usock_cmd_enqueue(ucmd, gu); + return 0; +} + +static int phonebook_read_cb(struct gsmd_atcmd *cmd, void *ctx, char *resp) +{ + struct gsmd_user *gu = ctx; + struct gsmd_phonebook *gp; + struct gsmd_ucmd *ucmd; + char *fcomma, *lcomma; + char *ptr; + /* FIXME: We should check this case "When the entry is empty" */ + ucmd = gsmd_ucmd_fill(sizeof(*gp), GSMD_MSG_PHONEBOOK, + GSMD_PHONEBOOK_READ, 0); + + if (!ucmd) + 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'; + + 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'; + + 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 */ + + ucmd = gsmd_ucmd_fill(strlen(resp)+1, GSMD_MSG_PHONEBOOK, + GSMD_PHONEBOOK_READRG, 0); + if (!ucmd) + return -ENOMEM; + + strcpy(ucmd->buf, resp); + + usock_cmd_enqueue(ucmd, gu); + + return 0; +} + +static int phonebook_write_cb(struct gsmd_atcmd *cmd, void *ctx, char *resp) +{ + struct gsmd_user *gu = ctx; + struct gsmd_ucmd *ucmd; + + ucmd = gsmd_ucmd_fill(strlen(resp)+1, GSMD_MSG_PHONEBOOK, + GSMD_PHONEBOOK_WRITE, 0); + if (!ucmd) + return -ENOMEM; + + strcpy(ucmd->buf, resp); + + usock_cmd_enqueue(ucmd, gu); + + return 0; +} + +static int phonebook_delete_cb(struct gsmd_atcmd *cmd, void *ctx, char *resp) +{ + struct gsmd_user *gu = ctx; + struct gsmd_ucmd *ucmd; + + ucmd = gsmd_ucmd_fill(strlen(resp)+1, GSMD_MSG_PHONEBOOK, + GSMD_PHONEBOOK_DELETE, 0); + if (!ucmd) + return -ENOMEM; + + strcpy(ucmd->buf, resp); + + usock_cmd_enqueue(ucmd, gu); + + return 0; +} + +static int phonebook_support_cb(struct gsmd_atcmd *cmd, void *ctx, char *resp) +{ + struct gsmd_user *gu = ctx; + struct gsmd_phonebook_support *gps; + struct gsmd_ucmd *ucmd; + char *fcomma, *lcomma; + char *dash; + + 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, '-'); + if (!dash) { + talloc_free(ucmd); + return -EIO; + } + gps->index = atoi(dash+1); + + fcomma = strchr(resp, ','); + if (!fcomma) { + talloc_free(ucmd); + return -EIO; + } + gps->nlength = atoi(fcomma+1); + + lcomma = strrchr(resp, ','); + if (!lcomma) { + talloc_free(ucmd); + return -EIO; + } + gps->tlength = atoi(lcomma+1); + + 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; + struct gsmd_phonebook *gp; + struct gsmd_phonebook_find *gpf; + int *index; + int atcmd_len; + char buf[1024]; + + switch (gph->msg_subtype) { + 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("\""); + cmd = atcmd_fill("AT+CPBF=\"", atcmd_len, + &phonebook_find_cb, gu, gph->id); + if (!cmd) + return -ENOMEM; + sprintf(cmd->buf, "AT+CPBF=\"%s\"", gpf->findtext); + break; + case GSMD_PHONEBOOK_READ: + if(len < sizeof(*gph) + sizeof(int)) + return -EINVAL; + index = (int *) ((void *)gph + sizeof(*gph)); + + sprintf(buf, "%d", *index); + + atcmd_len = 1 + strlen("AT+CPBR=") + strlen(buf); + cmd = atcmd_fill("AT+CPBR=", atcmd_len, + &phonebook_read_cb, gu, gph->id); + if (!cmd) + return -ENOMEM; + sprintf(cmd->buf, "AT+CPBR=%d", *index); + break; + case GSMD_PHONEBOOK_READRG: + if(len < sizeof(*gph) + sizeof(*gpr)) + return -EINVAL; + gpr = (struct gsmd_phonebook_readrg *) ((void *)gph + sizeof(*gph)); + + sprintf(buf, "%d,%d", gpr->index1, gpr->index2); + + atcmd_len = 1 + strlen("AT+CPBR=") + strlen(buf); + cmd = atcmd_fill("AT+CPBR=", atcmd_len, + &phonebook_readrg_cb, gu, gph->id); + if (!cmd) + return -ENOMEM; + sprintf(cmd->buf, "AT+CPBR=%s", buf); + break; + case GSMD_PHONEBOOK_WRITE: + if(len < sizeof(*gph) + sizeof(*gp)) + return -EINVAL; + gp = (struct gsmd_phonebook *) ((void *)gph + sizeof(*gph)); + + 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); + if (!cmd) + return -ENOMEM; + sprintf(cmd->buf, "AT+CPBW=%s", buf); + break; + case GSMD_PHONEBOOK_DELETE: + if(len < sizeof(*gph) + sizeof(int)) + return -EINVAL; + index = (int *) ((void *)gph + sizeof(*gph)); + + sprintf(buf, "%d", *index); + + atcmd_len = 1 + strlen("AT+CPBW=") + strlen(buf); + cmd = atcmd_fill("AT+CPBW=", atcmd_len, + &phonebook_delete_cb, gu, gph->id); + if (!cmd) + return -ENOMEM; + sprintf(cmd->buf, "AT+CPBW=%s", buf); + break; + case GSMD_PHONEBOOK_GET_SUPPORT: + cmd = atcmd_fill("AT+CPBR=?", 9+1, + &phonebook_support_cb, gu, gph->id); + break; + default: + return -EINVAL; + } + + if (cmd) + return atcmd_submit(gu->gsmd, cmd); + else + return 0; +} +#endif static usock_msg_handler *pcmd_type_handlers[__NUM_GSMD_MSGS] = { [GSMD_MSG_PASSTHROUGH] = &usock_rcv_passthrough, @@ -420,6 +847,8 @@ static usock_msg_handler *pcmd_type_handlers[__NUM_GSMD_MSGS] = { [GSMD_MSG_PIN] = &usock_rcv_pin, [GSMD_MSG_PHONE] = &usock_rcv_phone, [GSMD_MSG_NETWORK] = &usock_rcv_network, + [GSMD_MSG_SMS] = &usock_rcv_sms, + //[GSMD_MSG_PHONEBOOK] = &usock_rcv_phonebook, }; static int usock_rcv_pcmd(struct gsmd_user *gu, char *buf, int len) diff --git a/src/libgsmd/Makefile.am b/src/libgsmd/Makefile.am index 5ea36f1..20a6725 100644 --- a/src/libgsmd/Makefile.am +++ b/src/libgsmd/Makefile.am @@ -5,6 +5,6 @@ AM_CFLAGS = -std=gnu99 lib_LTLIBRARIES = libgsmd.la libgsmd_la_LDFLAGS = -Wc,-nostartfiles -version-info $(LIBVERSION) -libgsmd_la_SOURCES = libgsmd.c libgsmd_input.c libgsmd_voicecall.c libgsmd_passthrough.c libgsmd_event.c libgsmd_phone.c libgsmd_network.c libgsmd_pin.c +libgsmd_la_SOURCES = libgsmd.c libgsmd_input.c libgsmd_voicecall.c libgsmd_passthrough.c libgsmd_event.c libgsmd_phone.c libgsmd_network.c libgsmd_pin.c libgsmd_sms.c libgsmd_phonebook.c noinst_HEADERS = lgsm_internals.h diff --git a/src/libgsmd/libgsmd_phonebook.c b/src/libgsmd/libgsmd_phonebook.c new file mode 100644 index 0000000..c569e02 --- /dev/null +++ b/src/libgsmd/libgsmd_phonebook.c @@ -0,0 +1,146 @@ +#include +#include +#include + +#include +#include +#include + +#include +#include + +#include "lgsm_internals.h" + +int lgsm_pb_find_entry(struct lgsm_handle *lh, + const struct lgsm_phonebook_find *pb_find) +{ + struct gsmd_msg_hdr *gmh; + struct gsmd_phonebook_find *gpf; + int rc; + + gmh = lgsm_gmh_fill(GSMD_MSG_PHONEBOOK, + GSMD_PHONEBOOK_FIND, sizeof(*gpf)); + if (!gmh) + return -ENOMEM; + gpf = (struct gsmd_phonebook_find *)gmh->data; + memcpy(gpf->findtext, pb_find->findtext, sizeof(gpf->findtext)); + gpf->findtext[sizeof(gpf->findtext)-1] = '\0'; + + rc = lgsm_send(lh, gmh); + if (rc < gmh->len + sizeof(*gmh)) { + lgsm_gmh_free(gmh);; + return -EIO; + } + + lgsm_gmh_free(gmh); + + return 0; +} + +int lgsm_pb_read_entry(struct lgsm_handle *lh, int index) +{ + struct gsmd_msg_hdr *gmh; + int rc; + + gmh = lgsm_gmh_fill(GSMD_MSG_PHONEBOOK, + GSMD_PHONEBOOK_READ, sizeof(int)); + if (!gmh) + return -ENOMEM; + *(int *) gmh->data = index; + + rc = lgsm_send(lh, gmh); + if (rc < gmh->len + sizeof(*gmh)) { + lgsm_gmh_free(gmh);; + return -EIO; + } + + lgsm_gmh_free(gmh); + + return 0; +} + +int lgsm_pb_read_entryies(struct lgsm_handle *lh, + const struct lgsm_phonebook_readrg *pb_readrg) +{ + struct gsmd_msg_hdr *gmh; + struct gsmd_phonebook_readrg *gpr; + int rc; + + gmh = lgsm_gmh_fill(GSMD_MSG_PHONEBOOK, + GSMD_PHONEBOOK_READRG, sizeof(*gpr)); + if (!gmh) + return -ENOMEM; + gpr = (struct gsmd_phonebook_readrg *) gmh->data; + gpr->index1 = pb_readrg->index1; + gpr->index2 = pb_readrg->index2; + + rc = lgsm_send(lh, gmh); + if (rc < gmh->len + sizeof(*gmh)) { + lgsm_gmh_free(gmh);; + return -EIO; + } + + lgsm_gmh_free(gmh); + + return 0; +} + +int lgsmd_pb_del_entry(struct lgsm_handle *lh, int index) +{ + struct gsmd_msg_hdr *gmh; + int rc; + + gmh = lgsm_gmh_fill(GSMD_MSG_PHONEBOOK, + GSMD_PHONEBOOK_DELETE, sizeof(int)); + if (!gmh) + return -ENOMEM; + + *(int *)(gmh->data) = index; + + rc = lgsm_send(lh, gmh); + if (rc < gmh->len + sizeof(*gmh)) { + lgsm_gmh_free(gmh); + return -EIO; + } + + lgsm_gmh_free(gmh); + + return 0; +} + +int lgsmd_pb_write_entry(struct lgsm_handle *lh, + const struct lgsm_phonebook *pb) +{ + /* FIXME: only support alphabet now */ + struct gsmd_msg_hdr *gmh; + struct gsmd_phonebook *gp; + int rc; + + gmh = lgsm_gmh_fill(GSMD_MSG_PHONEBOOK, + GSMD_PHONEBOOK_WRITE, sizeof(*gp)); + if (!gmh) + return -ENOMEM; + gp = (struct gsmd_phonebook *) gmh->data; + gp->index = pb->index; + memcpy(gp->numb, pb->numb, sizeof(gp->numb)); + gp->numb[sizeof(gp->numb)-1] = '\0'; + gp->type = pb->type; + memcpy(gp->text, pb->text, sizeof(gp->text)); + gp->text[sizeof(gp->text)-1] = '\0'; + + rc = lgsm_send(lh, gmh); + if (rc < gmh->len + sizeof(*gmh)) { + lgsm_gmh_free(gmh);; + return -EIO; + } + + lgsm_gmh_free(gmh); + + return 0; +} + + +int lgsm_pb_get_support(struct lgsm_handle *lh) +{ + return lgsm_send_simple(lh, GSMD_MSG_PHONEBOOK, GSMD_PHONEBOOK_GET_SUPPORT); +} diff --git a/src/libgsmd/libgsmd_sms.c b/src/libgsmd/libgsmd_sms.c new file mode 100644 index 0000000..261dca3 --- /dev/null +++ b/src/libgsmd/libgsmd_sms.c @@ -0,0 +1,231 @@ +#include +#include +#include +#include + +#include +#include +#include + +#include +#include + +#include "lgsm_internals.h" + +int lgsm_sms_list(struct lgsm_handle *lh, enum gsmd_msg_sms_type stat) +{ + /* FIXME: only support PDU mode now */ + struct gsmd_msg_hdr *gmh; + int rc; + + gmh = lgsm_gmh_fill(GSMD_MSG_SMS, + GSMD_SMS_LIST, sizeof(int)); + if (!gmh) + return -ENOMEM; + *(int *) gmh->data = stat; + + rc = lgsm_send(lh, gmh); + if (rc < gmh->len + sizeof(*gmh)) { + lgsm_gmh_free(gmh);; + return -EIO; + } + + lgsm_gmh_free(gmh); + + return 0; +} + +int lgsm_sms_read(struct lgsm_handle *lh, int index) +{ + struct gsmd_msg_hdr *gmh; + int rc; + + gmh = lgsm_gmh_fill(GSMD_MSG_SMS, + GSMD_SMS_READ, sizeof(int)); + if (!gmh) + return -ENOMEM; + *(int *) gmh->data = index; + + rc = lgsm_send(lh, gmh); + if (rc < gmh->len + sizeof(*gmh)) { + lgsm_gmh_free(gmh);; + return -EIO; + } + + lgsm_gmh_free(gmh); + + return 0; +} + +int lgsmd_sms_delete(struct lgsm_handle *lh, + const struct lgsm_sms_delete *sms_del) +{ + struct gsmd_msg_hdr *gmh; + struct gsmd_sms_delete *gsd; + int rc; + + gmh = lgsm_gmh_fill(GSMD_MSG_SMS, + GSMD_SMS_DELETE, sizeof(*gsd)); + if (!gmh) + return -ENOMEM; + gsd = (struct gsmd_sms_delete *) gmh->data; + gsd->index = sms_del->index; + gsd->delflg = sms_del->delflg; + + rc = lgsm_send(lh, gmh); + if (rc < gmh->len + sizeof(*gmh)) { + lgsm_gmh_free(gmh); + return -EIO; + } + + lgsm_gmh_free(gmh); + + return 0; +} + +int lgsmd_sms_send(struct lgsm_handle *lh, + const struct lgsm_sms *sms) +{ + /* FIXME: only support PDU mode */ + struct gsmd_msg_hdr *gmh; + struct gsmd_sms *gs; + int rc; + + gmh = lgsm_gmh_fill(GSMD_MSG_SMS, + GSMD_SMS_SEND, sizeof(*gs)); + if (!gmh) + return -ENOMEM; + gs = (struct gsmd_sms *) gmh->data; + + rc = lgsm_send(lh, gmh); + if (rc < gmh->len + sizeof(*gmh)) { + lgsm_gmh_free(gmh); + return -EIO; + } + + lgsm_gmh_free(gmh); + + return 0; +} + +int lgsmd_sms_write(struct lgsm_handle *lh, + const struct lgsm_sms_write *sms_write) +{ + /* FIXME: only support PDU mode */ + struct gsmd_msg_hdr *gmh; + struct gsmd_sms_write *gsw; + int rc; + + gmh = lgsm_gmh_fill(GSMD_MSG_SMS, + GSMD_SMS_WRITE, sizeof(*gsw)); + if (!gmh) + return -ENOMEM; + gsw = (struct gsmd_sms_write *) gmh->data; + + rc = lgsm_send(lh, gmh); + if (rc < gmh->len + sizeof(*gmh)) { + lgsm_gmh_free(gmh); + return -EIO; + } + + lgsm_gmh_free(gmh); + + return 0; +} + +int packing_7bit_character(char *src, char *dest) +{ + int i,j = 0; + unsigned char ch1, ch2; + char tmp[2]; + int shift = 0; + + *dest = '\0'; + + for ( i=0; i> shift; + ch2 = src[(i+1)] & 0x7F; + ch2 = ch2 << (7-shift); + + ch1 = ch1 | ch2; + + j = strlen(dest); + sprintf(tmp, "%x", (ch1 >> 4)); + dest[j++] = tmp[0]; + sprintf(tmp, "%x", (ch1 & 0x0F)); + dest[j++] = tmp[0]; + dest[j++] = '\0'; + + shift++; + + if ( 7 == shift ) { + shift = 0; + i++; + } + } + + return 0; +} + +int unpacking_7bit_character(char *src, char *dest) +{ + unsigned char ch1, ch2 = '\0'; + int i, j; + char buf[8]; + int shift = 0; + + *dest = '\0'; + + for ( i=0; i> shift)) << shift) | ch2; + dest[j++] = '\0'; + + ch2 = ch1 >> (7-shift); + + shift++; + } + + return 0; +} + +/* Refer to 3GPP TS 11.11 Annex B */ +int packing_UCS2_80(char *src, char *dest) +{ + return 0; +} + +/* Refer to 3GPP TS 11.11 Annex B */ +int unpacking_UCS2_80(char *src, char *dest) +{ + return 0; +} + +/* Refer to 3GPP TS 11.11 Annex B */ +int packing_UCS2_81(char *src, char *dest) +{ + return 0; +} + +/* Refer to 3GPP TS 11.11 Annex B */ +int unpacking_UCS2_81(char *src, char *dest) +{ + return 0; +} + +/* Refer to 3GPP TS 11.11 Annex B */ +int packing_UCS2_82(char *src, char *dest) +{ + return 0; +} + +/* Refer to 3GPP TS 11.11 Annex B */ +int unpacking_UCS2_82(char *src, char *dest) +{ + return 0; +} diff --git a/src/util/shell.c b/src/util/shell.c index 4fef8f9..dfd14cf 100644 --- a/src/util/shell.c +++ b/src/util/shell.c @@ -29,6 +29,9 @@ #include #include #include +#include +#include +#include #define STDIN_BUF_SIZE 1024 @@ -39,6 +42,58 @@ static int pt_msghandler(struct lgsm_handle *lh, struct gsmd_msg_hdr *gmh) printf("RSTR=`%s'\n", payload); } +/* this is the handler for receiving phonebook responses */ +static int pb_msghandler(struct lgsm_handle *lh, struct gsmd_msg_hdr *gmh) +{ + struct gsmd_phonebook *gp; + struct gsmd_phonebook_support *gps; + char *payload; + + switch (gmh->msg_subtype) { + case GSMD_PHONEBOOK_FIND: + break; + case GSMD_PHONEBOOK_READRG: + payload = (char *)gmh + sizeof(*gmh); + 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); + 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; + default: + return -EINVAL; + } +} + +/* this is the handler for receiving sms responses */ +static int sms_msghandler(struct lgsm_handle *lh, struct gsmd_msg_hdr *gmh) +{ + char *payload; + + switch (gmh->msg_subtype) { + case GSMD_SMS_LIST: + break; + case GSMD_SMS_READ: + case GSMD_SMS_SEND: + case GSMD_SMS_WRITE: + case GSMD_SMS_DELETE: + payload = (char *)gmh + sizeof(*gmh); + printf("%s\n", payload); + break; + default: + return -EINVAL; + } +} + static int shell_help(void) { printf( "\tA\tAnswer incoming call\n" @@ -48,6 +103,17 @@ static int shell_help(void) "\to\tPower Off\n" "\tR\tRegister Netowrk\n" "\tT\tSend DTMF Tone\n" + "\tpd\tPB Delete (pb=index)\n" + "\tpr\tPB Read (pr=index)\n" + "\tprr\tPB Read Range (prr=index1,index2)\n" + "\tpf\tPB Find (pff=indtext)\n" + "\tpw\tPB Write (pw=index,number,text)\n" + "\tps\tPB Support\n" + "\tsd\tSMS Delete (sd=index,delflg)\n" + "\tsl\tSMS List (sl=stat)\n" + "\tsr\tSMS Read (sr=index)\n" + "\tss\tSMS Send (ss=number,text)\n" + "\tsw\tSMS Write (sw=stat,number,text)\n" "\tq\tQuit\n" ); } @@ -59,8 +125,11 @@ int shell_main(struct lgsm_handle *lgsmh) char rbuf[STDIN_BUF_SIZE+1]; int rlen = sizeof(rbuf); fd_set readset; + char *ptr, *fcomma, *lcomma; lgsm_register_handler(lgsmh, GSMD_MSG_PASSTHROUGH, &pt_msghandler); + lgsm_register_handler(lgsmh, GSMD_MSG_PHONEBOOK, &pb_msghandler); + lgsm_register_handler(lgsmh, GSMD_MSG_SMS, &sms_msghandler); fcntl(0, F_SETFD, O_NONBLOCK); fcntl(lgsm_fd(lgsmh), F_SETFD, O_NONBLOCK); @@ -135,6 +204,101 @@ int shell_main(struct lgsm_handle *lgsmh) continue; printf("DTMF: %c\n", buf[1]); lgsm_voice_dtmf(lgsmh, buf[1]); + } else if ( !strncmp(buf, "pd", 2)) { + printf("Delete Phonebook Entry\n"); + ptr = strchr(buf, '='); + lgsmd_pb_del_entry(lgsmh, atoi(ptr+1)); + } else if ( !strncmp(buf, "prr", 3)) { + printf("Read Phonebook Entries\n"); + struct lgsm_phonebook_readrg pb_readrg; + + 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, '='); + 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; + + ptr = strchr(buf, '='); + 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); + } else if ( !strncmp(buf, "pw", 2)) { + printf("Write Phonebook Entry\n"); + struct lgsm_phonebook pb; + + ptr = strchr(buf, '='); + pb.index = atoi(ptr+1); + + fcomma = strchr(buf, ','); + lcomma = strrchr(buf, ','); + 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); + } else if ( !strncmp(buf, "ps", 2)) { + printf("Get Phonebook Support\n"); + lgsm_pb_get_support(lgsmh); + } else if ( !strncmp(buf, "sd", 2)) { + printf("Delete SMS\n"); + struct lgsm_sms_delete sms_del; + + ptr = strchr(buf, '='); + sms_del.index = atoi(ptr+1); + ptr = strchr(buf, ','); + sms_del.delflg = atoi(ptr+1); + + lgsmd_sms_delete(lgsmh, &sms_del); + } else if ( !strncmp(buf, "sl", 2)) { + printf("List SMS\n"); + ptr = strchr(buf, '='); + + lgsm_sms_list(lgsmh, atoi(ptr+1)); + } else if ( !strncmp(buf, "sr", 2)) { + printf("Read SMS\n"); + ptr = strchr(buf, '='); + + lgsm_sms_read(lgsmh, atoi(ptr+1)); + } else if ( !strncmp(buf, "ss", 2)) { + printf("Send SMS\n"); + struct lgsm_sms sms; + + ptr = strchr(buf, '='); + fcomma = strchr(buf, ','); + strncpy(sms.addr, ptr+1, (fcomma-ptr-1)); + sms.addr[fcomma-ptr-1] = '\0'; + strncpy(sms.data, fcomma+1, strlen(fcomma+1)); + sms.data[strlen(fcomma+1)] = '\0'; + + lgsmd_sms_send(lgsmh, &sms); + } else if ( !strncmp(buf, "sw", 2)) { + printf("Write SMS\n"); + struct lgsm_sms_write sms_write; + + ptr = strchr(buf, '='); + sms_write.stat = atoi(ptr+1); + fcomma = strchr(buf, ','); + lcomma = strrchr(buf, ','); + strncpy(sms_write.sms.addr, fcomma+1, (lcomma-fcomma-1)); + sms_write.sms.addr[lcomma-fcomma-1] = '\0'; + strncpy(sms_write.sms.data, lcomma+1, strlen(lcomma+1)); + sms_write.sms.data[strlen(lcomma+1)] = '\0'; + + lgsmd_sms_write(lgsmh, &sms_write); } else { printf("Unknown command `%s'\n", buf); } -- cgit v1.2.3