All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH] Implement writing EF-MBDN on SetProperty or Enhanced Voicemail IE.
@ 2009-08-05  7:08 Andrzej Zaborowski
  2009-08-05 16:33 ` Andrzej Zaborowski
  2009-08-05 18:59 ` Denis Kenzior
  0 siblings, 2 replies; 4+ messages in thread
From: Andrzej Zaborowski @ 2009-08-05  7:08 UTC (permalink / raw)
  To: ofono

[-- Attachment #1: Type: text/plain, Size: 11461 bytes --]

I've not tested this on a real SIM yet.
---
 src/message-waiting.c |   51 ++++++++++++++++++++++++++++++++++++------------
 src/simutil.c         |   27 +++++++++++++++++++++++++
 src/simutil.h         |    2 +
 src/smsutil.c         |   47 +++++++++++++++++++++++++++++---------------
 src/smsutil.h         |    8 +++++++
 5 files changed, 106 insertions(+), 29 deletions(-)

diff --git a/src/message-waiting.c b/src/message-waiting.c
index 14a6e9c..568cea6 100644
--- a/src/message-waiting.c
+++ b/src/message-waiting.c
@@ -164,12 +164,12 @@ static DBusMessage *mw_get_properties(DBusConnection *conn,
 	return reply;
 }
 
-static void mbdn_set_cb(gboolean ok, void *data)
+static void mbdn_set_cb(struct ofono_modem *modem, int ok, void *data)
 {
 	struct mbdn_set_request *req = data;
 	struct ofono_phone_number *old = &req->mw->mailbox_number[req->mailbox];
 	const char *property;
-	DBusMessage *reply;
+	DBusMessage *reply = 0; /* Quiet a warning */
 
 	if (!ok) {
 		if (req->msg)
@@ -208,11 +208,19 @@ out:
 	g_free(req);
 }
 
-static void set_mbdn(struct ofono_modem *modem, int mailbox,
+static DBusMessage *set_mbdn(struct ofono_modem *modem, int mailbox,
 			const char *number, DBusMessage *msg)
 {
 	DBusConnection *conn = ofono_dbus_get_connection();
 	struct mbdn_set_request *req;
+	unsigned char efmbdn[255];
+
+	if (modem->message_waiting->efmbdn_record_id[mailbox] == 0) {
+		if (msg)
+			return __ofono_error_failed(msg);
+
+		return NULL;
+	}
 
 	req = g_new0(struct mbdn_set_request, 1);
 
@@ -222,8 +230,19 @@ static void set_mbdn(struct ofono_modem *modem, int mailbox,
 	string_to_phone_number(number, &req->number);
 	req->msg = dbus_message_ref(msg);
 
-	/* TODO: Fill the actual sim_write data */
-	mbdn_set_cb(TRUE, req);
+	sim_adn_build(efmbdn, req->mw->efmbdn_length, &req->number);
+
+	if (ofono_sim_write(modem, SIM_EFMBDN_FILEID, mbdn_set_cb,
+			OFONO_SIM_FILE_STRUCTURE_FIXED,
+			req->mw->efmbdn_record_id[mailbox],
+			efmbdn, req->mw->efmbdn_length, req) == -1) {
+		g_free(req);
+
+		if (msg)
+			return __ofono_error_failed(msg);
+	}
+
+	return NULL;
 }
 
 static DBusMessage *mw_set_property(DBusConnection *conn, DBusMessage *msg,
@@ -275,8 +294,7 @@ static DBusMessage *mw_set_property(DBusConnection *conn, DBusMessage *msg,
 		if (g_str_equal(cur_number, value))
 			return dbus_message_new_method_return(msg);
 
-		set_mbdn(modem, i, value, msg);
-		return NULL;
+		return set_mbdn(modem, i, value, msg);
 	}
 
 	return __ofono_error_invalid_args(msg);
@@ -599,6 +617,7 @@ static void handle_enhanced_voicemail_iei(struct ofono_modem *modem,
 {
 	int profile, n;
 	gboolean set;
+	struct sms_address mailbox_address;
 
 	if (length < 3)
 		return;
@@ -614,9 +633,10 @@ static void handle_enhanced_voicemail_iei(struct ofono_modem *modem,
 		if (discard)
 			*discard = (iei[0] & (1 << 4)) ? FALSE : TRUE;
 
-		/* TODO: VM_MAILBOX_ACCESS_ADDRESS */
-		n = 2 + (iei[1] + 1) / 2;
-		if (length < n + 11)
+		/* VM_MAILBOX_ACCESS_ADDRESS */
+		n = 0;
+		if (!sms_decode_address_field(iei + 1, length - 1, &n,
+					FALSE, &mailbox_address))
 			return;
 
 		/* TODO: VM_MESSAGE_PRIORITY_INDICATION */
@@ -636,9 +656,10 @@ static void handle_enhanced_voicemail_iei(struct ofono_modem *modem,
 		if (discard)
 			*discard = (iei[0] & (1 << 4)) ? FALSE : TRUE;
 
-		/* TODO: VM_MAILBOX_ACCESS_ADDRESS */
-		n = 2 + (iei[1] + 1) / 2;
-		if (length < n + 11)
+		/* VM_MAILBOX_ACCESS_ADDRESS */
+		n = 0;
+		if (!sms_decode_address_field(iei + 1, length - 1, &n,
+					FALSE, &mailbox_address))
 			return;
 
 		/* Other parameters currently not supported */
@@ -647,6 +668,10 @@ static void handle_enhanced_voicemail_iei(struct ofono_modem *modem,
 		mw_set_indicator(modem, profile, SMS_MWI_TYPE_VOICE,
 					set, iei[n + 2]);
 	}
+
+	if (mailbox_address.address[0] != '\0')
+		set_mbdn(modem, SMS_MWI_TYPE_VOICE,
+				sms_address_to_string(&mailbox_address), NULL);
 }
 
 void ofono_handle_sms_mwi(struct ofono_modem *modem,
diff --git a/src/simutil.c b/src/simutil.c
index 51b1f5c..7a0830e 100644
--- a/src/simutil.c
+++ b/src/simutil.c
@@ -426,3 +426,30 @@ gboolean sim_adn_parse(const unsigned char *data, int length,
 
 	return TRUE;
 }
+
+void sim_adn_build(unsigned char *data, int length,
+			const struct ofono_phone_number *ph)
+{
+	int number_len = strlen(ph->number);
+
+	/* Alpha-Identifier field */
+	if (length > 14) {
+		memset(data, 0xff, length - 14);
+		data += length - 14;
+	}
+
+	number_len = (number_len + 1) / 2;
+	*data++ = number_len + 1;
+
+	/* Use given number type and 'Unknown' for Numbering Plan */
+	*data++ = 0x80 | (ph->type << 4) | 0;
+
+	encode_bcd_number(ph->number, data);
+	memset(data + number_len, 0xff, 10 - number_len);
+	data += 10;
+
+	/* CCP1 unused */
+	*data++ = 0xff;
+	/* Ext1 unused */
+	*data++ = 0xff;
+}
diff --git a/src/simutil.h b/src/simutil.h
index c2b1e20..9d198db 100644
--- a/src/simutil.h
+++ b/src/simutil.h
@@ -82,3 +82,5 @@ static inline enum sim_file_access file_access_condition_decode(int bcd)
 
 gboolean sim_adn_parse(const unsigned char *data, int length,
 			struct ofono_phone_number *ph);
+void sim_adn_build(unsigned char *data, int length,
+			const struct ofono_phone_number *ph);
diff --git a/src/smsutil.c b/src/smsutil.c
index ad38ed9..ba2bbc1 100644
--- a/src/smsutil.c
+++ b/src/smsutil.c
@@ -110,6 +110,17 @@ static inline int to_semi_oct(char in)
 	return digit;
 }
 
+void encode_bcd_number(const char *number, unsigned char *out)
+{
+	while (number[0] != '\0' && number[1] != '\0') {
+		*out = to_semi_oct(*number++);
+		*out++ |= to_semi_oct(*number++) << 4;
+	}
+
+	if (*number)
+		*out = to_semi_oct(*number) | 0xf0;
+}
+
 /* Returns whether the DCS could be parsed successfully, e.g. no reserved
  * values were used
  */
@@ -446,8 +457,8 @@ static gboolean encode_validity_period(const struct sms_validity_period *vp,
 	return FALSE;
 }
 
-static gboolean encode_address(const struct sms_address *in, gboolean sc,
-				unsigned char *pdu, int *offset)
+gboolean sms_encode_address_field(const struct sms_address *in, gboolean sc,
+					unsigned char *pdu, int *offset)
 {
 	size_t len = strlen(in->address);
 	unsigned char addr_len = 0;
@@ -533,9 +544,9 @@ out:
 	return TRUE;
 }
 
-static gboolean decode_address(const unsigned char *pdu, int len,
-				int *offset, gboolean sc,
-				struct sms_address *out)
+gboolean sms_decode_address_field(const unsigned char *pdu, int len,
+					int *offset, gboolean sc,
+					struct sms_address *out)
 {
 	unsigned char addr_len;
 	unsigned char addr_type;
@@ -635,7 +646,7 @@ static gboolean encode_deliver(const struct sms_deliver *in, unsigned char *pdu,
 
 	set_octet(pdu, offset, oct);
 
-	if (encode_address(&in->oaddr, FALSE, pdu, offset) == FALSE)
+	if (sms_encode_address_field(&in->oaddr, FALSE, pdu, offset) == FALSE)
 		return FALSE;
 
 	set_octet(pdu, offset, in->pid);
@@ -672,7 +683,8 @@ static gboolean decode_deliver(const unsigned char *pdu, int len,
 	out->deliver.udhi = is_bit_set(octet, 6);
 	out->deliver.rp = is_bit_set(octet, 7);
 
-	if (!decode_address(pdu, len, &offset, FALSE, &out->deliver.oaddr))
+	if (!sms_decode_address_field(pdu, len, &offset,
+					FALSE, &out->deliver.oaddr))
 		return FALSE;
 
 	if (!next_octet(pdu, len, &offset, &out->deliver.pid))
@@ -883,7 +895,7 @@ static gboolean encode_status_report(const struct sms_status_report *in,
 
 	set_octet(pdu, offset, in->mr);
 
-	if (!encode_address(&in->raddr, FALSE, pdu, offset))
+	if (!sms_encode_address_field(&in->raddr, FALSE, pdu, offset))
 		return FALSE;
 
 	if (!encode_scts(&in->scts, pdu, offset))
@@ -935,8 +947,8 @@ static gboolean decode_status_report(const unsigned char *pdu, int len,
 	if (!next_octet(pdu, len, &offset, &out->status_report.mr))
 		return FALSE;
 
-	if (!decode_address(pdu, len, &offset, FALSE,
-				&out->status_report.raddr))
+	if (!sms_decode_address_field(pdu, len, &offset, FALSE,
+					&out->status_report.raddr))
 		return FALSE;
 
 	if (!decode_scts(pdu, len, &offset, &out->status_report.scts))
@@ -1173,7 +1185,7 @@ static gboolean encode_submit(const struct sms_submit *in,
 
 	set_octet(pdu, offset, in->mr);
 
-	if (encode_address(&in->daddr, FALSE, pdu, offset) == FALSE)
+	if (sms_encode_address_field(&in->daddr, FALSE, pdu, offset) == FALSE)
 		return FALSE;
 
 	set_octet(pdu, offset, in->pid);
@@ -1215,7 +1227,8 @@ static gboolean decode_submit(const unsigned char *pdu, int len,
 	if (!next_octet(pdu, len, &offset, &out->submit.mr))
 		return FALSE;
 
-	if (!decode_address(pdu, len, &offset, FALSE, &out->submit.daddr))
+	if (!sms_decode_address_field(pdu, len, &offset,
+					FALSE, &out->submit.daddr))
 		return FALSE;
 
 	if (!next_octet(pdu, len, &offset, &out->submit.pid))
@@ -1265,7 +1278,7 @@ static gboolean encode_command(const struct sms_command *in,
 
 	set_octet(pdu, offset, in->mn);
 
-	if (!encode_address(&in->daddr, FALSE, pdu, offset))
+	if (!sms_encode_address_field(&in->daddr, FALSE, pdu, offset))
 		return FALSE;
 
 	set_octet(pdu, offset, in->cdl);
@@ -1305,7 +1318,8 @@ static gboolean decode_command(const unsigned char *pdu, int len,
 	if (!next_octet(pdu, len, &offset, &out->command.mn))
 		return FALSE;
 
-	if (!decode_address(pdu, len, &offset, FALSE, &out->command.daddr))
+	if (!sms_decode_address_field(pdu, len, &offset,
+					FALSE, &out->command.daddr))
 		return FALSE;
 
 	if (!next_octet(pdu, len, &offset, &out->command.cdl))
@@ -1328,7 +1342,7 @@ gboolean sms_encode(const struct sms *in, int *len, int *tpdu_len,
 
 	if (in->type == SMS_TYPE_DELIVER || in->type == SMS_TYPE_SUBMIT ||
 			in->type == SMS_TYPE_COMMAND)
-		if (!encode_address(&in->sc_addr, TRUE, pdu, &offset))
+		if (!sms_encode_address_field(&in->sc_addr, TRUE, pdu, &offset))
 			return FALSE;
 
 	tpdu_start = offset;
@@ -1396,7 +1410,8 @@ gboolean sms_decode(const unsigned char *pdu, int len, gboolean outgoing,
 		return FALSE;
 
 	if (tpdu_len < len) {
-		if (!decode_address(pdu, len, &offset, TRUE, &out->sc_addr))
+		if (!sms_decode_address_field(pdu, len, &offset,
+						TRUE, &out->sc_addr))
 			return FALSE;
 	}
 
diff --git a/src/smsutil.h b/src/smsutil.h
index d362aa9..95d0c78 100644
--- a/src/smsutil.h
+++ b/src/smsutil.h
@@ -401,6 +401,7 @@ static inline unsigned char bit_field(unsigned char oct, int start, int num)
 }
 
 void extract_bcd_number(const unsigned char *buf, int len, char *out);
+void encode_bcd_number(const char *number, unsigned char *out);
 
 gboolean sms_decode(const unsigned char *pdu, int len, gboolean outgoing,
 			int tpdu_len, struct sms *out);
@@ -408,6 +409,13 @@ gboolean sms_decode(const unsigned char *pdu, int len, gboolean outgoing,
 gboolean sms_encode(const struct sms *in, int *len, int *tpdu_len,
 			unsigned char *pdu);
 
+gboolean sms_decode_address_field(const unsigned char *pdu, int len,
+					int *offset, gboolean sc,
+					struct sms_address *out);
+
+gboolean sms_encode_address_field(const struct sms_address *in, gboolean sc,
+					unsigned char *pdu, int *offset);
+
 int sms_udl_in_bytes(guint8 ud_len, guint8 dcs);
 
 time_t sms_scts_to_time(const struct sms_scts *scts, struct tm *remote);
-- 
1.6.1


^ permalink raw reply related	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2009-08-05 18:59 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2009-08-05  7:08 [PATCH] Implement writing EF-MBDN on SetProperty or Enhanced Voicemail IE Andrzej Zaborowski
2009-08-05 16:33 ` Andrzej Zaborowski
2009-08-05 17:48   ` Denis Kenzior
2009-08-05 18:59 ` Denis Kenzior

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.