sms.py revision 6be2bce4a88f601f488643cfec2c1c8831c61091
1# Copyright (c) 2012 The Chromium OS Authors. All rights reserved.
2# Use of this source code is governed by a BSD-style license that can be
3# found in the LICENSE file.
4
5
6import dbus
7
8import dbus_std_ifaces
9import mm1
10
11class SMSConfigException(Exception):
12    """
13    Raised when an error occurs while setting the SMS property template.
14
15    """
16    pass
17
18class SMS(dbus_std_ifaces.DBusProperties):
19    """
20    Pseudomodem implementation of the org.freedesktop.ModemManager1.Sms
21    interface.
22
23    The SMS interface defines operations and properties of a single SMS
24    message.
25
26    Modems implementing the Messaging interface will export one SMS object for
27    each SMS stored in the device.
28
29    """
30
31    _sms_index = 0
32    _props_template = {}
33    _settable_props = set([ 'SMSC', 'Validity', 'Class', 'Storage',
34                            'DeliveryReportRequest' ])
35
36    def __init__(self, bus, sender_number, content):
37        self._sender_number = sender_number
38        self._content = content
39        dbus_std_ifaces.DBusProperties.__init__(
40                self, self._get_next_sms_path(), bus)
41
42    @classmethod
43    def _get_next_sms_path(cls):
44        path = mm1.SMS_PATH + '/' + str(cls._sms_index)
45        cls._sms_index += 1
46        return path
47
48    @classmethod
49    def set_config(cls, params):
50        """
51        Sets the values that should be used for SMS properties when a new
52        SMS is constructed.
53
54        @param params: A dictionary containing properties and values to set.
55                Only some properties are allowed to be set through this method,
56                which are contained in |_settable_props|. A value of "default"
57                can be used (which is a string) to use the default value for
58                that dictionary when constructing the next SMS object.
59
60        @raises SMSConfigException, if params is malformed or contains a
61                disallowed property.
62
63        """
64        if not isinstance(params, dict):
65            raise SMSConfigException('sms.SMS.set_config only accepts '
66                                     'dictionaries.')
67        keyset = set(params)
68        if not keyset.issubset(cls._settable_props):
69            raise SMSConfigException(
70                    'Properties: ' + repr(keyset.difference(params)) + ' are '
71                    'not settable.')
72
73        for key, value in params.iteritems():
74            if value == 'default' and cls._props_template.has_key(key):
75                cls._props_template.pop(key)
76            else:
77                cls._props_template[key] = value
78
79    def _InitializeProperties(self):
80        props = {}
81        props['State'] = dbus.types.UInt32(mm1.MM_SMS_STATE_UNKNOWN)
82        props['PduType'] = dbus.types.UInt32(mm1.MM_SMS_PDU_TYPE_UNKNOWN)
83        props['Number'] = self._sender_number
84        # For now, only support 'Text' and not 'Data'
85        props['Text'] = self._content
86        props['SMSC'] = self._props_template.get('SMSC', '1231212')
87        props['Validity'] = self._props_template.get('Validity',
88                dbus.types.Struct(
89                        [ dbus.types.UInt32(mm1.MM_SMS_VALIDITY_TYPE_UNKNOWN),
90                          dbus.types.UInt32(0) ],
91                        signature='uv'))
92        props['Class'] = self._props_template.get('Class', dbus.types.Int32(-1))
93        props['DeliveryReportRequest'] = self._props_template.get(
94                'DeliveryReportRequest',
95                dbus.types.Boolean(False))
96        props['Storage'] = self._props_template.get(
97                'Storage', dbus.types.UInt32(mm1.MM_SMS_STORAGE_UNKNOWN))
98        # TODO(armansito): This may be useful for split SMS messages. Need to
99        # study the SMS standard to figure out how to make use of this
100        # property.
101        props['MessageReference'] =  dbus.types.UInt32(0)
102
103        # Timestamp, DischargeTimestamp, and DeliveryState won't be available
104        # until an action (such as send, receive, status report) is take with
105        # the SMS.
106        props['Timestamp'] = ''
107        props['DischargeTimestamp'] = ''
108        return { mm1.I_SMS: props }
109
110    # Remember to decorate your concrete implementation with
111    # @utils.log_dbus_method()
112    @dbus.service.method(mm1.I_SMS)
113    def Send(self):
114        """
115        If the message has not yet been sent, queue it for delivery.
116
117        """
118        raise NotImplementedError()
119
120    # Remember to decorate your concrete implementation with
121    # @utils.log_dbus_method()
122    @dbus.service.method(mm1.I_SMS, in_signature='u')
123    def Store(self, storage):
124        """
125        Stores the message in the device if not already done.
126
127        @param storage: An MMSmsStorage value.
128
129        """
130        raise NotImplementedError()
131