[1/5] sms: Kill the sms->sender and use addr/ton/npi throughout the code
diff mbox

Message ID 1398423450-23319-1-git-send-email-holger@freyther.de
State Accepted
Headers show

Commit Message

Holger Freyther April 25, 2014, 10:57 a.m. UTC
From: Holger Hans Peter Freyther <zecke@selfish.org>

This is an incompatible database schema change. Store the type of
the address in the database for both the sender and the receiver.

Currently it is possible to use SMPP to store a SMS and the NPI
and TON will be lost on the delivery of the SMS. The schema is
changed to make the delivery always use the right NPI/TON. This
patch is not ready for the master branch as there is no upgrade
path for the HLR yet.
---
 openbsc/include/openbsc/gsm_data.h |  1 -
 openbsc/src/libmsc/db.c            | 62 +++++++++++++++++++++++---------------
 openbsc/src/libmsc/gsm_04_11.c     |  9 ++----
 openbsc/src/libmsc/smpp_openbsc.c  |  5 ++-
 4 files changed, 42 insertions(+), 35 deletions(-)

Comments

Holger Freyther April 25, 2014, 11:21 a.m. UTC | #1
On Fri, Apr 25, 2014 at 12:57:26PM +0200, Holger Freyther wrote:

> -	gsms->sender = subscr_get(conn->subscr);
> +	strncpy(gsms->src.addr, conn->subscr->extension, sizeof(gsms->src.addr)-1);

this includes the fix Ivan made. I would really appreciate if you
could send bugfixes like this to the list. 

holger
Ivan Kluchnikov April 25, 2014, 11:48 a.m. UTC | #2
Hi Holger,

> I would really appreciate if you
> could send bugfixes like this to the list.

Ok.
Also I can say, that we tested this patch set on our deployments and
the code is working stable.

Patch
diff mbox

diff --git a/openbsc/include/openbsc/gsm_data.h b/openbsc/include/openbsc/gsm_data.h
index 8f24d4f..4338cd6 100644
--- a/openbsc/include/openbsc/gsm_data.h
+++ b/openbsc/include/openbsc/gsm_data.h
@@ -304,7 +304,6 @@  struct gsm_sms_addr {
 
 struct gsm_sms {
 	unsigned long long id;
-	struct gsm_subscriber *sender;
 	struct gsm_subscriber *receiver;
 	struct gsm_sms_addr src, dst;
 	enum gsm_sms_source_id source;
diff --git a/openbsc/src/libmsc/db.c b/openbsc/src/libmsc/db.c
index bfa4e75..df26b04 100644
--- a/openbsc/src/libmsc/db.c
+++ b/openbsc/src/libmsc/db.c
@@ -95,7 +95,6 @@  static char *create_stmts[] = {
 		"id INTEGER PRIMARY KEY AUTOINCREMENT, "
 		"created TIMESTAMP NOT NULL, "
 		"sent TIMESTAMP, "
-		"sender_id INTEGER NOT NULL, "
 		"receiver_id INTEGER NOT NULL, "
 		"deliver_attempts INTEGER NOT NULL DEFAULT 0, "
 		/* data directly copied/derived from SMS */
@@ -105,7 +104,12 @@  static char *create_stmts[] = {
 		"protocol_id INTEGER NOT NULL, "
 		"data_coding_scheme INTEGER NOT NULL, "
 		"ud_hdr_ind INTEGER NOT NULL, "
-		"dest_addr TEXT, "
+		"src_addr TEXT NOT NULL, "
+		"src_ton INTEGER NOT NULL, "
+		"src_npi INTEGER NOT NULL, "
+		"dest_addr TEXT NOT NULL, "
+		"dest_ton INTEGER NOT NULL, "
+		"dest_npi INTEGER NOT NULL, "
 		"user_data BLOB, "	/* TP-UD */
 		/* additional data, interpreted from SMS */
 		"header BLOB, "		/* UD Header */
@@ -1214,7 +1218,7 @@  int db_subscriber_assoc_imei(struct gsm_subscriber *subscriber, char imei[GSM_IM
 int db_sms_store(struct gsm_sms *sms)
 {
 	dbi_result result;
-	char *q_text, *q_daddr;
+	char *q_text, *q_daddr, *q_saddr;
 	unsigned char *q_udata;
 	char *validity_timestamp = "2222-2-2";
 
@@ -1222,25 +1226,35 @@  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->dst.addr, &q_daddr);
+	dbi_conn_quote_string_copy(conn, (char *)sms->src.addr, &q_saddr);
 	dbi_conn_quote_binary_copy(conn, sms->user_data, sms->user_data_len,
 				   &q_udata);
+
 	/* FIXME: correct validity period */
 	result = dbi_conn_queryf(conn,
 		"INSERT INTO SMS "
-		"(created, sender_id, receiver_id, valid_until, "
+		"(created, receiver_id, valid_until, "
 		 "reply_path_req, status_rep_req, protocol_id, "
-		 "data_coding_scheme, ud_hdr_ind, dest_addr, "
-		 "user_data, text) VALUES "
-		"(datetime('now'), %llu, %llu, %u, "
-		 "%u, %u, %u, %u, %u, %s, %s, %s)",
-		sms->sender->id,
+		 "data_coding_scheme, ud_hdr_ind, "
+		 "user_data, text, "
+		 "dest_addr, dest_ton, dest_npi, "
+		 "src_addr, src_ton, src_npi) VALUES "
+		"(datetime('now'), %llu, %u, "
+		"%u, %u, %u, "
+		"%u, %u, "
+		"%s, %s, "
+		"%s, %u, %u, "
+		"%s, %u, %u)",
 		sms->receiver ? sms->receiver->id : 0, validity_timestamp,
 		sms->reply_path_req, sms->status_rep_req, sms->protocol_id,
 		sms->data_coding_scheme, sms->ud_hdr_ind,
-		q_daddr, q_udata, q_text);
+		q_udata, q_text,
+		q_daddr, sms->dst.ton, sms->dst.npi,
+		q_saddr, sms->src.ton, sms->src.npi);
 	free(q_text);
-	free(q_daddr);
 	free(q_udata);
+	free(q_daddr);
+	free(q_saddr);
 
 	if (!result)
 		return -EIO;
@@ -1252,8 +1266,8 @@  int db_sms_store(struct gsm_sms *sms)
 static struct gsm_sms *sms_from_result(struct gsm_network *net, dbi_result result)
 {
 	struct gsm_sms *sms = sms_alloc();
-	long long unsigned int sender_id, receiver_id;
-	const char *text, *daddr;
+	long long unsigned int receiver_id;
+	const char *text, *daddr, *saddr;
 	const unsigned char *user_data;
 
 	if (!sms)
@@ -1261,18 +1275,6 @@  static struct gsm_sms *sms_from_result(struct gsm_network *net, dbi_result resul
 
 	sms->id = dbi_result_get_ulonglong(result, "id");
 
-	sender_id = dbi_result_get_ulonglong(result, "sender_id");
-	sms->sender = subscr_get_by_id(net, sender_id);
-	if (!sms->sender) {
-		LOGP(DLSMS, LOGL_ERROR,
-			"Failed to find sender(%llu) for id(%llu)\n",
-			sender_id, sms->id);
-		sms_free(sms);
-		return NULL;
-	}
-
-	strncpy(sms->src.addr, sms->sender->extension, sizeof(sms->src.addr)-1);
-
 	receiver_id = dbi_result_get_ulonglong(result, "receiver_id");
 	sms->receiver = subscr_get_by_id(net, receiver_id);
 	if (!sms->receiver) {
@@ -1293,12 +1295,22 @@  static struct gsm_sms *sms_from_result(struct gsm_network *net, dbi_result resul
 						  "data_coding_scheme");
 	/* sms->msg_ref is temporary and not stored in DB */
 
+	sms->dst.npi = dbi_result_get_uint(result, "dest_npi");
+	sms->dst.ton = dbi_result_get_uint(result, "dest_ton");
 	daddr = dbi_result_get_string(result, "dest_addr");
 	if (daddr) {
 		strncpy(sms->dst.addr, daddr, sizeof(sms->dst.addr));
 		sms->dst.addr[sizeof(sms->dst.addr)-1] = '\0';
 	}
 
+	sms->src.npi = dbi_result_get_uint(result, "src_npi");
+	sms->src.ton = dbi_result_get_uint(result, "src_ton");
+	saddr = dbi_result_get_string(result, "src_addr");
+	if (saddr) {
+		strncpy(sms->src.addr, saddr, sizeof(sms->src.addr));
+		sms->src.addr[sizeof(sms->src.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))
diff --git a/openbsc/src/libmsc/gsm_04_11.c b/openbsc/src/libmsc/gsm_04_11.c
index 5f10759..b2100d8 100644
--- a/openbsc/src/libmsc/gsm_04_11.c
+++ b/openbsc/src/libmsc/gsm_04_11.c
@@ -73,8 +73,6 @@  struct gsm_sms *sms_alloc(void)
 void sms_free(struct gsm_sms *sms)
 {
 	/* drop references to subscriber structure */
-	if (sms->sender)
-		subscr_put(sms->sender);
 	if (sms->receiver)
 		subscr_put(sms->receiver);
 #ifdef BUILD_SMPP
@@ -97,8 +95,7 @@  struct gsm_sms *sms_from_text(struct gsm_subscriber *receiver,
 	sms->receiver = subscr_get(receiver);
 	strncpy(sms->text, text, sizeof(sms->text)-1);
 
-	sms->sender = subscr_get(sender);
-	strncpy(sms->src.addr, sms->sender->extension, sizeof(sms->src.addr)-1);
+	strncpy(sms->src.addr, sender->extension, sizeof(sms->src.addr)-1);
 	sms->reply_path_req = 0;
 	sms->status_rep_req = 0;
 	sms->ud_hdr_ind = 0;
@@ -378,12 +375,12 @@  static int gsm340_rx_tpdu(struct gsm_subscriber_connection *conn, struct msgb *m
 		}
 	}
 
-	gsms->sender = subscr_get(conn->subscr);
+	strncpy(gsms->src.addr, conn->subscr->extension, sizeof(gsms->src.addr)-1);
 
 	LOGP(DLSMS, LOGL_INFO, "RX SMS: Sender: %s, MTI: 0x%02x, VPF: 0x%02x, "
 	     "MR: 0x%02x PID: 0x%02x, DCS: 0x%02x, DA: %s, "
 	     "UserDataLength: 0x%02x, UserData: \"%s\"\n",
-	     subscr_name(gsms->sender), sms_mti, sms_vpf, gsms->msg_ref,
+	     subscr_name(conn->subscr), sms_mti, sms_vpf, gsms->msg_ref,
 	     gsms->protocol_id, gsms->data_coding_scheme, gsms->dst.addr,
 	     gsms->user_data_len,
 			sms_alphabet == DCS_7BIT_DEFAULT ? gsms->text :
diff --git a/openbsc/src/libmsc/smpp_openbsc.c b/openbsc/src/libmsc/smpp_openbsc.c
index ab558ce..ec541c2 100644
--- a/openbsc/src/libmsc/smpp_openbsc.c
+++ b/openbsc/src/libmsc/smpp_openbsc.c
@@ -133,7 +133,6 @@  static int submit_to_sms(struct gsm_sms **psms, struct gsm_network *net,
 	strncpy(sms->dst.addr, dest->extension, sizeof(sms->dst.addr)-1);
 
 	/* fill in the source address */
-	sms->sender = subscr_get_by_id(net, 1);
 	sms->src.ton = submit->source_addr_ton;
 	sms->src.npi = submit->source_addr_npi;
 	strncpy(sms->src.addr, (char *)submit->source_addr, sizeof(sms->src.addr)-1);
@@ -475,13 +474,13 @@  static int deliver_to_esme(struct osmo_esme *esme, struct gsm_sms *sms,
 		deliver.source_addr_npi = NPI_Land_Mobile_E212;
 		snprintf((char *)deliver.source_addr,
 			sizeof(deliver.source_addr), "%s",
-			sms->sender->imsi);
+			conn->subscr->imsi);
 	} else {
 		deliver.source_addr_ton = TON_Network_Specific;
 		deliver.source_addr_npi = NPI_ISDN_E163_E164;
 		snprintf((char *)deliver.source_addr,
 			 sizeof(deliver.source_addr), "%s",
-			 sms->sender->extension);
+			 conn->subscr->extension);
 	}
 
 	deliver.dest_addr_ton	= sms->dst.ton;