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 --- include/gsmd/usock.h | 164 ++++++++++++++- include/libgsmd/libgsmd.h | 1 + include/libgsmd/misc.h | 4 +- include/libgsmd/phonebook.h | 52 +++++ include/libgsmd/sms.h | 114 +++++++++++ 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 +++++++++++++++ 11 files changed, 1310 insertions(+), 4 deletions(-) create mode 100644 include/libgsmd/sms.h create mode 100644 src/libgsmd/libgsmd_phonebook.c create mode 100644 src/libgsmd/libgsmd_sms.c diff --git a/include/gsmd/usock.h b/include/gsmd/usock.h index cb5e0b9..2032230 100644 --- a/include/gsmd/usock.h +++ b/include/gsmd/usock.h @@ -21,6 +21,7 @@ enum gsmd_msg_type { GSMD_MSG_NETWORK = 6, GSMD_MSG_PHONE = 7, GSMD_MSG_PIN = 8, + GSMD_MSG_SMS = 9, __NUM_GSMD_MSGS }; @@ -63,6 +64,102 @@ enum gsmd_msg_network { GSMD_NETWORK_CIND_GET = 6, }; +enum gsmd_msg_sms { + GSMD_SMS_LIST = 1, + GSMD_SMS_READ = 2, + GSMD_SMS_SEND = 3, + GSMD_SMS_WRITE = 4, + GSMD_SMS_DELETE = 5, +}; + +/* SMS stat from 3GPP TS 07.05, Clause 3.1 */ +enum gsmd_msg_sms_type { + GSMD_SMS_REC_UNREAD = 0, + GSMD_SMS_REC_READ = 1, + GSMD_SMS_STO_UNSENT = 2, + GSMD_SMS_STO_SENT = 3, + GSMD_SMS_ALL = 4, +}; + +/* SMS format from 3GPP TS 07.05, Clause 3.2.3 */ +enum gsmd_msg_sms_fmt { + GSMD_SMS_FMT_PDU = 0, + GSMD_SMS_FMT_TEXT = 1, +}; + +/* Refer to GSM 03.40 subclause 9.2.3.1 */ +enum gsmd_sms_tp_mti { + GSMD_SMS_TP_MTI_DELIVER = 0, + GSMD_SMS_TP_MTI_DELIVER_REPORT = 0, + GSMD_SMS_TP_MTI_STATUS_REPORT = 2, + GSMD_SMS_TP_MTI_COMMAND = 2, + GSMD_SMS_TP_MTI_SUBMIT = 1, + GSMD_SMS_TP_MTI_SUBMIT_REPORT = 1, + GSMD_SMS_TP_MTI_RESERVED = 3, +}; + +/* Refer to GSM 03.40 subclause 9.2.3.2, */ +/* for SMS-DELIVER, SMS-STATUS-REPORT */ +enum gsmd_sms_tp_mms { + GSMD_SMS_TP_MMS_MORE = (0<<2), + GSMD_SMS_TP_MMS_NO_MORE = (1<<2), +}; + +/* Refer to GSM 03.40 subclause 9.2.3.3, */ +/* for SMS-SUBMIT */ +enum gsmd_sms_tp_vpf { + GSMD_SMS_TP_VPF_NOT_PRESENT = (0<<3), + GSMD_SMS_TP_VPF_RESERVED = (1<<3), + GSMD_SMS_TP_VPF_RELATIVE = (2<<3), + GSMD_SMS_TP_VPF_ABSOLUTE = (3<<3), +}; + +/* Refer to GSM 03.40 subclause 9.2.3.4, */ +/* for SMS-DELIVER */ +enum gsmd_sms_tp_sri { + GSMD_SMS_TP_SRI_NOT_RETURN = (0<<5), + GSMD_SMS_TP_SRI_STATUS_RETURN = (1<<5), +}; + +/* Refer to GSM 03.40 subclause 9.2.3.5, */ +/* for SMS-SUBMIT, SMS-COMMAND */ +enum gsmd_sms_tp_srr { + GSMD_SMS_TP_SRR_NOT_REQUEST = (0<<5), + GSMD_SMS_TP_SRR_STATUS_REQUEST = (1<<5), +}; + +/* Refer to GSM 03.40 subclause 9.2.3.17, */ +/* for SMS-SUBMIT, SMS-DELIVER */ +enum gsmd_sms_tp_rp { + GSMD_SMS_TP_RP_NOT_SET = (0<<7), + GSMD_SMS_TP_RP_SET = (1<<7), +}; + +/* Refer to GSM 03.40 subclause 9.2.3.23 */ +/* for SMS-SUBMIT, SMS-DELIVER */ +enum gsmd_sms_tp_udhi { + GSMD_SMS_TP_UDHI_NO_HEADER = (0<<6), + GSMD_SMS_TP_UDHI_WTIH_HEADER = (1<<6), +}; + +/* SMS delflg from 3GPP TS 07.05, Clause 3.5.4 */ +enum gsmd_msg_sms_delflg { + GSMD_SMS_DELFLG_INDEX = 0, + GSMD_SMS_DELFLG_READ = 1, + GSMD_SMS_DELFLG_READ_SENT = 2, + GSMD_SMS_DELFLG_LEAVING_UNREAD = 3, + GSMD_SMS_DELFLG_ALL = 4, +}; + +enum gsmd_msg_phonebook { + GSMD_PHONEBOOK_FIND = 1, + GSMD_PHONEBOOK_READ = 2, + GSMD_PHONEBOOK_READRG = 3, + GSMD_PHONEBOOK_WRITE = 4, + GSMD_PHONEBOOK_DELETE = 5, + GSMD_PHONEBOOK_GET_SUPPORT = 6, +}; + /* Length from 3GPP TS 04.08, Clause 10.5.4.7 */ #define GSMD_ADDR_MAXLEN 32 @@ -137,6 +234,72 @@ struct gsmd_evt_auxdata { } u; } __attribute__((packed)); +/* Refer to GSM 07.05 subclause 3.5.4 */ +struct gsmd_sms_delete { + u_int8_t index; + u_int8_t delflg; +} __attribute__ ((packed)); + +/* Refer to GSM 03.40 subclause 9.2.2.2 and GSM 07.05 subclause 4.3 */ +#define GSMD_SMS_DATA_MAXLEN 164 +struct gsmd_sms { + u_int8_t length; + char data[GSMD_SMS_DATA_MAXLEN+1]; +} __attribute__ ((packed)); + +/* Refer to GSM 07.05 subclause 4.4 */ +struct gsmd_sms_write { + u_int8_t stat; + struct gsmd_sms sms; +} __attribute__ ((packed)); + +/* Refer to GSM 03.40 subclause 9.2.2.2 */ +struct gsmd_sms_submit { + u_int8_t length; + char data[GSMD_SMS_DATA_MAXLEN+1]; +} __attribute__ ((packed)); + +/* Refer to GSM 03.40 subclause 9.2.2.1 */ +struct gsmd_sms_deliver { + u_int8_t length; + char origl_addr[12]; + u_int8_t proto_ident; + u_int8_t coding_scheme; + char time_stamp[7]; + char user_data[140]; +} __attribute__ ((packed)); + +/* Refer to GSM 07.07 subclause 8.12 */ +struct gsmd_phonebook_readrg { + u_int8_t index1; + u_int8_t index2; +} __attribute__ ((packed)); + +/* Refer to GSM 07.07 subclause 8.14 */ +/* FIXME: the nlength and tlength depend on SIM, use +CPBR=? to get */ +#define GSMD_PB_NUMB_MAXLEN 44 +#define GSMD_PB_TEXT_MAXLEN 14 +struct gsmd_phonebook { + u_int8_t index; + char numb[GSMD_PB_NUMB_MAXLEN+1]; + u_int8_t type; + char text[GSMD_PB_TEXT_MAXLEN+1]; +} __attribute__ ((packed)); + + +/* Refer to GSM 07.07 subclause 8.13 */ +/* FIXME: the tlength depends on SIM, use +CPBR=? to get */ +struct gsmd_phonebook_find { + char findtext[GSMD_PB_TEXT_MAXLEN+1]; +} __attribute__ ((packed)); + +/* Refer to GSM 07.07 subclause 8.12 */ +struct gsmd_phonebook_support { + u_int8_t index; + u_int8_t nlength; + u_int8_t tlength; +} __attribute__ ((packed)); + struct gsmd_msg_hdr { u_int8_t version; u_int8_t msg_type; @@ -147,7 +310,6 @@ struct gsmd_msg_hdr { u_int8_t data[]; } __attribute__((packed)); - #ifdef __GSMD__ #include diff --git a/include/libgsmd/libgsmd.h b/include/libgsmd/libgsmd.h index 8c34c6a..fc56890 100644 --- a/include/libgsmd/libgsmd.h +++ b/include/libgsmd/libgsmd.h @@ -65,5 +65,6 @@ extern int lgsm_subscriptions(struct lgsm_handle *lh, u_int32_t subscriptions); extern struct gsmd_msg_hdr *lgsm_gmh_fill(int type, int subtype, int payload_len); extern int lgsm_send(struct lgsm_handle *lh, struct gsmd_msg_hdr *gmh); +extern int lgsm_handle_packet(struct lgsm_handle *lh, char *buf, int len); #endif diff --git a/include/libgsmd/misc.h b/include/libgsmd/misc.h index 95e219d..cbc2df0 100644 --- a/include/libgsmd/misc.h +++ b/include/libgsmd/misc.h @@ -1,5 +1,5 @@ -#ifndef _LIBGSMD_H -#define _LIBGSMD_H +#ifndef _LIBGSMD_MISC_H +#define _LIBGSMD_MISC_H /* libgsmd.h - Library API for gsmd, the GSM Daemon * (C) 2006 by Harald Welte diff --git a/include/libgsmd/phonebook.h b/include/libgsmd/phonebook.h index 92c3a7f..a08d891 100644 --- a/include/libgsmd/phonebook.h +++ b/include/libgsmd/phonebook.h @@ -20,6 +20,36 @@ enum lgsm_pbook_type { LGSM_PB_TA_PHONEBOOK = 11, }; +/* Refer to GSM 07.07 subclause 8.14 */ +enum lgsm_pb_addr_type { + LGSM_PB_ATYPE_INTL = 145, + LGSM_PB_ATYPE_OTHE = 129, +}; + +/* Refer to GSM 07.07 subclause 8.12 */ +struct lgsm_phonebook_readrg { + int index1; + int index2; +}; + +/* Refer to GSM 07.07 subclause 8.14 */ +/* FIXME: the nlength and tlength depend on SIM, use +CPBR=? to get */ +#define LGSM_PB_NUMB_MAXLEN 44 +#define LGSM_PB_TEXT_MAXLEN 14 +struct lgsm_phonebook { + int index; + char numb[LGSM_PB_NUMB_MAXLEN+1]; + enum lgsm_pb_addr_type type; + char text[LGSM_PB_TEXT_MAXLEN+1]; +}; + +/* Refer to GSM 07.07 subclause 8.13 */ +/* FIXME: the tlength depends on SIM, use +CPBR=? to get */ +struct lgsm_phonebook_find { + char findtext[LGSM_PB_TEXT_MAXLEN+1]; +}; + +#if 0 /* Get a bitmask of supported phonebook types */ extern int lgsm_pb_get_types(struct lgsm_handle *lh, u_int32 *typemask); @@ -30,6 +60,7 @@ extern int lgsm_pb_get_range(struct lgsm_handle *lh, u_int32_t *nlength, *u_int32_t tlength); #define LGSM_PB_TEXT_MAXLEN 31 +#endif struct lgsm_pb_entry { struct lgsm_pb_entry *next; @@ -47,5 +78,26 @@ extern int lgsm_pb_get_entry(struct lgsm_handle *lh, extern int lgsm_pb_set_entry(struct lgsm_handle *lh, struct lgsm_pb_entry *pb); +/* Find phonebook entires which alphanumeric filed start + * with string */ +extern int lgsm_pb_find_entry(struct lgsm_handle *lh, + const struct lgsm_phonebook_find *pb_find); + +/* Read phonebook entry in location number index */ +extern int lgsm_pb_read_entry(struct lgsm_handle *lh, int index); + +/* Read phonebook entries in location number range */ +extern int lgsm_pb_read_entryies(struct lgsm_handle *lh, + const struct lgsm_phonebook_readrg *pb_readrg); + +/* Delete phonebook entry in location index */ +extern int lgsmd_pb_del_entry(struct lgsm_handle *lh, int index); + +/* Write phonebook entry in location */ +extern int lgsmd_pb_write_entry(struct lgsm_handle *lh, + const struct lgsm_phonebook *pb); + +/* Get the location range/nlength/tlength supported */ +extern int lgsm_pb_get_support(struct lgsm_handle *lh); #endif diff --git a/include/libgsmd/sms.h b/include/libgsmd/sms.h new file mode 100644 index 0000000..a07fc74 --- /dev/null +++ b/include/libgsmd/sms.h @@ -0,0 +1,114 @@ +#ifndef _LIBGSMD_SMS_H +#define _LIBGSMD_SMS_H + +#include + +/* Short Message Service */ + +/* Data Coding Scheme, refer to GSM 03.38 Clause 4 */ +#define B5_COMPRESSED (1<<5) +#define B4_CLASSMEANING (1<<4) +enum { + MESSAGE_CLASS_CLASS0 = 0x00, + MESSAGE_CLASS_CLASS1 = 0x01, + MESSAGE_CLASS_CLASS2 = 0x10, + MESSAGE_CLASS_CLASS3 = 0x11, +}; + +enum { + ALPHABET_DEFAULT = (0x00<<2), + ALPHABET_8BIT = (0x01<<2), + ALPHABET_UCS2 = (0x10<<2), + ALPHABET_RESERVED = (0x11<<2), +}; + +/* Coding of Alpha fields in the SIM for UCS2, (3GPP TS 11.11 Annex B) */ +//enum { + +//}; + + +/* SMS delflg from 3GPP TS 07.05, Clause 3.5.4 */ +enum lgsm_msg_sms_delflg { + LGSM_SMS_DELFLG_INDEX = 0, + LGSM_SMS_DELFLG_READ = 1, + LGSM_SMS_DELFLG_READ_SENT = 2, + LGSM_SMS_DELFLG_LEAVING_UNREAD = 3, + LGSM_SMS_DELFLG_ALL = 4, +}; + +/* SMS stat from 3GPP TS 07.05, Clause 3.1 */ +/* FIXME: only support PDU mode */ +enum lgsm_msg_sms_stat { + LGSM_SMS_REC_UNREAD = 0, + LGSM_SMS_REC_READ = 1, + LGSM_SMS_STO_UNSENT = 2, + LGSM_SMS_STO_SENT = 3, + LGSM_SMS_ALL = 4, +}; + +/* Refer to GSM 07.05 subclause 3.5.4 */ +struct lgsm_sms_delete { + int index; + enum lgsm_msg_sms_delflg delflg; +}; + +/* Refer to GSM 03.40 subclause 9.2.2.2 */ +#define LGSM_SMS_ADDR_MAXLEN 12 +#define LGSM_SMS_DATA_MAXLEN 140 +struct lgsm_sms { + /* FIXME: max length of data, + * 7 bit coding - 160(140*8/7); ucs2 coding - 70(140/2) */ + char addr[LGSM_SMS_ADDR_MAXLEN+1]; + char data[LGSM_SMS_DATA_MAXLEN+1]; +}; + +/* GSM 03.40 subclause 9.2.2.2 and GSM 07.05 subclause 4.4 and subclause 3.1 */ +struct lgsm_sms_write { + enum lgsm_msg_sms_stat stat; + struct lgsm_sms sms; +}; + +/* List Messages */ +extern int lgsm_sms_list(struct lgsm_handle *lh, enum gsmd_msg_sms_type stat); + +/* Read Message */ +extern int lgsm_sms_read(struct lgsm_handle *lh, int index); + +/* Delete Message */ +extern int lgsmd_sms_delete(struct lgsm_handle *lh, + const struct lgsm_sms_delete *sms_del); + +/* Send Message */ +extern int lgsmd_sms_send(struct lgsm_handle *lh, const struct lgsm_sms *sms); + +/* Write Message to Memory */ +extern int lgsmd_sms_write(struct lgsm_handle *lh, + const struct lgsm_sms_write *sms_write); + +/* Packing of 7-bit characters, refer to GSM 03.38 subclause 6.1.2.1.1 */ +extern int packing_7bit_character(char *src, char *dest); + +/* Packing of 7-bit characters, refer to GSM 03.38 subclause 6.1.2.1.1 */ +extern int unpacking_7bit_character(char *src, char *dest); + +/* Refer to 3GPP TS 11.11 Annex B */ +extern int packing_UCS2_80(char *src, char *dest); + +/* Refer to 3GPP TS 11.11 Annex B */ +extern int unpacking_UCS2_80(char *src, char *dest); + +/* Refer to 3GPP TS 11.11 Annex B */ +extern int packing_UCS2_81(char *src, char *dest); + +/* Refer to 3GPP TS 11.11 Annex B */ +extern int unpacking_UCS2_81(char *src, char *dest); + +/* Refer to 3GPP TS 11.11 Annex B */ +extern int packing_UCS2_82(char *src, char *dest); + +/* Refer to 3GPP TS 11.11 Annex B */ +extern int unpacking_UCS2_82(char *src, char *dest); + +#endif + 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