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