From deb782ae35f8276609458ec9e9fb4add70b64614 Mon Sep 17 00:00:00 2001
From: Dennis Wehrle <openbsc@wehrle.it>
Date: Tue, 22 Mar 2011 18:18:14 +0100
Subject: [PATCH] SMS-fix: due to a misuse of user_data_len the sms where cropped (on vty) and wrongly stored on the database.

---
 openbsc/src/libmsc/db.c        |   22 ++++++++++++++--------
 openbsc/src/libmsc/gsm_04_11.c |    4 +---
 openbsc/src/libmsc/gsm_04_80.c |    4 +++-
 3 files changed, 18 insertions(+), 12 deletions(-)

diff --git a/openbsc/src/libmsc/db.c b/openbsc/src/libmsc/db.c
index 95a7d36..cf72332 100644
--- a/openbsc/src/libmsc/db.c
+++ b/openbsc/src/libmsc/db.c
@@ -996,8 +996,10 @@ int db_sms_store(struct gsm_sms *sms)
 
 	dbi_conn_quote_string_copy(conn, (char *)sms->text, &q_text);
 	dbi_conn_quote_string_copy(conn, (char *)sms->dest_addr, &q_daddr);
-	dbi_conn_quote_binary_copy(conn, sms->user_data, sms->user_data_len,
-				   &q_udata);
+
+	int octet_len = gsm_get_octet_len(sms->user_data_len);
+	dbi_conn_quote_binary_copy(conn, sms->user_data, octet_len, &q_udata);
+
 	/* FIXME: correct validity period */
 	result = dbi_conn_queryf(conn,
 		"INSERT INTO SMS "
@@ -1057,17 +1059,21 @@ static struct gsm_sms *sms_from_result(struct gsm_network *net, dbi_result resul
 		sms->dest_addr[sizeof(sms->dest_addr)-1] = '\0';
 	}
 
-	sms->user_data_len = dbi_result_get_field_length(result, "user_data");
-	user_data = dbi_result_get_binary(result, "user_data");
-	if (sms->user_data_len > sizeof(sms->user_data))
-		sms->user_data_len = (u_int8_t) sizeof(sms->user_data);
-	memcpy(sms->user_data, user_data, sms->user_data_len);
-
 	text = dbi_result_get_string(result, "text");
 	if (text) {
 		strncpy(sms->text, text, sizeof(sms->text));
 		sms->text[sizeof(sms->text)-1] = '\0';
 	}
+
+	/* user_data_len contains the number of septets, therefore use the "text"-field to get user_data_len. */
+	/* But each extension character has to be count twice, because they need 2 septets. */
+	sms->user_data_len = gsm_get_septet_len(text);
+
+	user_data = dbi_result_get_binary(result, "user_data");
+	if (sms->user_data_len > sizeof(sms->user_data))
+		sms->user_data_len = (u_int8_t) sizeof(sms->user_data);
+	memcpy(sms->user_data, user_data, sms->user_data_len);
+
 	return sms;
 }
 
diff --git a/openbsc/src/libmsc/gsm_04_11.c b/openbsc/src/libmsc/gsm_04_11.c
index 812e758..891571f 100644
--- a/openbsc/src/libmsc/gsm_04_11.c
+++ b/openbsc/src/libmsc/gsm_04_11.c
@@ -526,9 +526,7 @@ static int gsm340_gen_tpdu(struct msgb *msg, struct gsm_sms *sms)
 	/* generate TP-UD */
 	switch (gsm338_get_sms_alphabet(sms->data_coding_scheme)) {
 	case DCS_7BIT_DEFAULT:
-		octet_len = sms->user_data_len*7/8;
-		if (sms->user_data_len*7%8 != 0)
-			octet_len++;
+		octet_len = gsm_get_octet_len(sms->user_data_len);
 		/* Warning, user_data_len indicates the amount of septets
 		 * (characters), we need amount of octets occupied */
 		smsp = msgb_put(msg, octet_len);
diff --git a/openbsc/src/libmsc/gsm_04_80.c b/openbsc/src/libmsc/gsm_04_80.c
index 494c319..90227c7 100644
--- a/openbsc/src/libmsc/gsm_04_80.c
+++ b/openbsc/src/libmsc/gsm_04_80.c
@@ -73,7 +73,9 @@ int gsm0480_send_ussd_response(struct gsm_subscriber_connection *conn,
 	/* First put the payload text into the message */
 	ptr8 = msgb_put(msg, 0);
 	response_len = gsm_7bit_encode(ptr8, response_text);
-	msgb_put(msg, response_len);
+
+	int octet_len = gsm_get_octet_len(response_len);
+	msgb_put(msg, octet_len);
 
 	/* Then wrap it as an Octet String */
 	msgb_wrap_with_TL(msg, ASN1_OCTET_STRING_TAG);
-- 
1.7.1

