libmsc: Allow to set sender id when sending SMS from the VTY

Signed-off-by: Sylvain Munaut <tnt@246tNt.com>
diff --git a/openbsc/include/openbsc/gsm_04_11.h b/openbsc/include/openbsc/gsm_04_11.h
index 2abe3e2..72b6948 100644
--- a/openbsc/include/openbsc/gsm_04_11.h
+++ b/openbsc/include/openbsc/gsm_04_11.h
@@ -29,7 +29,7 @@
 
 struct gsm_sms *sms_alloc(void);
 void sms_free(struct gsm_sms *sms);
-struct gsm_sms *sms_from_text(struct gsm_subscriber *receiver, int dcs, const char *text);
+struct gsm_sms *sms_from_text(struct gsm_subscriber *receiver, struct gsm_subscriber *sender, int dcs, const char *text);
 
 void _gsm411_sms_trans_free(struct gsm_trans *trans);
 int gsm411_send_sms_subscr(struct gsm_subscriber *subscr,
diff --git a/openbsc/src/libmsc/gsm_04_11.c b/openbsc/src/libmsc/gsm_04_11.c
index 46bb074..f22a7e1 100644
--- a/openbsc/src/libmsc/gsm_04_11.c
+++ b/openbsc/src/libmsc/gsm_04_11.c
@@ -84,7 +84,9 @@
 	talloc_free(sms);
 }
 
-struct gsm_sms *sms_from_text(struct gsm_subscriber *receiver, int dcs, const char *text)
+struct gsm_sms *sms_from_text(struct gsm_subscriber *receiver,
+                              struct gsm_subscriber *sender,
+                              int dcs, const char *text)
 {
 	struct gsm_sms *sms = sms_alloc();
 
@@ -94,8 +96,7 @@
 	sms->receiver = subscr_get(receiver);
 	strncpy(sms->text, text, sizeof(sms->text)-1);
 
-	/* FIXME: don't use ID 1 static */
-	sms->sender = subscr_get_by_id(receiver->net, 1);
+	sms->sender = subscr_get(sender);
 	strncpy(sms->src.addr, sms->sender->extension, sizeof(sms->src.addr)-1);
 	sms->reply_path_req = 0;
 	sms->status_rep_req = 0;
diff --git a/openbsc/src/libmsc/token_auth.c b/openbsc/src/libmsc/token_auth.c
index cf26ba8..45b5a8e 100644
--- a/openbsc/src/libmsc/token_auth.c
+++ b/openbsc/src/libmsc/token_auth.c
@@ -63,6 +63,7 @@
 		return 0;
 
 	if (subscr->flags & GSM_SUBSCRIBER_FIRST_CONTACT) {
+		struct gsm_subscriber *sender;
 		uint32_t token;
 		char *sms_str;
 
@@ -79,7 +80,13 @@
 			goto unauth;
 		}
 
-		sms = sms_from_text(subscr, 0, sms_str);
+
+		/* FIXME: don't use ID 1 static */
+		sender = subscr_get_by_id(subscr->net, 1);
+
+		sms = sms_from_text(subscr, sender, 0, sms_str);
+
+		subscr_put(sender);
 		talloc_free(sms_str);
 		if (!sms) {
 			rc = -ENOMEM;
diff --git a/openbsc/src/libmsc/vty_interface_layer3.c b/openbsc/src/libmsc/vty_interface_layer3.c
index eeeb51f..60eacad 100644
--- a/openbsc/src/libmsc/vty_interface_layer3.c
+++ b/openbsc/src/libmsc/vty_interface_layer3.c
@@ -144,12 +144,13 @@
 	return CMD_SUCCESS;
 }
 
-static int _send_sms_str(struct gsm_subscriber *receiver, char *str,
-			 uint8_t tp_pid)
+static int _send_sms_str(struct gsm_subscriber *receiver,
+                         struct gsm_subscriber *sender,
+                         char *str, uint8_t tp_pid)
 {
 	struct gsm_sms *sms;
 
-	sms = sms_from_text(receiver, 0, str);
+	sms = sms_from_text(receiver, sender, 0, str);
 	sms->protocol_id = tp_pid;
 
 	/* store in database for the queue */
@@ -229,24 +230,39 @@
 
 DEFUN(subscriber_send_sms,
       subscriber_send_sms_cmd,
-      "subscriber " SUBSCR_TYPES " ID sms send .LINE",
+      "subscriber " SUBSCR_TYPES " ID sms sender " SUBSCR_TYPES " SENDER_ID send .LINE",
 	SUBSCR_HELP "SMS Operations\n" "Send SMS\n" "Actual SMS Text")
 {
 	struct gsm_network *gsmnet = gsmnet_from_vty(vty);
 	struct gsm_subscriber *subscr = get_subscr_by_argv(gsmnet, argv[0], argv[1]);
+	struct gsm_subscriber *sender = get_subscr_by_argv(gsmnet, argv[2], argv[3]);
 	char *str;
 	int rc;
 
 	if (!subscr) {
 		vty_out(vty, "%% No subscriber found for %s %s%s",
 			argv[0], argv[1], VTY_NEWLINE);
-		return CMD_WARNING;
+		rc = CMD_WARNING;
+		goto err;
 	}
-	str = argv_concat(argv, argc, 2);
-	rc = _send_sms_str(subscr, str, 0);
+
+	if (!sender) {
+		vty_out(vty, "%% No sender found for %s %s%s",
+			argv[2], argv[3], VTY_NEWLINE);
+		rc = CMD_WARNING;
+		goto err;
+	}
+
+	str = argv_concat(argv, argc, 4);
+	rc = _send_sms_str(subscr, sender, str, 0);
 	talloc_free(str);
 
-	subscr_put(subscr);
+err:
+	if (sender)
+		subscr_put(sender);
+
+	if (subscr)
+		subscr_put(subscr);
 
 	return rc;
 }
@@ -259,20 +275,34 @@
 {
 	struct gsm_network *gsmnet = gsmnet_from_vty(vty);
 	struct gsm_subscriber *subscr = get_subscr_by_argv(gsmnet, argv[0], argv[1]);
+	struct gsm_subscriber *sender = get_subscr_by_argv(gsmnet, argv[2], argv[3]);
 	char *str;
 	int rc;
 
 	if (!subscr) {
 		vty_out(vty, "%% No subscriber found for %s %s%s",
 			argv[0], argv[1], VTY_NEWLINE);
-		return CMD_WARNING;
+		rc = CMD_WARNING;
+		goto err;
 	}
 
-	str = argv_concat(argv, argc, 2);
-	rc = _send_sms_str(subscr, str, 64);
+	if (!sender) {
+		vty_out(vty, "%% No sender found for %s %s%s",
+			argv[2], argv[3], VTY_NEWLINE);
+		rc = CMD_WARNING;
+		goto err;
+	}
+
+	str = argv_concat(argv, argc, 4);
+	rc = _send_sms_str(subscr, sender, str, 64);
 	talloc_free(str);
 
-	subscr_put(subscr);
+err:
+	if (sender)
+		subscr_put(sender);
+
+	if (subscr)
+		subscr_put(subscr);
 
 	return rc;
 }