diff options
author | tick <tick@99fdad57-331a-0410-800a-d7fa5415bdb3> | 2007-10-25 10:35:26 +0000 |
---|---|---|
committer | tick <tick@99fdad57-331a-0410-800a-d7fa5415bdb3> | 2007-10-25 10:35:26 +0000 |
commit | 9e6cee624e011a163892e8798fb904cb6f2e804a (patch) | |
tree | 3cd7f4d69374c4bff10631eaf3e8f3f2dda7e8dc | |
parent | a4ee05b6942d5b82269a1a0ea453b5467e44b96e (diff) |
Adding decoder TP-DCS, and it's based on 3GPP TS23.038 Clause 4. (Erin Yueh)
git-svn-id: http://svn.openmoko.org/trunk/src/target/gsm@3265 99fdad57-331a-0410-800a-d7fa5415bdb3
-rw-r--r-- | include/gsmd/usock.h | 54 | ||||
-rw-r--r-- | src/gsmd/sms_pdu.c | 100 | ||||
-rw-r--r-- | src/util/event.c | 2 | ||||
-rw-r--r-- | src/util/shell.c | 2 |
4 files changed, 158 insertions, 0 deletions
diff --git a/include/gsmd/usock.h b/include/gsmd/usock.h index 66cdf48..f37cfa8 100644 --- a/include/gsmd/usock.h +++ b/include/gsmd/usock.h @@ -121,6 +121,58 @@ enum gsmd_sms_alphabet { ALPHABET_RESERVED = (0x11<<2), }; +/* bit 1 & bit0 */ +enum gsmd_sms_msg_class { + MSG_CLASS_CLASS0 = 0, + MSG_CLASS_CLASS1 = 1, + MSG_CLASS_CLASS2 = 2, + MSG_CLASS_CLASS3 = 3, + MSG_CLASS_NONE = 4, +}; + +/* bit 3 & bit 2*/ +enum gsmd_sms_alphabet_type { + SMS_ALPHABET_7_BIT_DEFAULT = 0, + SMS_ALPHABET_8_BIT = 1, + SMS_ALPHABET_UCS2 = 2, + SMS_ALPHABET_RESESRVED = 3, +}; + +enum gsmd_sms_msg_compressed { + NOT_COMPRESSED = 0, + COMPRESSED = 1, +}; + +/* message waiting indication */ +enum gsmd_sms_msg_waiting_group { + MESSAGE_WAITING_NONE = 0, + MESSAGE_WAITING_DISCARD = 1, + MESSAGE_WAITING_STORE = 2, + MESSAGE_WAITING_NONE_1111 = 3, +}; + +enum gsmd_sms_msg_waiting_type { + MESSAGE_WAITING_VOICEMAIL = 0, + MESSAGE_WAITING_FAX = 1, + MESSAGE_WAITING_EMAIL = 2, + MESSAGE_WAITING_OTHER = 3, +}; + +enum gsmd_sms_msg_waiting_active { + NOT_ACTIVE = 0, + ACTIVE = 1, +}; + +struct gsmd_sms_datacodingscheme { + enum gsmd_sms_msg_class msg_class; + enum gsmd_sms_alphabet_type alphabet; + enum gsmd_sms_msg_compressed is_compressed; + enum gsmd_sms_msg_waiting_group mwi_group; + enum gsmd_sms_msg_waiting_active mwi_active; + enum gsmd_sms_msg_waiting_type mwi_kind; + u_int8_t raw_dcs_data; +} __attribute__ ((packed)); + /* Refer to GSM 03.40 subclause 9.2.3.1 */ enum gsmd_sms_tp_mti { GSMD_SMS_TP_MTI_DELIVER = 0, @@ -325,6 +377,8 @@ struct gsmd_sms { u_int8_t length; u_int8_t coding_scheme; int has_header; + int is_voicemail; + struct gsmd_sms_datacodingscheme dcs; char data[GSMD_SMS_DATA_MAXLEN+1]; } __attribute__ ((packed)); diff --git a/src/gsmd/sms_pdu.c b/src/gsmd/sms_pdu.c index d461999..ae7a69d 100644 --- a/src/gsmd/sms_pdu.c +++ b/src/gsmd/sms_pdu.c @@ -87,6 +87,9 @@ int sms_pdu_to_msg(struct gsmd_sms_list *dst, if (len < 1 || len < 1 + src[0] + pdulen || pdulen < 1) return 1; + /* init voicemail is false */ + dst->payload.is_voicemail = 0; + /* Skip SMSC number and its Type-of-address */ len -= 1 + src[0]; src += 1 + src[0]; @@ -111,7 +114,19 @@ int sms_pdu_to_msg(struct gsmd_sms_list *dst, len -= 3 + i; src += 3 + i; + + /* check voicemail by TP-PID */ + if(src[0] == 0x5f) /* return call message */ + dst->payload.is_voicemail = 1; + /* decode TP-DCS */ + if(sms_pdu_decode_dcs(&dst->payload.dcs,src+1)) + return 1; + /* check voicemail by MWI */ + if(dst->payload.dcs.mwi_kind == MESSAGE_WAITING_VOICEMAIL && + (dst->payload.dcs.mwi_group == MESSAGE_WAITING_DISCARD || + dst->payload.dcs.mwi_group == MESSAGE_WAITING_STORE)) + dst->payload.is_voicemail = 1; /* TP-DCS */ switch (src[1] >> 4) { case 0x0 ... 3: /* General Data Coding indication */ @@ -315,3 +330,88 @@ int cbs_pdu_to_msg(struct gsmd_cbm *dst, u_int8_t *src, int pdulen, int len) memcpy(dst->data, src + 6, len - 6); return 0; } + +/* Refer to GSM 03.38 Clause 4, for TP-DCS */ +int sms_pdu_decode_dcs(struct gsmd_sms_datacodingscheme *dcs, + const u_int8_t *data) +{ + int pos = 0, i; + + /* init dcs value */ + dcs->mwi_active = NOT_ACTIVE; + dcs->mwi_kind = MESSAGE_WAITING_OTHER; + + /* bits 7-6 */ + i = ( data[pos] & 0xC0 ) >> 6; + switch( i ) + { + case 0: /* pattern 00xx xxxx */ + dcs->is_compressed = data[pos] & 0x20; + if( data[pos] & 0x10 ) + dcs->msg_class = data[pos] & 0x03; + else + /* no class information */ + dcs->msg_class = MSG_CLASS_NONE; + dcs->alphabet = ( data[pos] & 0x0C ) >> 2; + dcs->mwi_group = MESSAGE_WAITING_NONE; + break; + case 3: /* pattern 1111 xxxx */ + /* bits 5-4 */ + if( (data[pos] & 0x30) == 0x30 ) + { + /* bit 3 is reserved */ + /* bit 2 */ + dcs->alphabet = (data[pos] & 0x04 ) ? SMS_ALPHABET_8_BIT: + SMS_ALPHABET_7_BIT_DEFAULT; + /* bits 1-0 */ + dcs->msg_class = data[pos] & 0x03; + /* set remaining fields */ + dcs->is_compressed = NOT_COMPRESSED; + dcs->mwi_group = MESSAGE_WAITING_NONE_1111; + } + else + { + /* Message waiting groups */ + dcs->is_compressed = NOT_COMPRESSED; + dcs->msg_class = MSG_CLASS_NONE; + /* bits 5-4 */ + if( (data[pos] & 0x30) == 0x00 ) + { + dcs->mwi_group = MESSAGE_WAITING_DISCARD; + dcs->alphabet = SMS_ALPHABET_7_BIT_DEFAULT; + } + else if( (data[pos] & 0x30) == 0x10 ) + { + dcs->mwi_group = MESSAGE_WAITING_STORE; + dcs->alphabet = SMS_ALPHABET_7_BIT_DEFAULT; + } + else + { + dcs->mwi_group = MESSAGE_WAITING_STORE; + dcs->alphabet = SMS_ALPHABET_UCS2; + } + /* bit 3 */ + dcs->mwi_active = ( data[pos] & 0x08 ) ? ACTIVE : + NOT_ACTIVE; + /* bit 2 is reserved */ + /* bits 1-0 */ + dcs->mwi_kind = data[pos] & 0x03; + } + break; + default: + /* reserved values */ + dcs->msg_class = MSG_CLASS_NONE; + dcs->alphabet = SMS_ALPHABET_7_BIT_DEFAULT; + dcs->is_compressed = NOT_COMPRESSED; + dcs->mwi_group = MESSAGE_WAITING_NONE; + dcs->mwi_active = NOT_ACTIVE; + dcs->mwi_kind = MESSAGE_WAITING_OTHER; + break; + } + + if ( dcs->alphabet > SMS_ALPHABET_UCS2 ) + dcs->alphabet = SMS_ALPHABET_7_BIT_DEFAULT; + /* keep raw dcs data*/ + dcs->raw_dcs_data = data[pos]; + return 0; +} diff --git a/src/util/event.c b/src/util/event.c index ea0dcb4..f14f906 100644 --- a/src/util/event.c +++ b/src/util/event.c @@ -42,6 +42,8 @@ static int insms_handler(struct lgsm_handle *lh, int evt, char payload[GSMD_SMS_DATA_MAXLEN]; if (aux->u.sms.inlined) { sms = (struct gsmd_sms_list *) aux->data; + if(sms->payload.is_voicemail) + printf("EVENT: You have a voice mail \n"); printf("EVENT: Incoming SMS from/to %s%s, at %i%i-%i%i-%i%i " "%i%i:%i%i:%i%i, GMT%c%i\n", ((sms->addr.type & __GSMD_TOA_TON_MASK) == diff --git a/src/util/shell.c b/src/util/shell.c index 922b64e..096b2cf 100644 --- a/src/util/shell.c +++ b/src/util/shell.c @@ -152,6 +152,8 @@ static int sms_msghandler(struct lgsm_handle *lh, struct gsmd_msg_hdr *gmh) case GSMD_SMS_LIST: case GSMD_SMS_READ: sms = (struct gsmd_sms_list *) ((void *) gmh + sizeof(*gmh)); + if(sms->payload.is_voicemail) + printf("it's a voicemail \n"); printf("%s message %i from/to %s%s, at %i%i-%i%i-%i%i " "%i%i:%i%i:%i%i, GMT%c%i\n", msgtype[sms->stat], sms->index, |