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