xref: /aosp_15_r20/external/autotest/client/common_lib/cros/network/xmlrpc_datatypes.py (revision 9c5db1993ded3edbeafc8092d69fe5de2ee02df7)
1# Lint as: python2, python3
2# Copyright (c) 2013 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
6import copy
7import logging
8import pprint
9import sys
10
11from autotest_lib.client.common_lib.cros import xmlrpc_types
12from autotest_lib.client.common_lib.cros.network import xmlrpc_security_types
13
14
15def deserialize(serialized):
16    """Deserialize an argument to the XmlRpc proxy.
17
18    @param serialized dict representing a serialized object.
19    @return the corresponding deserialized object.
20
21    """
22    return xmlrpc_types.deserialize(serialized, module=sys.modules[__name__])
23
24
25class AssociationParameters(xmlrpc_types.XmlRpcStruct):
26    """Describes parameters used in WiFi connection attempts."""
27
28    DEFAULT_DISCOVERY_TIMEOUT = 15
29    DEFAULT_ASSOCIATION_TIMEOUT = 15
30    DEFAULT_CONFIGURATION_TIMEOUT = 15
31    # Mode for most routers and access points.
32    STATION_TYPE_MANAGED = 'managed'
33    # Mode for certain kinds of p2p networks like old Android phone hotspots.
34    STATION_TYPE_IBSS = 'ibss'
35
36    @property
37    def security(self):
38        """@return string security type for this network."""
39        return self.security_config.security
40
41
42    @property
43    def security_parameters(self):
44        """@return dict of service property/value pairs related to security."""
45        return self.security_config.get_shill_service_properties()
46
47
48    def __init__(self, ssid=None, security_config=None,
49                 discovery_timeout=DEFAULT_DISCOVERY_TIMEOUT,
50                 association_timeout=DEFAULT_ASSOCIATION_TIMEOUT,
51                 configuration_timeout=DEFAULT_CONFIGURATION_TIMEOUT,
52                 is_hidden=False, save_credentials=False, station_type=None,
53                 expect_failure=False, guid=None, autoconnect=None,
54                 bgscan_config=None):
55        """Construct an AssociationParameters.
56
57        @param ssid string the network to connect to (e.g. 'GoogleGuest').
58        @param security_config SecurityConfig object or serialized version.
59        @param discovery_timeout int timeout for discovery in seconds.
60        @param association_timeout int timeout for association in seconds.
61        @param configuration_timeout int timeout for configuration in seconds.
62        @param is_hidden bool True iff this is a hidden service.
63        @param save_credentials True iff the credentials should be saved for
64                this service.
65        @param station_type string station type to connect with.  Usually
66                left unfilled unless we're attempting to connect to a
67                non-managed BSS.  One of STATION_TYPE_* above.
68        @param expect_failure bool True if we expect this connection attempt to
69                fail.
70        @param guid string unique identifier of this service.
71        @param autoconnect: bool or None.  None indicates that this should not
72                be set one way or the other, while a boolean indicates a desired
73                value.
74
75        """
76        super(AssociationParameters, self).__init__()
77        self.ssid = ssid
78        # The security config is a little tricky.  When we're being deserialized
79        # this is passed to us in the form of a dictionary which also needs
80        # to be deserialized into a real object.
81        if isinstance(security_config, dict):
82            self.security_config = xmlrpc_security_types.deserialize(
83                    security_config)
84        elif security_config is not None:
85            self.security_config = copy.copy(security_config)
86        else:
87            self.security_config = xmlrpc_security_types.SecurityConfig()
88
89        # The bgscan configuration is similar to the security configuration.
90        if isinstance(bgscan_config, dict):
91            self.bgscan_config = deserialize(bgscan_config)
92        elif bgscan_config is not None:
93            self.bgscan_config = copy.copy(bgscan_config)
94        else:
95            self.bgscan_config = BgscanConfiguration()
96        self.discovery_timeout = discovery_timeout
97        self.association_timeout = association_timeout
98        self.configuration_timeout = configuration_timeout
99        self.is_hidden = is_hidden
100        self.save_credentials = save_credentials
101        self.station_type = station_type
102        self.expect_failure = expect_failure
103        self.guid = guid
104        self.autoconnect = autoconnect
105
106
107    def __str__(self):
108        """Returns a formatted string of member parameters"""
109        return pprint.pformat(self.__dict__)
110
111
112class AssociationResult(xmlrpc_types.XmlRpcStruct):
113    """Describes the result of an association attempt."""
114
115    def __init__(self, success=False, discovery_time=-1.0,
116                 association_time=-1.0, configuration_time=-1.0,
117                 failure_reason='unknown'):
118        """Construct an AssociationResult.
119
120        @param success bool True iff we were successful in connecting to
121                this WiFi network.
122        @param discovery_time int number of seconds it took to find and call
123                connect on a network from the time the proxy is told to connect.
124                This includes scanning time.
125        @param association_time int number of seconds it takes from the moment
126                that we call connect to the moment we're fully associated with
127                the BSS.  This includes wpa handshakes.
128        @param configuration_time int number of seconds it takes from
129                association till we have an IP address and mark the network as
130                being either online or portalled.
131        @param failure_reason int holds a descriptive reason for why the
132                negotiation failed when |successs| is False.  Undefined
133                otherwise.
134
135        """
136        super(AssociationResult, self).__init__()
137        self.success = success
138        self.discovery_time = discovery_time
139        self.association_time = association_time
140        self.configuration_time = configuration_time
141        self.failure_reason = failure_reason
142
143
144    @staticmethod
145    def from_dbus_proxy_output(raw):
146        """Factory for AssociationResult.
147
148        The object which knows how to talk over DBus to shill is not part of
149        autotest and as a result can't return a AssociationResult.  Instead,
150        it returns a similar looing tuple, which we'll parse.
151
152        @param raw tuple from ShillProxy.
153        @return AssociationResult parsed output from ShillProxy.
154
155        """
156        return AssociationResult(success=raw[0],
157                                 discovery_time=raw[1],
158                                 association_time=raw[2],
159                                 configuration_time=raw[3],
160                                 failure_reason=raw[4])
161
162
163class BgscanConfiguration(xmlrpc_types.XmlRpcStruct):
164    """Describes how to configure wpa_supplicant on a DUT."""
165
166    # Clears shill's bgscan method property on the WiFi device.
167    # This causes shill to choose between simple and no bgscan
168    # depending on the number of visible BSS's for a network.
169    SCAN_METHOD_DEFAULT = 'default'
170    # Disables background scan entirely.
171    SCAN_METHOD_NONE = 'none'
172    # A periodic background scan based on signal strength.
173    SCAN_METHOD_SIMPLE = 'simple'
174
175    # These three parameters come out shill's wifi.cc.
176    # and refer to inputs to the simple scanning method.
177    DEFAULT_SHORT_INTERVAL_SECONDS = 64
178    DEFAULT_LONG_INTERVAL_SECONDS = 60
179    DEFAULT_SIGNAL_THRESHOLD = -72
180
181    def __init__(self, interface=None, signal=DEFAULT_SIGNAL_THRESHOLD,
182                 short_interval=DEFAULT_SHORT_INTERVAL_SECONDS,
183                 long_interval=DEFAULT_LONG_INTERVAL_SECONDS,
184                 method=SCAN_METHOD_DEFAULT):
185        """Construct a BgscanConfiguration.
186
187        @param interface string interface to configure (e.g. wlan0).
188        @param signal int signal threshold to scan below.
189        @param short_interval int wpa_supplicant short scanning interval.
190        @param long_interval int wpa_supplicant normal scanning interval.
191        @param method string a valid wpa_supplicant scanning algorithm (e.g.
192                any of SCAN_METHOD_* above).
193
194        """
195        super(BgscanConfiguration, self).__init__()
196        self.interface = interface
197        self.signal = signal
198        self.short_interval = short_interval
199        self.long_interval = long_interval
200        self.method = method
201
202
203    def set_auto_signal(self, signal_average, signal_offset=None,
204                        signal_noise=None):
205        """Set the signal threshold automatically from observed parameters.
206
207        @param signal_average int average signal level.
208        @param signal_offset int amount to adjust the average by.
209        @param signal_noise int amount of background noise observed.
210
211        """
212        signal = signal_average
213        if signal_offset:
214            signal += signal_offset
215        if signal_noise:
216            # Compensate for real noise vs standard estimate
217            signal -= 95 + signal_noise
218        logging.debug('Setting signal via auto configuration: '
219                      'avg=%d, offset=%r, noise=%r => signal=%d.',
220                      signal_average, signal_offset, signal_noise, signal)
221        self.signal = signal
222
223
224class ConfigureServiceParameters(xmlrpc_types.XmlRpcStruct):
225    """Describes a group of optional settings for use with ConfigureService.
226
227    The Manager in shill has a method ConfigureService which takes a dictionary
228    of parameters, and uses some of them to look up a service, and sets the
229    remainder of the properties on the service.  This struct represents
230    some of the optional parameters that can be set in this way.  Current
231    consumers of this interface look up the service by GUID.
232
233    """
234
235    def __init__(self, guid, passphrase=None, autoconnect=None):
236        """Construct a ConfigureServiceParameters.
237
238        @param guid string GUID of the service to configure.
239        @param passphrase string optional psk passphrase.
240        @param autoconnect: bool or None.  None indicates that this should not
241                be set one way or the other, while a boolean indicates a desired
242                value.
243
244        """
245        super(ConfigureServiceParameters, self).__init__()
246        self.guid = guid
247        self.passphrase = passphrase
248        self.autoconnect = autoconnect
249