Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1105)

Unified Diff: sms_message.cc

Issue 6740005: Handle UCS-2 data coding scheme for SMS messsages. (Closed) Base URL: ssh://gitrw.chromium.org:9222/cromo.git@master
Patch Set: Remove redundant comparison operations Created 9 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « no previous file | sms_message_unittest.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: sms_message.cc
diff --git a/sms_message.cc b/sms_message.cc
index 5f4001bcb08500819efb6cada55ceae95971dfb1..b9f7dcba47316f0c4cd35d5b4cde0371de990486 100644
--- a/sms_message.cc
+++ b/sms_message.cc
@@ -8,9 +8,12 @@
#include "utilities.h"
-static const uint8_t INTL_E164_NUMBER_FORMAT = 0x91;
-static const uint8_t SMSC_TIMESTAMP_LEN = 7;
-static const size_t MIN_PDU_LEN = 7 + SMSC_TIMESTAMP_LEN;
+static const uint8_t kIntlE164NumberFormat = 0x91;
+static const uint8_t kAlphaFormat = 0xd0;
+static const uint8_t kDataCodingSchemeGsm7 = 0;
+static const uint8_t kDataCodingSchemeUcs2 = 8;
+static const uint8_t kSmscTimestampLen = 7;
+static const size_t kMinPduLen = 7 + kSmscTimestampLen;
static char NibbleToChar(uint8_t nibble) {
switch (nibble) {
@@ -58,8 +61,8 @@ SmsMessage* SmsMessage::CreateMessage(const uint8_t* pdu, size_t pdu_len) {
utilities::DumpHex(pdu, pdu_len);
// Make sure the PDU is of a valid size
- if (pdu_len < MIN_PDU_LEN) {
- LOG(INFO) << "PDU too short: " << pdu_len << " vs. " << MIN_PDU_LEN;
+ if (pdu_len < kMinPduLen) {
+ LOG(INFO) << "PDU too short: " << pdu_len << " vs. " << kMinPduLen;
return NULL;
}
@@ -73,7 +76,7 @@ SmsMessage* SmsMessage::CreateMessage(const uint8_t* pdu, size_t pdu_len) {
// 1 octet - type of sender address (value 0x91 is international E.164)
// variable - sender address
// 1 octet - protocol identifier (value = 0)
- // 1 octet - data coding scheme (value = 0)
+ // 1 octet - data coding scheme (value 0 is GSM7, 8 is UCS2)
// 7 octets - SMSC timestamp
// 1 octet - user data length in septets
// variable - user data (body of message)
@@ -86,9 +89,9 @@ SmsMessage* SmsMessage::CreateMessage(const uint8_t* pdu, size_t pdu_len) {
uint8_t smsc_addr_num_octets = pdu[0];
uint8_t variable_length_items = smsc_addr_num_octets;
- if (pdu_len < variable_length_items + MIN_PDU_LEN) {
+ if (pdu_len < variable_length_items + kMinPduLen) {
LOG(INFO) << "PDU too short: " << pdu_len << " vs. "
- << variable_length_items + MIN_PDU_LEN;
+ << variable_length_items + kMinPduLen;
return NULL;
}
@@ -99,29 +102,29 @@ SmsMessage* SmsMessage::CreateMessage(const uint8_t* pdu, size_t pdu_len) {
// and thus an integral number of octets
uint8_t sender_addr_num_octets = (sender_addr_num_digits + 1) >> 1;
variable_length_items += sender_addr_num_octets;
- if (pdu_len < variable_length_items + MIN_PDU_LEN) {
+ if (pdu_len < variable_length_items + kMinPduLen) {
LOG(INFO) << "PDU too short: " << pdu_len << " vs. "
- << variable_length_items + MIN_PDU_LEN;
+ << variable_length_items + kMinPduLen;
return NULL;
}
uint8_t tp_pid_offset = msg_start_offset + 3 + sender_addr_num_octets;
- uint8_t user_data_offset = tp_pid_offset + 2 + SMSC_TIMESTAMP_LEN;
+ uint8_t user_data_offset = tp_pid_offset + 2 + kSmscTimestampLen;
uint8_t user_data_num_septets = pdu[user_data_offset];
variable_length_items += (7 * (user_data_num_septets + 1 )) / 8;
- if (pdu_len < variable_length_items + MIN_PDU_LEN) {
+ if (pdu_len < variable_length_items + kMinPduLen) {
LOG(INFO) << "PDU too short: " << pdu_len << " vs. "
- << variable_length_items + MIN_PDU_LEN;
+ << variable_length_items + kMinPduLen;
return NULL;
}
- // wow do some validity checks on the values of several fields in the PDU
+ // now do some validity checks on the values of several fields in the PDU
// smsc number format must be international, E.164
- if (pdu[1] != INTL_E164_NUMBER_FORMAT) {
+ if (pdu[1] != kIntlE164NumberFormat) {
LOG(INFO) << "Invalid SMSC address format: " << std::hex << (int)pdu[1]
- << " vs. " << std::hex << INTL_E164_NUMBER_FORMAT;
+ << " vs. " << std::hex << kIntlE164NumberFormat;
return NULL;
}
// we only handle SMS-DELIVER messages, with more-messages-to-send false
@@ -130,6 +133,14 @@ SmsMessage* SmsMessage::CreateMessage(const uint8_t* pdu, size_t pdu_len) {
<< (int)pdu[msg_start_offset] << " vs. 0x04";
return NULL;
}
+ // we only handle E164 and ALPHA sender address formats
+ uint8_t sender_addr_type = pdu[msg_start_offset + 2];
+ if (sender_addr_type != kIntlE164NumberFormat &&
+ sender_addr_type != kAlphaFormat) {
+ LOG(INFO) << "Unhandled sender address format: " << std::hex <<
+ sender_addr_type;
+ return NULL;
+ }
// we only handle the basic protocol identifier
if (pdu[tp_pid_offset] != 0) {
LOG(INFO) << "Unhandled protocol identifier: " << std::hex
@@ -137,23 +148,38 @@ SmsMessage* SmsMessage::CreateMessage(const uint8_t* pdu, size_t pdu_len) {
return NULL;
}
// for data coding scheme, we only handle the default alphabet, i.e. GSM7
- if (pdu[tp_pid_offset+1] != 0) {
+ uint8_t dcs = pdu[tp_pid_offset+1] & 0x0ec;
+ if (dcs != kDataCodingSchemeGsm7 && dcs != kDataCodingSchemeUcs2) {
LOG(INFO) << "Unhandled data coding scheme: " << std::hex
- << (int)pdu[tp_pid_offset+1] << " vs. 0x00";
+ << (int)pdu[tp_pid_offset+1];
return NULL;
}
std::string smsc_addr = SemiOctetsToBcdString(&pdu[2],
smsc_addr_num_octets-1);
- std::string sender_addr = SemiOctetsToBcdString(&pdu[msg_start_offset+3],
- sender_addr_num_octets);
+ std::string sender_addr;
+ if (sender_addr_type == kIntlE164NumberFormat)
+ sender_addr = SemiOctetsToBcdString(&pdu[msg_start_offset+3],
+ sender_addr_num_octets);
+ else {
+ uint8_t *bytes = new uint8_t[sender_addr_num_octets+1];
+ bytes[0] = (sender_addr_num_digits * 4) / 7;
+ memcpy(&bytes[1], &pdu[msg_start_offset+3], sender_addr_num_octets);
+ sender_addr = utilities::Gsm7ToUtf8String(bytes);
+ delete [] bytes;
+ }
+
std::string sc_timestamp = SemiOctetsToBcdString(&pdu[tp_pid_offset+2],
- SMSC_TIMESTAMP_LEN-1);
- std::string msg_text = utilities::Gsm7ToUtf8String(&pdu[user_data_offset]);
+ kSmscTimestampLen-1);
+ std::string msg_text;
+ if (dcs == kDataCodingSchemeGsm7)
+ msg_text = utilities::Gsm7ToUtf8String(&pdu[user_data_offset]);
+ else
+ msg_text = utilities::Ucs2ToUtf8String(&pdu[user_data_offset]);
// The last two semi-octets of the timestamp indicate an offset from
// GMT, and are handled differently than the first 12 semi-octets.
- uint8_t toff_octet = pdu[tp_pid_offset+1+SMSC_TIMESTAMP_LEN];
+ uint8_t toff_octet = pdu[tp_pid_offset+1+kSmscTimestampLen];
sc_timestamp += (toff_octet & 0x8) ? '-' : '+';
uint8_t offset_in_hours =
((toff_octet & 0x7) << 4 | (toff_octet & 0xf0) >> 4) / 4;
« no previous file with comments | « no previous file | sms_message_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698