mmsd consumers design
*********************

mmsd handles all the SMS WAP Push notifications delivered by oFono. In addition
to the processing of the MMS WAP Push notifications, it also provides a
dispatch mechanism for any other kind of WAP Push notifications to the
registered consumer.


Consumer basic
==============

In order to be identified by mmsd as a specific WAP Push notification consumer,
a program does not need to register in a sense of having to be running and
register. It just puts a D-Bus session activation configuration file in place
and then lets mmsd knows what's the D-Bus service name to call out to. mmsd
just has to send a D-Bus message to a target daemon and it will activate if
configured that way.

Each WAP Push notification consumer has to install (in /usr/lib/mms/push.d/
directory) their configuration file on what types of message they want to
consume and how they want to consume them. In addition it needs to install the
appropriate D-Bus session activation configuration file matching the same
service name (in /usr/share/dbus-1/services/).


Consumer configuration file
===========================

The content of the configuration file is the following, it describes the D-Bus
interface to be provided by a consumer (acting as a service provider):

[OMA-DM]
# simple match on the content type
MatchContentType=application/vnd.syncml.notification
# match on WAP application id
MatchApplicationId=x-wap-application:syncml.dm
# D-Bus session or system bus
TargetBus=session
# D-Bus service name
TargetService=com.meego.omadm
# D-Bus target path
TargetPath=/com/meego/omadm

You can have as many of group (i.e. [OMA-DM]) you want in one file or multiple
files. They will all be read on mmsd startup and can then be progressed. This
file must be located in /usr/lib/mms/push.d/ directory, its name extension must
be ".conf".

TargetPath, TargetService keys are mandatory.

TargetBus key is optional, if it is present the currently only supported value
is "session", if it is not present then the default value "session" will be
used.

MatchApplicationId key is optional, MatchContentType key is mandatory.

If only the MatchContentType key is present without the MatchApplicationId key,
then the consumer will be notified of all the received WAP push messages having
the same content type.

If the MatchApplicationId key is present, then the consumer will be notified of
all the received WAP push messages having both the same content type AND the
same application Id.

The D-Bus target method is named Notify, see the [Notify API] section below for
its signature details.


D-Bus activation service file
=============================

D-Bus needs a ".service" file to know what program to launch for a given
service, that file has to be installed in /usr/share/dbus-1/services/.

The content of the service file is the following:

[D-BUS Service]
Name=com.meego.omadm
Exec=/usr/bin/omadm_consumer


Notify API
==========

Service		unique name (must match the consumer's TargetService)
Interface	org.ofono.mms.PushConsumer
Object path	freely definable

Method		void Notify(array{byte} header, array{byte} body)

			Requests the consumer to process a new WAP Push
			notification that has arrived containing an appropriate
			message.

			Possible Errors: None


Python consumer sample
======================

The sample location and name must match the 'Exec' key entry value of the D-Bus
activation service file. This consumer receives the WAP Push Notification and
dumps the WAP Push Notifcation's header and body in 2 separates files.

The "Release" method is only present to gracefully exit the sample using the
shell command below:
# dbus-send --print-reply --session --dest="com.meego.omadm"
			/com/meego/omadm org.ofono.mms.PushConsumer.Release

#!/usr/bin/env python
import gobject

import dbus
import dbus.service
import dbus.mainloop.glib

if getattr(dbus, 'version', (0,0,0)) >= (0,41,0):
	import dbus.glib

class ServerObject(dbus.service.Object):
	def __init__(self):
		# Here the service name
		bus_name = dbus.service.BusName("com.meego.omadm",
							bus=dbus.SessionBus())
		# Here the object path
		dbus.service.Object.__init__(self, bus_name, "/com/meego/omadm")

	# Here the interface name, and the method is named same as on dbus.
	@dbus.service.method("org.ofono.mms.PushConsumer",
				in_signature="ayay", out_signature="i")
	def Notify(self, hdr, body):
		hdrstr = ""
		for hbyte in hdr:
			hdrstr += str(hbyte)

		print "hdr length = %d, hdr : %s" % (len (hdr), hdrstr)

		bodystr = ""
		for bbyte in body:
			bodystr += str(bbyte)

		print "body length = %d, body : %s" % (len(body), bodystr)

		f = open("/tmp/dm_header.out", "w")
		f.write("%s" % (hdrstr))
		f.close()

		f = open("/tmp/dm_body.out", "w")
		f.write("%s" % (bodystr))
		f.close()
		return 0

	@dbus.service.method("org.ofono.mms.PushConsumer")
	def Release(self):
		mainloop.quit()

if __name__ == '__main__':
	dbus.mainloop.glib.DBusGMainLoop(set_as_default=True)

	server = ServerObject()

	mainloop = gobject.MainLoop()
	mainloop.run()
