1# Copyright 2023 Google LLC
2#
3# Licensed under the Apache License, Version 2.0 (the 'License');
4# you may not use this file except in compliance with the License.
5# You may obtain a copy of the License at
6#
7#     https://www.apache.org/licenses/LICENSE-2.0
8#
9# Unless required by applicable law or agreed to in writing, software
10# distributed under the License is distributed on an 'AS IS' BASIS,
11# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12# See the License for the specific language governing permissions and
13# limitations under the License.
14"""Client Class to access the Floss GATT server interface."""
15
16import collections
17import logging
18
19from floss.pandora.floss import bluetooth_gatt_service
20from floss.pandora.floss import floss_enums
21from floss.pandora.floss import observer_base
22from floss.pandora.floss import utils
23from gi.repository import GLib
24
25
26class GattServerCallbacks:
27    """Callbacks for the GATT server interface.
28
29    Implement this to observe these callbacks when exporting callbacks via register_server.
30    """
31
32    def on_server_registered(self, status, server_id):
33        """Called when GATT server registered.
34
35        Args:
36            status: floss_enums.GattStatus.
37            server_id: Bluetooth GATT server id.
38        """
39        pass
40
41    def on_server_connection_state(self, server_id, connected, addr):
42        """Called when GATT server connection state changed.
43
44        Args:
45            server_id: Bluetooth GATT server id.
46            connected: A boolean value that indicates whether the GATT server is connected.
47            addr: Remote device MAC address.
48        """
49        pass
50
51    def on_service_added(self, status, service):
52        """Called when service added.
53
54        Args:
55            status: floss_enums.GattStatus.
56            service: BluetoothGattService.
57        """
58        pass
59
60    def on_service_removed(self, status, handle):
61        """Called when service removed.
62
63        Args:
64            status: floss_enums.GattStatus.
65            handle: Service record handle.
66        """
67        pass
68
69    def on_characteristic_read_request(self, addr, trans_id, offset, is_long, handle):
70        """Called when there is a request to read a characteristic.
71
72        Args:
73            addr: Remote device MAC address.
74            trans_id: Transaction id.
75            offset: Represents the offset from which the attribute value should be read.
76            is_long: A boolean value representing whether the characteristic size is longer than what we can put in the
77                     ATT PDU.
78            handle: The characteristic handle.
79        """
80        pass
81
82    def on_descriptor_read_request(self, addr, trans_id, offset, is_long, handle):
83        """Called when there is a request to read a descriptor.
84
85        Args:
86            addr: Remote device MAC address.
87            trans_id: Transaction id.
88            offset: Represents the offset from which the descriptor value should be read.
89            is_long: A boolean value representing whether the descriptor size is longer than what we can put in the
90                     ATT PDU.
91            handle: The descriptor handle.
92        """
93        pass
94
95    def on_characteristic_write_request(self, addr, trans_id, offset, length, is_prep, need_rsp, handle, value):
96        """Called when there is a request to write a characteristic.
97
98        Args:
99            addr: Remote device MAC address.
100            trans_id: Transaction id.
101            offset: Represents the offset at which the attribute value should be written.
102            length: The length of the attribute value that should be written.
103            is_prep: A boolean value representing whether it's a 'prepare write' command.
104            need_rsp: A boolean value representing whether it's a 'write no response' command.
105            handle: The characteristic handle.
106            value: The value that should be written to the attribute.
107        """
108        pass
109
110    def on_descriptor_write_request(self, addr, trans_id, offset, length, is_prep, need_rsp, handle, value):
111        """Called when there is a request to write a descriptor.
112
113        Args:
114            addr: Remote device MAC address.
115            trans_id: Transaction id.
116            offset: The offset value at which the value should be written.
117            length: The length of the value that should be written.
118            is_prep: A boolean value representing whether it's a 'prepare write' command.
119            need_rsp: A boolean value representing whether it's a 'write no response' command.
120            handle: The descriptor handle.
121            value: The value that should be written to the descriptor.
122        """
123        pass
124
125    def on_execute_write(self, addr, trans_id, exec_write):
126        """Called when execute write.
127
128        Args:
129            addr: Remote device MAC address.
130            trans_id: Transaction id.
131            exec_write: A boolean value that indicates whether the write operation should be executed or canceled.
132        """
133        pass
134
135    def on_notification_sent(self, addr, status):
136        """Called when notification sent.
137
138        Args:
139            addr: Remote device MAC address.
140            status: floss_enums.GattStatus.
141        """
142        pass
143
144    def on_mtu_changed(self, addr, mtu):
145        """Called when the MTU changed.
146
147        Args:
148            addr: Remote device MAC address.
149            mtu: Maximum transmission unit.
150        """
151        pass
152
153    def on_phy_update(self, addr, tx_phy, rx_phy, status):
154        """Called when physical update.
155
156        Args:
157            addr: Remote device MAC address.
158            tx_phy: The new TX PHY for the connection.
159            rx_phy: The new RX PHY for the connection.
160            status: floss_enums.GattStatus.
161        """
162        pass
163
164    def on_phy_read(self, addr, tx_phy, rx_phy, status):
165        """Called when physical read.
166
167        Args:
168            addr: Remote device MAC address.
169            tx_phy: The current transmit PHY for the connection.
170            rx_phy: The current receive PHY for the connection.
171            status: floss_enums.GattStatus.
172        """
173        pass
174
175    def on_connection_updated(self, addr, interval, latency, timeout, status):
176        """Called when connection updated.
177
178        Args:
179            addr: Remote device MAC address.
180            interval: Connection interval value.
181            latency: The number of consecutive connection events during which the device doesn't have to be listening.
182            timeout: Supervision timeout for this connection in milliseconds.
183            status: floss_enums.GattStatus.
184        """
185        pass
186
187    def on_subrate_change(self, addr, subrate_factor, latency, cont_num, timeout, status):
188        """Called when subrate changed.
189
190        Args:
191            addr: Remote device MAC address.
192            subrate_factor: Subrate factor value.
193            latency: The number of consecutive connection events during which the device doesn't have to be listening.
194            cont_num: Continuation number.
195            timeout: Supervision timeout for this connection in milliseconds.
196            status: floss_enums.GattStatus.
197        """
198        pass
199
200
201def uuid16_to_uuid128(uuid):
202    """Converts 16-bit UUID to 128-bit UUID.
203
204    Args:
205        uuid: 16-bit UUID value.
206
207    Returns:
208        128-bit UUID.
209    """
210    return utils.uuid16_to_uuid128(uuid).upper()
211
212
213class FlossGattServer(GattServerCallbacks):
214    """Handles method calls and callbacks from the GATT server interface."""
215
216    ADAPTER_SERVICE = 'org.chromium.bluetooth'
217    GATT_SERVER_INTERFACE = 'org.chromium.bluetooth.BluetoothGatt'
218    GATT_OBJECT_PATTERN = '/org/chromium/bluetooth/hci{}/gatt'
219    GATT_CB_OBJ_NAME = 'test_gatt_server'
220    CB_EXPORTED_INTF = 'org.chromium.bluetooth.BluetoothGattServerCallback'
221
222    # Bluetooth GATT DataBase attribute type.
223    BTGATT_DB_PRIMARY_SERVICE = 0
224    BTGATT_DB_SECONDARY_SERVICE = 1
225    BTGATT_DB_INCLUDED_SERVICE = 2
226    BTGATT_DB_CHARACTERISTIC = 3
227    BTGATT_DB_DESCRIPTOR = 4
228
229    GATT_READ_AUTH_REQUIRED = floss_enums.GattPermission.PERM_READ_ENCRYPTED
230    GATT_READ_MITM_REQUIRED = floss_enums.GattPermission.PERM_READ_ENC_MITM
231    GATT_WRITE_AUTH_REQUIRED = (floss_enums.GattPermission.PERM_WRITE_ENCRYPTED |
232                                floss_enums.GattPermission.PERM_WRITE_SIGNED)
233    GATT_WRITE_MITM_REQUIRED = (floss_enums.GattPermission.PERM_WRITE_ENC_MITM |
234                                floss_enums.GattPermission.PERM_WRITE_SIGNED_MITM)
235
236    SERVICE_ATTR_UUID = uuid16_to_uuid128('7777')
237    SERVER_CHANGED_CHAR_UUID = uuid16_to_uuid128('2a05')
238    SERVER_SUP_FEAT_UUID = uuid16_to_uuid128('2b3a')
239    CLIENT_SUP_FEAT_UUID = uuid16_to_uuid128('2b29')
240    DATABASE_HASH_UUID = uuid16_to_uuid128('2b2a')
241    LONG_CHAR_UUID = uuid16_to_uuid128('b000')
242    DESCRIPTOR_UUID = uuid16_to_uuid128('b001')
243    KEY_SIZE_CHAR_UUID = uuid16_to_uuid128('b002')
244    UNAUTHORIZED_CHAR_UUID = uuid16_to_uuid128('b003')
245    AUTHENTICATION_CHAR_UUID = uuid16_to_uuid128('b004')
246    INVALID_FOR_LE_UUID = uuid16_to_uuid128('b005')
247    INVALID_FOR_BR_EDR_UUID = uuid16_to_uuid128('b006')
248    NO_READ_CHAR_UUID = uuid16_to_uuid128('b007')
249    NO_WRITE_CHAR_UUID = uuid16_to_uuid128('b008')
250    SHORT_CHAR_UUID = uuid16_to_uuid128('b009')
251    WRITE_NO_RESPONSE_CHAR_UUID = uuid16_to_uuid128('b00a')
252    NOTIFY_CHAR_UUID = uuid16_to_uuid128('b00b')
253    AUTHENTICATE_SHORT_CHAR_UUID = uuid16_to_uuid128('b00c')
254    CCC_DESCRIPTOR_UUID = uuid16_to_uuid128('2902')
255    LONG_CHAR_512_UUID = uuid16_to_uuid128('b00d')
256    MITM_SHORT_CHAR_UUID = uuid16_to_uuid128('b00e')
257
258    LONG_TEST_VALUE_512 = [bytes([7])] * 512
259    LONG_TEST_VALUE = [bytes([7])] * 48
260    SHORT_TEST_VALUE = [bytes([7])] * 2
261    NOTIFICATION_VALUE = [bytes([1]), bytes([0])]
262    INDICATION_VALUE = [bytes([2]), bytes([0])]
263
264    class ExportedGattServerCallbacks(observer_base.ObserverBase):
265        """
266        <node>
267            <interface name="org.chromium.bluetooth.BluetoothGattServerCallback">
268                <method name="OnServerRegistered">
269                    <arg type="u" name="status" direction="in" />
270                    <arg type="i" name="server_id" direction="in" />
271                </method>
272                <method name="OnServerConnectionState">
273                    <arg type="i" name="server_id" direction="in" />
274                    <arg type="b" name="connected" direction="in" />
275                    <arg type="s" name="addr" direction="in" />
276                </method>
277                <method name="OnServiceAdded">
278                    <arg type="u" name="status" direction="in" />
279                    <arg type="a{sv}" name="service" direction="in" />
280                </method>
281                <method name="OnServiceRemoved">
282                    <arg type="u" name="status" direction="in" />
283                    <arg type="i" name="handle" direction="in" />
284                </method>
285                <method name="OnCharacteristicReadRequest">
286                    <arg type="s" name="addr" direction="in" />
287                    <arg type="i" name="trans_id" direction="in" />
288                    <arg type="i" name="offset" direction="in" />
289                    <arg type="b" name="is_long" direction="in" />
290                    <arg type="i" name="handle" direction="in" />
291                </method>
292                <method name="OnDescriptorReadRequest">
293                    <arg type="s" name="addr" direction="in" />
294                    <arg type="i" name="trans_id" direction="in" />
295                    <arg type="i" name="offset" direction="in" />
296                    <arg type="b" name="is_long" direction="in" />
297                    <arg type="i" name="handle" direction="in" />
298                </method>
299                <method name="OnCharacteristicWriteRequest">
300                    <arg type="s" name="addr" direction="in" />
301                    <arg type="i" name="trans_id" direction="in" />
302                    <arg type="i" name="offset" direction="in" />
303                    <arg type="i" name="length" direction="in" />
304                    <arg type="b" name="is_prep" direction="in" />
305                    <arg type="b" name="need_rsp" direction="in" />
306                    <arg type="i" name="handle" direction="in" />
307                    <arg type="ay" name="value" direction="in" />
308                </method>
309                <method name="OnDescriptorWriteRequest">
310                    <arg type="s" name="addr" direction="in" />
311                    <arg type="i" name="trans_id" direction="in" />
312                    <arg type="i" name="offset" direction="in" />
313                    <arg type="i" name="length" direction="in" />
314                    <arg type="b" name="is_prep" direction="in" />
315                    <arg type="b" name="need_rsp" direction="in" />
316                    <arg type="i" name="handle" direction="in" />
317                    <arg type="ay" name="value" direction="in" />
318                </method>
319                <method name="OnExecuteWrite">
320                    <arg type="s" name="addr" direction="in" />
321                    <arg type="i" name="trans_id" direction="in" />
322                    <arg type="b" name="exec_write" direction="in" />
323                </method>
324                <method name="OnNotificationSent">
325                    <arg type="s" name="addr" direction="in" />
326                    <arg type="u" name="status" direction="in" />
327                </method>
328                <method name="OnMtuChanged">
329                    <arg type="s" name="addr" direction="in" />
330                    <arg type="i" name="mtu" direction="in" />
331                </method>
332                <method name="OnPhyUpdate">
333                    <arg type="s" name="addr" direction="in" />
334                    <arg type="u" name="tx_phy" direction="in" />
335                    <arg type="u" name="rx_phy" direction="in" />
336                    <arg type="u" name="status" direction="in" />
337                </method>
338                <method name="OnPhyRead">
339                    <arg type="s" name="addr" direction="in" />
340                    <arg type="u" name="tx_phy" direction="in" />
341                    <arg type="u" name="rx_phy" direction="in" />
342                    <arg type="u" name="status" direction="in" />
343                </method>
344                <method name="OnConnectionUpdated">
345                    <arg type="s" name="addr" direction="in" />
346                    <arg type="i" name="interval" direction="in" />
347                    <arg type="i" name="latency" direction="in" />
348                    <arg type="i" name="timeout" direction="in" />
349                    <arg type="u" name="status" direction="in" />
350                </method>
351                <method name="OnSubrateChange">
352                    <arg type="s" name="addr" direction="in" />
353                    <arg type="i" name="subrate_factor" direction="in" />
354                    <arg type="i" name="latency" direction="in" />
355                    <arg type="i" name="cont_num" direction="in" />
356                    <arg type="i" name="timeout" direction="in" />
357                    <arg type="u" name="status" direction="in" />
358                </method>
359            </interface>
360        </node>
361        """
362
363        def __init__(self):
364            """Constructs exported callbacks object."""
365            observer_base.ObserverBase.__init__(self)
366
367        def OnServerRegistered(self, status, server_id):
368            """Handles server registration callback.
369
370            Args:
371                status: floss_enums.GattStatus.
372                server_id: Bluetooth GATT server id.
373            """
374            for observer in self.observers.values():
375                observer.on_server_registered(status, server_id)
376
377        def OnServerConnectionState(self, server_id, connected, addr):
378            """Handles server connection state callback.
379
380            Args:
381                server_id: Bluetooth GATT server id.
382                connected: A boolean value that indicates whether the GATT server is connected.
383                addr: Remote device MAC address.
384            """
385            for observer in self.observers.values():
386                observer.on_server_connection_state(server_id, connected, addr)
387
388        def OnServiceAdded(self, status, service):
389            """Handles service added callback.
390
391            Args:
392                status: floss_enums.GattStatus.
393                service: BluetoothGattService.
394            """
395            for observer in self.observers.values():
396                observer.on_service_added(status, service)
397
398        def OnServiceRemoved(self, status, handle):
399            """Handles service removed callback.
400
401            Args:
402                status: floss_enums.GattStatus.
403                handle: Service record handle.
404            """
405            for observer in self.observers.values():
406                observer.on_service_removed(status, handle)
407
408        def OnCharacteristicReadRequest(self, addr, trans_id, offset, is_long, handle):
409            """Handles characteristic read request callback.
410
411            Args:
412                addr: Remote device MAC address.
413                trans_id: Transaction id.
414                offset: Represents the offset from which the attribute value should be read.
415                is_long: A boolean value representing whether the characteristic size is longer than what we can put in
416                         the ATT PDU.
417                handle: The characteristic handle.
418            """
419            for observer in self.observers.values():
420                observer.on_characteristic_read_request(addr, trans_id, offset, is_long, handle)
421
422        def OnCharacteristicWriteRequest(self, addr, trans_id, offset, length, is_prep, need_rsp, handle, value):
423            """Handles characteristic write request callback.
424
425            Args:
426                addr: Remote device MAC address.
427                trans_id: Transaction id.
428                offset: Represents the offset from which the attribute value should be read.
429                length: The length of the value that should be written.
430                is_prep: A boolean value representing whether it's a 'prepare write' command.
431                need_rsp: A boolean value representing whether it's a 'write no response' command.
432                handle: The descriptor handle.
433                value: The value that should be written to the descriptor.
434            """
435            for observer in self.observers.values():
436                observer.on_characteristic_write_request(addr, trans_id, offset, length, is_prep, need_rsp, handle,
437                                                         value)
438
439        def OnDescriptorReadRequest(self, addr, trans_id, offset, is_long, handle):
440            """Handles descriptor read request callback.
441
442            Args:
443                addr: Remote device MAC address.
444                trans_id: Transaction id.
445                offset: Represents the offset from which the descriptor value should be read.
446                is_long: A boolean value representing whether the descriptor size is longer than what we can put in the
447                         ATT PDU.
448                handle: The descriptor handle.
449            """
450            for observer in self.observers.values():
451                observer.on_descriptor_read_request(addr, trans_id, offset, is_long, handle)
452
453        def OnDescriptorWriteRequest(self, addr, trans_id, offset, length, is_prep, need_rsp, handle, value):
454            """Handles descriptor write request callback.
455
456            Args:
457                addr: Remote device MAC address.
458                trans_id: Transaction id.
459                offset: The offset value at which the value should be written.
460                length: The length of the value that should be written.
461                is_prep: A boolean value representing whether it's a 'prepare write' command.
462                need_rsp: A boolean value representing whether it's a 'write no response' command.
463                handle: The descriptor handle.
464                value: The value that should be written to the descriptor.
465            """
466            for observer in self.observers.values():
467                observer.on_descriptor_write_request(addr, trans_id, offset, length, is_prep, need_rsp, handle, value)
468
469        def OnExecuteWrite(self, addr, trans_id, exec_write):
470            """Handles execute write callback.
471
472            Args:
473                addr: Remote device MAC address.
474                trans_id: Transaction id.
475                exec_write: A boolean value that indicates whether the write operation should be executed or canceled.
476            """
477            for observer in self.observers.values():
478                observer.on_execute_write(addr, trans_id, exec_write)
479
480        def OnNotificationSent(self, addr, status):
481            """Handles notification sent callback.
482
483            Args:
484                addr: Remote device MAC address.
485                status: floss_enums.GattStatus.
486            """
487            for observer in self.observers.values():
488                observer.on_notification_sent(addr, status)
489
490        def OnMtuChanged(self, addr, mtu):
491            """Handles MTU changed callback.
492
493            Args:
494                addr: Remote device MAC address.
495                mtu: Maximum transmission unit.
496            """
497            for observer in self.observers.values():
498                observer.on_mtu_changed(addr, mtu)
499
500        def OnPhyUpdate(self, addr, tx_phy, rx_phy, status):
501            """Handles physical update callback.
502
503            Args:
504                addr: Remote device MAC address.
505                tx_phy: The new TX PHY for the connection.
506                rx_phy: The new RX PHY for the connection.
507                status: floss_enums.GattStatus.
508            """
509            for observer in self.observers.values():
510                observer.on_phy_update(addr, tx_phy, rx_phy, status)
511
512        def OnPhyRead(self, addr, tx_phy, rx_phy, status):
513            """Handles physical read callback.
514
515            Args:
516                addr: Remote device MAC address.
517                tx_phy: The current transmit PHY for the connection.
518                rx_phy: The current receive PHY for the connection.
519                status: floss_enums.GattStatus.
520            """
521            for observer in self.observers.values():
522                observer.on_phy_read(addr, tx_phy, rx_phy, status)
523
524        def OnConnectionUpdated(self, addr, interval, latency, timeout, status):
525            """Handles connection updated callback.
526
527            Args:
528                addr: Remote device MAC address.
529                interval: Connection interval value.
530                latency: The number of consecutive connection events during which the device doesn't have to be
531                         listening.
532                timeout: Supervision timeout for this connection in milliseconds.
533                status: floss_enums.GattStatus.
534            """
535            for observer in self.observers.values():
536                observer.on_connection_updated(addr, interval, latency, timeout, status)
537
538        def on_subrate_change(self, addr, subrate_factor, latency, cont_num, timeout, status):
539            """Handles subrate changed callback.
540
541            Args:
542                addr: Remote device MAC address.
543                subrate_factor: Subrate factor value.
544                latency: The number of consecutive connection events during which the device doesn't have to be
545                         listening.
546                cont_num: Continuation number.
547                timeout: Supervision timeout for this connection in milliseconds.
548                status: floss_enums.GattStatus.
549            """
550            for observer in self.observers.values():
551                observer.on_subrate_change(addr, subrate_factor, latency, cont_num, timeout, status)
552
553    def __init__(self, bus, hci):
554        """Constructs the client.
555
556        Args:
557            bus: D-Bus bus over which we'll establish connections.
558            hci: HCI adapter index. Get this value from 'get_default_adapter' on FlossManagerClient.
559        """
560        self.bus = bus
561        self.hci = hci
562        self.objpath = self.GATT_OBJECT_PATTERN.format(hci)
563        self.cb_dbus_objpath = utils.generate_dbus_cb_objpath(self.GATT_CB_OBJ_NAME, self.hci)
564
565        # Create and publish callbacks.
566        self.callbacks = self.ExportedGattServerCallbacks()
567        self.callbacks.add_observer('gatt_testing_server', self)
568        self.bus.register_object(self.cb_dbus_objpath, self.callbacks, None)
569        self.server_id = None
570        self.mtu_value = -1
571        self.write_requests = collections.deque([])
572        self.gatt_services = []
573        # Indicate if PTS attribute values were set or not (set only one time).
574        self.pts_set_values = False
575
576    def __del__(self):
577        """Destructor."""
578        del self.callbacks
579
580    def check_permissions(self, uuid):
581        """Checks request UUID permission.
582
583        Args:
584            uuid: 128-bit UUID value as string.
585
586        Returns:
587            GATT status.
588        """
589        if uuid is None:
590            logging.debug('check_permissions uuid is None or value is None')
591            return floss_enums.GattStatus.NOT_FOUND
592        elif uuid == self.LONG_CHAR_UUID:
593            logging.debug('check_permissions: uuid == long_char, return GATT_SUCCESS')
594        elif uuid == self.DESCRIPTOR_UUID:
595            logging.debug('check_permissions: uuid == descriptor, return GATT_SUCCESS')
596        elif uuid == self.UNAUTHORIZED_CHAR_UUID:
597            logging.debug('check_permissions: uuid == unauthorize_char, return GATT_INSUF_AUTHORIZATION')
598            return floss_enums.GattStatus.INSUF_AUTHORIZATION
599        elif uuid == self.AUTHENTICATION_CHAR_UUID:
600            logging.debug('check_permissions: uuid == authenticate_char, return GATT_SUCCESS')
601        elif uuid == self.INVALID_FOR_LE_UUID:
602            logging.debug('check_permissions: uuid == invalid_for_le, return GATT_SUCCESS')
603            return floss_enums.GattStatus.INTERNAL_ERROR
604        elif uuid == self.INVALID_FOR_BR_EDR_UUID:
605            logging.debug('check_permissions: uuid == invalid_for_bredr, return GATT_SUCCESS')
606            return floss_enums.GattStatus.INTERNAL_ERROR
607        elif uuid == self.NO_READ_CHAR_UUID:
608            logging.debug('check_permissions: uuid == no_read_char, return GATT_READ_NOT_PERMIT')
609            return floss_enums.GattStatus.READ_NOT_PERMIT
610        elif uuid == self.NO_WRITE_CHAR_UUID:
611            logging.debug('check_permissions: uuid == no_write_char, return GATT_WRITE_NOT_PERMIT')
612            return floss_enums.GattStatus.WRITE_NOT_PERMIT
613        elif uuid == self.SHORT_CHAR_UUID:
614            logging.debug('check_permissions: uuid == short_char, return GATT_SUCCESS')
615        elif uuid == self.WRITE_NO_RESPONSE_CHAR_UUID:
616            logging.debug('check_permissions: uuid == write_no_rsp_char, return GATT_SUCCESS')
617        elif uuid == self.AUTHENTICATE_SHORT_CHAR_UUID:
618            logging.debug('check_permissions: uuid == authenticate_short_char, return GATT_SUCCESS')
619        elif uuid == self.CCC_DESCRIPTOR_UUID:
620            logging.debug('check_permissions: uuid == ccc_descriptor, return GATT_SUCCESS')
621        elif uuid == self.LONG_CHAR_512_UUID:
622            logging.debug('check_permissions: uuid == long_char512, return GATT_SUCCESS')
623        elif uuid == self.MITM_SHORT_CHAR_UUID:
624            logging.debug('check_permissions: uuid == mitm_short_char, return GATT_SUCCESS')
625        else:
626            logging.debug('check_permissions: uuid: %s unknown return GATT_NOT_FOUND', uuid)
627            return floss_enums.GattStatus.NOT_FOUND
628        return floss_enums.GattStatus.SUCCESS
629
630    def generic_write(self, offset, length, handle, value):
631        """Writes GATT attribute value.
632
633        Args:
634            offset: Represents the offset at which the attribute value should be written.
635            length: The length of the attribute value that should be written.
636            handle: The attribute handle.
637            value: The value that should be written to the attribute.
638
639        Returns:
640            (Bluetooth Gatt status, attribute value).
641        """
642        attribute = self.get_attribute_from_handle(handle)
643        attr_value = attribute.value if attribute is not None else []
644
645        if len(attr_value) < offset:
646            logging.info('len(char_value) < offset')
647            return floss_enums.GattStatus.INVALID_OFFSET, []
648
649        if offset + length > len(attr_value):
650            logging.info('offset + len > len(char_value)')
651            return floss_enums.GattStatus.INVALID_ATTRLEN, []
652
653        attr_value[offset:(offset + length)] = value
654        self.update_attribute_value(attribute.uuid, attr_value)
655        return floss_enums.GattStatus.SUCCESS, attr_value
656
657    def generic_read(self, offset, handle):
658        """Reads GATT attribute value.
659
660        Args:
661            offset: Represents the offset from which the attribute value should be read.
662            handle: The attribute handle.
663
664        Returns:
665            (Bluetooth Gatt status, attribute value).
666        """
667        attr_value = self.get_attribute_value_from_handle(handle)
668
669        if offset < 0 or offset > len(attr_value):
670            logging.info('generic_read len(value) < offset')
671            return floss_enums.GattStatus.INVALID_OFFSET, []
672
673        return floss_enums.GattStatus.SUCCESS, attr_value[offset:]
674
675    def get_uuid_from_handle(self, handle):
676        """Gets attribute UUID from handle.
677
678        Args:
679            handle: The attribute handle.
680
681        Returns:
682            Attribute UUID as string if found, empty string otherwise.
683        """
684        attribute = self.get_attribute_from_handle(handle)
685        return '' if attribute is None else attribute.uuid
686
687    def get_attribute_value_from_handle(self, handle):
688        """Gets attribute value from handle.
689
690        Args:
691            handle: The attribute handle.
692
693        Returns:
694            Attribute value as list if found, empty list otherwise.
695        """
696        attribute = self.get_attribute_from_handle(handle)
697        return [] if attribute is None else attribute.value
698
699    def get_attribute_from_handle(self, handle):
700        """Gets GATT attribute from handle.
701
702        Args:
703            handle: The attribute handle.
704
705        Returns:
706            GATT attribute if found, None otherwise.
707        """
708        for service in self.gatt_services:
709            if int(service.instance_id) == int(handle):
710                return service
711            for char in service.characteristics:
712                if int(char.instance_id) == int(handle):
713                    return char
714                for desc in char.descriptors:
715                    if int(desc.instance_id) == int(handle):
716                        return desc
717
718        return None
719
720    def update_attribute_value(self, uuid, value):
721        """Update GATT attribute value.
722
723        Args:
724            uuid: GATT attribute uuid as string.
725            value: Attribute value as list.
726        """
727        for service in self.gatt_services:
728            if service.uuid == uuid:
729                service.value = value
730                return
731            for char in service.characteristics:
732                if char.uuid == uuid:
733                    char.value = value
734                    return
735                for desc in char.descriptors:
736                    if desc.uuid == uuid:
737                        desc.value = value
738                        return
739        logging.error('No attribute found with uuid = %s!', uuid)
740
741    def on_attr_read(self, addr, trans_id, offset, is_long, handle):
742        """Handles the read request for GATT attribute.
743
744        Args:
745            addr: Remote device MAC address.
746            trans_id: Transaction id.
747            offset: Represents the offset from which the attribute value should be read.
748            is_long: A boolean value representing whether the attribute size is longer than what we can put in the ATT
749                     PDU.
750            handle: The attribute handle.
751        """
752        uuid = self.get_uuid_from_handle(handle)
753        status = self.check_permissions(uuid)
754        value = []
755        if status == floss_enums.GattStatus.SUCCESS:
756            if not is_long:
757                offset = 0
758            status, value = self.generic_read(offset, handle)
759
760        self.proxy().SendResponse(self.server_id, addr, trans_id, status, offset, value)
761
762    def on_attr_write(self, addr, trans_id, offset, length, is_prep, need_rsp, handle, value):
763        """Handles the read request for GATT attribute.
764
765        Args:
766            addr: Remote device MAC address.
767            trans_id: Transaction id.
768            offset: Represents the offset at which the attribute value should be written.
769            length: The length of the attribute value that should be written.
770            is_prep: A boolean value representing whether it's a 'prepare write' command.
771            need_rsp: A boolean value representing whether it's a 'write no response' command.
772            handle: The attribute handle.
773            value: The value that should be written to the attribute.
774        """
775        uuid = self.get_uuid_from_handle(handle)
776        status = self.check_permissions(uuid)
777
778        if status == floss_enums.GattStatus.SUCCESS:
779            if is_prep:
780                self.write_requests.append((addr, trans_id, offset, length, is_prep, need_rsp, handle, value))
781            else:
782                # write request.
783                status, value = self.generic_write(offset, length, handle, value)
784        else:
785            value = []
786
787        if need_rsp:
788            self.proxy().SendResponse(self.server_id, addr, trans_id, status, offset, value)
789        else:
790            logging.info('No need to send response.')
791
792    def __set_pts_attributes_value(self):
793        """Sets PTS attributes value."""
794        if not self.pts_set_values:
795            self.update_attribute_value(self.SERVICE_ATTR_UUID, self.SHORT_TEST_VALUE)
796            self.update_attribute_value(self.SERVER_CHANGED_CHAR_UUID, self.SHORT_TEST_VALUE)
797            self.update_attribute_value(self.SERVER_SUP_FEAT_UUID, self.SHORT_TEST_VALUE)
798            self.update_attribute_value(self.CLIENT_SUP_FEAT_UUID, self.SHORT_TEST_VALUE)
799            self.update_attribute_value(self.DATABASE_HASH_UUID, self.SHORT_TEST_VALUE)
800            self.update_attribute_value(self.LONG_CHAR_UUID, self.LONG_TEST_VALUE)
801            self.update_attribute_value(self.DESCRIPTOR_UUID, self.LONG_TEST_VALUE)
802            self.update_attribute_value(self.KEY_SIZE_CHAR_UUID, self.LONG_TEST_VALUE)
803            self.update_attribute_value(self.UNAUTHORIZED_CHAR_UUID, self.LONG_TEST_VALUE)
804            self.update_attribute_value(self.AUTHENTICATION_CHAR_UUID, self.LONG_TEST_VALUE)
805            self.update_attribute_value(self.INVALID_FOR_LE_UUID, self.LONG_TEST_VALUE)
806            self.update_attribute_value(self.INVALID_FOR_BR_EDR_UUID, self.LONG_TEST_VALUE)
807            self.update_attribute_value(self.NO_READ_CHAR_UUID, self.LONG_TEST_VALUE)
808            self.update_attribute_value(self.NO_WRITE_CHAR_UUID, self.LONG_TEST_VALUE)
809            self.update_attribute_value(self.SHORT_CHAR_UUID, self.SHORT_TEST_VALUE)
810            self.update_attribute_value(self.WRITE_NO_RESPONSE_CHAR_UUID, self.LONG_TEST_VALUE)
811            self.update_attribute_value(self.NOTIFY_CHAR_UUID, self.SHORT_TEST_VALUE)
812            self.update_attribute_value(self.AUTHENTICATE_SHORT_CHAR_UUID, self.SHORT_TEST_VALUE)
813            self.update_attribute_value(self.CCC_DESCRIPTOR_UUID, self.INDICATION_VALUE)
814            self.update_attribute_value(self.LONG_CHAR_512_UUID, self.LONG_TEST_VALUE_512)
815            self.update_attribute_value(self.MITM_SHORT_CHAR_UUID, self.SHORT_TEST_VALUE)
816            self.pts_set_values = True
817
818    def __define_services(self):
819        """Defines GATT services for PTS testing."""
820
821        service = bluetooth_gatt_service.Service()
822        characteristic = bluetooth_gatt_service.Characteristic()
823        descriptor = bluetooth_gatt_service.Descriptor()
824        service.included_services = []
825        service.characteristics = []
826        characteristic.descriptors = []
827
828        service.uuid = self.SERVICE_ATTR_UUID
829        service.instance_id = 0
830        service.service_type = self.BTGATT_DB_PRIMARY_SERVICE
831
832        characteristic.uuid = self.SERVER_CHANGED_CHAR_UUID
833        characteristic.instance_id = 1
834        characteristic.properties = floss_enums.GattCharacteristicProprieties.CHAR_PROP_BIT_INDICATE
835        characteristic.permissions = floss_enums.GattPermission.PERM_READ | floss_enums.GattPermission.PERM_WRITE
836        characteristic.key_size = 0
837        characteristic.write_type = floss_enums.GattWriteType.WRITE
838
839        descriptor.uuid = self.CCC_DESCRIPTOR_UUID
840        descriptor.instance_id = 2
841        descriptor.permissions = floss_enums.GattPermission.PERM_READ | floss_enums.GattPermission.PERM_WRITE
842        characteristic.descriptors.append(descriptor)
843
844        service.characteristics.append(characteristic)
845
846        # ----------------------------------------------------
847        characteristic = bluetooth_gatt_service.Characteristic()
848        characteristic.uuid = self.SERVER_SUP_FEAT_UUID
849        characteristic.instance_id = 3
850        characteristic.properties = floss_enums.GattCharacteristicProprieties.CHAR_PROP_BIT_READ
851        characteristic.permissions = floss_enums.GattPermission.PERM_READ
852        characteristic.key_size = 0
853        characteristic.write_type = floss_enums.GattWriteType.INVALID
854        characteristic.descriptors = []
855
856        service.characteristics.append(characteristic)
857
858        # ----------------------------------------------------
859        characteristic = bluetooth_gatt_service.Characteristic()
860        characteristic.uuid = self.CLIENT_SUP_FEAT_UUID
861        characteristic.instance_id = 4
862        characteristic.properties = (floss_enums.GattCharacteristicProprieties.CHAR_PROP_BIT_READ |
863                                     floss_enums.GattCharacteristicProprieties.CHAR_PROP_BIT_WRITE)
864        characteristic.permissions = floss_enums.GattPermission.PERM_READ | floss_enums.GattPermission.PERM_WRITE
865        characteristic.key_size = 0
866        characteristic.write_type = floss_enums.GattWriteType.INVALID
867        characteristic.descriptors = []
868
869        service.characteristics.append(characteristic)
870
871        # ----------------------------------------------------
872        characteristic = bluetooth_gatt_service.Characteristic()
873        characteristic.uuid = self.DATABASE_HASH_UUID
874        characteristic.instance_id = 5
875        characteristic.properties = floss_enums.GattCharacteristicProprieties.CHAR_PROP_BIT_READ
876        characteristic.permissions = floss_enums.GattPermission.PERM_READ
877        characteristic.key_size = 0
878        characteristic.write_type = floss_enums.GattWriteType.INVALID
879        characteristic.descriptors = []
880
881        service.characteristics.append(characteristic)
882
883        # ----------------------------------------------------
884        characteristic = bluetooth_gatt_service.Characteristic()
885        characteristic.uuid = self.DATABASE_HASH_UUID
886        characteristic.instance_id = 5
887        characteristic.properties = floss_enums.GattCharacteristicProprieties.CHAR_PROP_BIT_READ
888        characteristic.permissions = floss_enums.GattPermission.PERM_READ
889        characteristic.key_size = 0
890        characteristic.write_type = floss_enums.GattWriteType.INVALID
891        characteristic.descriptors = []
892
893        service.characteristics.append(characteristic)
894
895        # ----------------------------------------------------
896        characteristic = bluetooth_gatt_service.Characteristic()
897        descriptor = bluetooth_gatt_service.Descriptor()
898        characteristic.uuid = self.LONG_CHAR_UUID
899        characteristic.instance_id = 6
900        characteristic.properties = (floss_enums.GattCharacteristicProprieties.CHAR_PROP_BIT_READ |
901                                     floss_enums.GattCharacteristicProprieties.CHAR_PROP_BIT_WRITE)
902        characteristic.permissions = floss_enums.GattPermission.PERM_READ | floss_enums.GattPermission.PERM_WRITE
903        characteristic.key_size = 0
904        characteristic.write_type = floss_enums.GattWriteType.WRITE
905        characteristic.descriptors = []
906
907        descriptor.uuid = self.DESCRIPTOR_UUID
908        descriptor.instance_id = 7
909        descriptor.permissions = floss_enums.GattPermission.PERM_READ | floss_enums.GattPermission.PERM_WRITE
910        characteristic.descriptors.append(descriptor)
911        service.characteristics.append(characteristic)
912
913        # ----------------------------------------------------
914        characteristic = bluetooth_gatt_service.Characteristic()
915        characteristic.uuid = self.KEY_SIZE_CHAR_UUID
916        characteristic.instance_id = 8
917        characteristic.properties = (floss_enums.GattCharacteristicProprieties.CHAR_PROP_BIT_READ |
918                                     floss_enums.GattCharacteristicProprieties.CHAR_PROP_BIT_WRITE)
919        characteristic.permissions = (
920            10 << 12) | floss_enums.GattPermission.PERM_READ_ENCRYPTED | floss_enums.GattPermission.PERM_WRITE_ENCRYPTED
921        characteristic.key_size = 10
922        characteristic.write_type = floss_enums.GattWriteType.WRITE
923        characteristic.descriptors = []
924
925        service.characteristics.append(characteristic)
926        # ----------------------------------------------------
927        characteristic = bluetooth_gatt_service.Characteristic()
928        characteristic.uuid = self.UNAUTHORIZED_CHAR_UUID
929        characteristic.instance_id = 9
930        characteristic.properties = (floss_enums.GattCharacteristicProprieties.CHAR_PROP_BIT_READ |
931                                     floss_enums.GattCharacteristicProprieties.CHAR_PROP_BIT_WRITE)
932        characteristic.permissions = floss_enums.GattPermission.PERM_READ | floss_enums.GattPermission.PERM_WRITE
933        characteristic.key_size = 0
934        characteristic.write_type = floss_enums.GattWriteType.WRITE
935        characteristic.descriptors = []
936
937        service.characteristics.append(characteristic)
938        # ----------------------------------------------------
939        characteristic = bluetooth_gatt_service.Characteristic()
940        characteristic.uuid = self.AUTHENTICATION_CHAR_UUID
941        characteristic.instance_id = 10
942        characteristic.properties = (floss_enums.GattCharacteristicProprieties.CHAR_PROP_BIT_READ |
943                                     floss_enums.GattCharacteristicProprieties.CHAR_PROP_BIT_WRITE |
944                                     floss_enums.GattCharacteristicProprieties.CHAR_PROP_BIT_AUTH)
945        characteristic.permissions = self.GATT_READ_AUTH_REQUIRED | self.GATT_WRITE_AUTH_REQUIRED
946        characteristic.key_size = 0
947        characteristic.write_type = floss_enums.GattWriteType.WRITE
948        characteristic.descriptors = []
949
950        service.characteristics.append(characteristic)
951
952        # ----------------------------------------------------
953        characteristic = bluetooth_gatt_service.Characteristic()
954        characteristic.uuid = self.INVALID_FOR_LE_UUID
955        characteristic.instance_id = 11
956        characteristic.properties = (floss_enums.GattCharacteristicProprieties.CHAR_PROP_BIT_READ |
957                                     floss_enums.GattCharacteristicProprieties.CHAR_PROP_BIT_WRITE)
958        characteristic.permissions = floss_enums.GattPermission.PERM_READ | floss_enums.GattPermission.PERM_WRITE
959        characteristic.key_size = 0
960        characteristic.write_type = floss_enums.GattWriteType.WRITE
961        characteristic.descriptors = []
962
963        service.characteristics.append(characteristic)
964        # ----------------------------------------------------
965        characteristic = bluetooth_gatt_service.Characteristic()
966        characteristic.uuid = self.INVALID_FOR_BR_EDR_UUID
967        characteristic.instance_id = 12
968        characteristic.properties = (floss_enums.GattCharacteristicProprieties.CHAR_PROP_BIT_READ |
969                                     floss_enums.GattCharacteristicProprieties.CHAR_PROP_BIT_WRITE)
970        characteristic.permissions = floss_enums.GattPermission.PERM_READ | floss_enums.GattPermission.PERM_WRITE
971        characteristic.key_size = 0
972        characteristic.write_type = floss_enums.GattWriteType.WRITE
973        characteristic.descriptors = []
974
975        service.characteristics.append(characteristic)
976        # ----------------------------------------------------
977        characteristic = bluetooth_gatt_service.Characteristic()
978        characteristic.uuid = self.NO_READ_CHAR_UUID
979        characteristic.instance_id = 13
980        # Only write property.
981        characteristic.properties = floss_enums.GattCharacteristicProprieties.CHAR_PROP_BIT_WRITE
982        # Only write permission.
983        characteristic.permissions = floss_enums.GattPermission.PERM_WRITE
984        characteristic.key_size = 0
985        characteristic.write_type = floss_enums.GattWriteType.WRITE
986        characteristic.descriptors = []
987
988        service.characteristics.append(characteristic)
989        # ----------------------------------------------------
990        characteristic = bluetooth_gatt_service.Characteristic()
991        characteristic.uuid = self.NO_WRITE_CHAR_UUID
992        characteristic.instance_id = 14
993        # Only read property.
994        characteristic.properties = floss_enums.GattCharacteristicProprieties.CHAR_PROP_BIT_READ
995        # Only read permission.
996        characteristic.permissions = floss_enums.GattPermission.PERM_READ
997        characteristic.key_size = 0
998        characteristic.write_type = floss_enums.GattWriteType.INVALID
999        characteristic.descriptors = []
1000
1001        service.characteristics.append(characteristic)
1002        # ----------------------------------------------------
1003        characteristic = bluetooth_gatt_service.Characteristic()
1004        characteristic.uuid = self.SHORT_CHAR_UUID
1005        characteristic.instance_id = 15
1006        characteristic.properties = (floss_enums.GattCharacteristicProprieties.CHAR_PROP_BIT_READ |
1007                                     floss_enums.GattCharacteristicProprieties.CHAR_PROP_BIT_WRITE)
1008        characteristic.permissions = floss_enums.GattPermission.PERM_READ | floss_enums.GattPermission.PERM_WRITE
1009        characteristic.key_size = 0
1010        characteristic.write_type = floss_enums.GattWriteType.WRITE
1011        characteristic.descriptors = []
1012
1013        service.characteristics.append(characteristic)
1014        # ----------------------------------------------------
1015        characteristic = bluetooth_gatt_service.Characteristic()
1016        characteristic.uuid = self.WRITE_NO_RESPONSE_CHAR_UUID
1017        characteristic.instance_id = 16
1018        # Write without response property.
1019        characteristic.properties = (floss_enums.GattCharacteristicProprieties.CHAR_PROP_BIT_READ |
1020                                     floss_enums.GattCharacteristicProprieties.CHAR_PROP_BIT_WRITE_NR)
1021        characteristic.permissions = floss_enums.GattPermission.PERM_READ | floss_enums.GattPermission.PERM_WRITE
1022        characteristic.key_size = 0
1023        characteristic.write_type = floss_enums.GattWriteType.WRITE_NO_RSP
1024        characteristic.descriptors = []
1025
1026        service.characteristics.append(characteristic)
1027        # ----------------------------------------------------
1028        characteristic = bluetooth_gatt_service.Characteristic()
1029        descriptor = bluetooth_gatt_service.Descriptor()
1030        characteristic.uuid = self.NOTIFY_CHAR_UUID
1031        characteristic.instance_id = 17
1032        characteristic.properties = (floss_enums.GattCharacteristicProprieties.CHAR_PROP_BIT_NOTIFY |
1033                                     floss_enums.GattCharacteristicProprieties.CHAR_PROP_BIT_INDICATE)
1034        characteristic.permissions = floss_enums.GattPermission.PERM_READ | floss_enums.GattPermission.PERM_WRITE
1035        characteristic.key_size = 0
1036        characteristic.write_type = floss_enums.GattWriteType.WRITE
1037        characteristic.descriptors = []
1038
1039        descriptor.uuid = self.CCC_DESCRIPTOR_UUID
1040        descriptor.instance_id = 18
1041        descriptor.permissions = floss_enums.GattPermission.PERM_READ | floss_enums.GattPermission.PERM_WRITE
1042
1043        characteristic.descriptors.append(descriptor)
1044        service.characteristics.append(characteristic)
1045        # ----------------------------------------------------
1046        characteristic = bluetooth_gatt_service.Characteristic()
1047        characteristic.uuid = self.AUTHENTICATE_SHORT_CHAR_UUID
1048        characteristic.instance_id = 19
1049        characteristic.properties = (floss_enums.GattCharacteristicProprieties.CHAR_PROP_BIT_READ |
1050                                     floss_enums.GattCharacteristicProprieties.CHAR_PROP_BIT_WRITE |
1051                                     floss_enums.GattCharacteristicProprieties.CHAR_PROP_BIT_AUTH)
1052        characteristic.permissions = self.GATT_READ_AUTH_REQUIRED | self.GATT_WRITE_AUTH_REQUIRED
1053        characteristic.key_size = 0
1054        characteristic.write_type = floss_enums.GattWriteType.WRITE
1055        characteristic.descriptors = []
1056
1057        service.characteristics.append(characteristic)
1058        # ----------------------------------------------------
1059        characteristic = bluetooth_gatt_service.Characteristic()
1060        characteristic.uuid = self.LONG_CHAR_512_UUID
1061        characteristic.instance_id = 20
1062        characteristic.properties = (floss_enums.GattCharacteristicProprieties.CHAR_PROP_BIT_READ |
1063                                     floss_enums.GattCharacteristicProprieties.CHAR_PROP_BIT_WRITE)
1064        characteristic.permissions = floss_enums.GattPermission.PERM_READ | floss_enums.GattPermission.PERM_WRITE
1065        characteristic.key_size = 0
1066        characteristic.write_type = floss_enums.GattWriteType.WRITE
1067        characteristic.descriptors = []
1068
1069        service.characteristics.append(characteristic)
1070        # ----------------------------------------------------
1071        characteristic = bluetooth_gatt_service.Characteristic()
1072        characteristic.uuid = self.MITM_SHORT_CHAR_UUID
1073        characteristic.instance_id = 21
1074        characteristic.properties = (floss_enums.GattCharacteristicProprieties.CHAR_PROP_BIT_READ |
1075                                     floss_enums.GattCharacteristicProprieties.CHAR_PROP_BIT_WRITE |
1076                                     floss_enums.GattCharacteristicProprieties.CHAR_PROP_BIT_AUTH)
1077        characteristic.permissions = self.GATT_READ_MITM_REQUIRED | self.GATT_WRITE_MITM_REQUIRED
1078        characteristic.key_size = 0
1079        characteristic.write_type = floss_enums.GattWriteType.WRITE
1080        characteristic.descriptors = []
1081        service.characteristics.append(characteristic)
1082        # ----------------------------------------------------
1083        service_dict = bluetooth_gatt_service.convert_object_to_dict(service)
1084        self.proxy().AddService(self.server_id, self.make_dbus_service(service_dict))
1085
1086    @utils.glib_callback()
1087    def on_server_registered(self, status, server_id):
1088        """Handles server registration callback.
1089
1090        Args:
1091            status: floss_enums.GattStatus.
1092            server_id: Bluetooth GATT server id.
1093        """
1094        logging.debug('on_server_registered: status: %s, server_id: %s', status, server_id)
1095
1096        if status != floss_enums.GattStatus.SUCCESS:
1097            logging.error('Failed to register server with id: %s, status = %s', server_id, status)
1098            return
1099        self.server_id = server_id
1100        self.__define_services()
1101
1102    @utils.glib_callback()
1103    def on_server_connection_state(self, server_id, connected, addr):
1104        """Handles GATT server connection state callback.
1105
1106        Args:
1107            server_id: Bluetooth GATT server id.
1108            connected: A boolean value that indicates whether the GATT server is connected.
1109            addr: Remote device MAC address.
1110        """
1111        logging.debug('on_server_connection_state: server_id: %s, connection_state: %s, device address: %s', server_id,
1112                      connected, addr)
1113
1114    @utils.glib_callback()
1115    def on_service_added(self, status, service):
1116        """Handles service added callback.
1117
1118        Args:
1119            status: floss_enums.GattStatus.
1120            service: BluetoothGattService.
1121        """
1122        if status != floss_enums.GattStatus.SUCCESS:
1123            return
1124        self.gatt_services.append(bluetooth_gatt_service.create_gatt_service(service))
1125
1126        logging.debug('on_service_added: status: %s, service: %s', status, service)
1127
1128        # This function will run once when the server is initiated.
1129        self.__set_pts_attributes_value()
1130
1131    @utils.glib_callback()
1132    def on_service_removed(self, status, handle):
1133        """Handles service removed callback.
1134
1135        Args:
1136            status: floss_enums.GattStatus.
1137            handle: Service record handle.
1138        """
1139        logging.debug('on_service_removed: status: %s, handle: %s', status, handle)
1140
1141    @utils.glib_callback()
1142    def on_characteristic_read_request(self, addr, trans_id, offset, is_long, handle):
1143        """Handles the read request of the characteristic callback.
1144
1145        Args:
1146            addr: Remote device MAC address.
1147            trans_id: Transaction id.
1148            offset: Represents the offset from which the attribute value should be read.
1149            is_long: A boolean value representing whether the characteristic size is longer than what we can put in the
1150                     ATT PDU.
1151            handle: The characteristic handle.
1152        """
1153        logging.debug(
1154            'on_characteristic_read_request: device address: %s, trans_id: %s, offset: %s, is_long: %s, handle: %s',
1155            addr, trans_id, offset, is_long, handle)
1156
1157        self.on_attr_read(addr, trans_id, offset, is_long, handle)
1158
1159    @utils.glib_callback()
1160    def on_descriptor_read_request(self, addr, trans_id, offset, is_long, handle):
1161        """Handles the read request of the descriptor callback.
1162
1163        Args:
1164            addr: Remote device MAC address.
1165            trans_id: Transaction id.
1166            offset: Represents the offset from which the descriptor value should be read.
1167            is_long: A boolean value representing whether the descriptor size is longer than what we can put in the
1168                     ATT PDU.
1169            handle: The descriptor handle.
1170        """
1171        logging.debug(
1172            'on_descriptor_read_request: device address: %s, trans_id: %s, offset: %s, is_long: %s, handle: %s', addr,
1173            trans_id, offset, is_long, handle)
1174        self.on_attr_read(addr, trans_id, offset, is_long, handle)
1175
1176    @utils.glib_callback()
1177    def on_characteristic_write_request(self, addr, trans_id, offset, length, is_prep, need_rsp, handle, value):
1178        """Handles the write request of the characteristic callback.
1179
1180        Args:
1181            addr: Remote device MAC address.
1182            trans_id: Transaction id.
1183            offset: Represents the offset at which the attribute value should be written.
1184            length: The length of the attribute value that should be written.
1185            is_prep: A boolean value representing whether it's a 'prepare write' command.
1186            need_rsp: A boolean value representing whether it's a 'write no response' command.
1187            handle: The characteristic handle.
1188            value: The value that should be written to the attribute.
1189        """
1190        logging.debug(
1191            'on_characteristic_write_request: device address: %s, trans_id: %s, offset: %s, length: %s, is_prep: %s, '
1192            'need_rsp: %s, handle: %s, values: %s', addr, trans_id, offset, length, is_prep, need_rsp, handle, value)
1193        self.on_attr_write(addr, trans_id, offset, length, is_prep, need_rsp, handle, value)
1194
1195    @utils.glib_callback()
1196    def on_descriptor_write_request(self, addr, trans_id, offset, length, is_prep, need_rsp, handle, value):
1197        """Handles the write request of the descriptor callback.
1198
1199        Args:
1200            addr: Remote device MAC address.
1201            trans_id: Transaction id.
1202            offset: The offset value at which the value should be written.
1203            length: The length of the value that should be written.
1204            is_prep: A boolean value representing whether it's a 'prepare write' command.
1205            need_rsp: A boolean value representing whether it's a 'write no response' command.
1206            handle: The descriptor handle.
1207            value: The value that should be written to the descriptor.
1208        """
1209        logging.debug(
1210            'on_descriptor_write_request: device address: %s, trans_id: %s, offset: %s, length: %s, is_prep: %s, '
1211            'need_rsp: %s, handle: %s, values: %s', addr, trans_id, offset, length, is_prep, need_rsp, handle, value)
1212        self.on_attr_write(addr, trans_id, offset, length, is_prep, need_rsp, handle, value)
1213
1214    @utils.glib_callback()
1215    def on_execute_write(self, addr, trans_id, exec_write):
1216        """Handles execute write callback.
1217
1218        Args:
1219            addr: Remote device MAC address.
1220            trans_id: Transaction id.
1221            exec_write: A boolean value that indicates whether the write operation should be executed or canceled.
1222        """
1223        logging.debug('on_execute_write: device address: %s, trans_id: %s, exec_write: %s', addr, trans_id, exec_write)
1224
1225        if not exec_write:
1226            self.write_requests.clear()
1227            status = floss_enums.GattStatus.SUCCESS
1228        else:
1229            write_requests, self.write_requests = self.write_requests, collections.deque([])
1230            for request in write_requests:
1231                _, _, offset2, length, _, _, handle2, value2 = request
1232                status, _ = self.generic_write(offset2, length, handle2, value2)
1233                if status != floss_enums.GattStatus.SUCCESS:
1234                    break
1235
1236        self.proxy().SendResponse(self.server_id, addr, trans_id, status, 0, [])
1237
1238    @utils.glib_callback()
1239    def on_notification_sent(self, addr, status):
1240        """Handles notification sent callback.
1241
1242        Args:
1243            addr: Remote device MAC address.
1244            status: floss_enums.GattStatus.
1245        """
1246        logging.debug('on_notification_sent: device address: %s, status: %s', addr, status)
1247
1248    @utils.glib_callback()
1249    def on_mtu_changed(self, addr, mtu):
1250        """Handles MTU changed callback.
1251
1252        Args:
1253            addr: Remote device MAC address.
1254            mtu: Maximum transmission unit.
1255        """
1256        logging.debug('on_mtu_changed: device address: %s, mtu : %s', addr, mtu)
1257        self.mtu_value = mtu
1258
1259    @utils.glib_callback()
1260    def on_phy_update(self, addr, tx_phy, rx_phy, status):
1261        """Handles physical update callback.
1262
1263        Args:
1264            addr: Remote device MAC address.
1265            tx_phy: The new TX PHY for the connection.
1266            rx_phy: The new RX PHY for the connection.
1267            status: floss_enums.GattStatus.
1268        """
1269        logging.debug('on_phy_update: device address: %s, tx_phy: %s, rx_phy: %s, status: %s', addr, tx_phy, rx_phy,
1270                      status)
1271
1272    @utils.glib_callback()
1273    def on_phy_read(self, addr, tx_phy, rx_phy, status):
1274        """Handles physical read callback.
1275
1276        Args:
1277            addr: Remote device MAC address.
1278            tx_phy: The current transmit PHY for the connection.
1279            rx_phy: The current receive PHY for the connection.
1280            status: floss_enums.GattStatus.
1281        """
1282        logging.debug('on_phy_read: device address: %s, tx_phy: %s, rx_phy: %s, status: %s', addr, tx_phy, rx_phy,
1283                      status)
1284
1285    @utils.glib_callback()
1286    def on_connection_updated(self, addr, interval, latency, timeout, status):
1287        """Handles connection updated callback.
1288
1289        Args:
1290            addr: Remote device MAC address.
1291            interval: Connection interval value.
1292            latency: The number of consecutive connection events during which the device doesn't have to be listening.
1293            timeout: Supervision timeout for this connection in milliseconds.
1294            status: floss_enums.GattStatus.
1295        """
1296        logging.debug('on_connection_updated: device address: %s, interval: %s, latency: %s, timeout: %s, status: %s',
1297                      addr, interval, latency, timeout, status)
1298
1299    @utils.glib_callback()
1300    def on_subrate_change(self, addr, subrate_factor, latency, cont_num, timeout, status):
1301        """Handles subrate changed callback.
1302
1303        Args:
1304            addr: Remote device MAC address.
1305            subrate_factor: Subrate factor value.
1306            latency: The number of consecutive connection events during which the device doesn't have to be listening.
1307            cont_num: Continuation number.
1308            timeout: Supervision timeout for this connection in milliseconds.
1309            status: floss_enums.GattStatus.
1310        """
1311        logging.debug(
1312            'on_subrate_change: device address: %s, subrate_factor: %s, latency: %s, cont_num: %s, timeout: %s, '
1313            'status: %s', addr, subrate_factor, latency, cont_num, timeout, status)
1314
1315    @utils.glib_call(False)
1316    def has_proxy(self):
1317        """Checks whether GATT server proxy can be acquired."""
1318        return bool(self.proxy())
1319
1320    def proxy(self):
1321        """Gets proxy object to GATT server interface for method calls."""
1322        return self.bus.get(self.ADAPTER_SERVICE, self.objpath)[self.GATT_SERVER_INTERFACE]
1323
1324    @utils.glib_call(False)
1325    def register_server(self, app_uuid, eatt_support):
1326        """Registers GATT server with provided UUID.
1327
1328        Args:
1329            app_uuid: GATT application uuid.
1330            eatt_support: A boolean value that indicates whether EATT is supported.
1331
1332        Returns:
1333            True on success, False otherwise.
1334        """
1335        self.proxy().RegisterServer(app_uuid, self.cb_dbus_objpath, eatt_support)
1336        return True
1337
1338    @utils.glib_call(False)
1339    def unregister_server(self):
1340        """Unregisters GATT server for this client.
1341
1342        Returns:
1343            True on success, False otherwise.
1344        """
1345        self.proxy().UnregisterServer(self.server_id)
1346        return True
1347
1348    @utils.glib_call(None)
1349    def server_connect(self, addr, is_direct, transport):
1350        """Connects remote device to GATT server.
1351
1352        Args:
1353            addr: Remote device MAC address.
1354            is_direct: A boolean value that specifies whether the connection should be made using direct connection.
1355            transport: BtTransport type.
1356
1357        Returns:
1358            Server connect as boolean on success, None otherwise.
1359        """
1360        return self.proxy().ServerConnect(self.server_id, addr, is_direct, transport)
1361
1362    @utils.glib_call(None)
1363    def server_disconnect(self, addr):
1364        """Disconnects remote device from the GATT server.
1365
1366        Args:
1367            addr: Remote device MAC address.
1368
1369        Returns:
1370            Server disconnect as boolean on success, None otherwise.
1371        """
1372        return self.proxy().ServerDisconnect(self.server_id, addr)
1373
1374    @utils.glib_call(False)
1375    def add_service(self, service):
1376        """Adds GATT service.
1377
1378        Args:
1379            service: BluetoothGattService.
1380
1381        Returns:
1382            True on success, False otherwise.
1383        """
1384        self.proxy().AddService(self.server_id, service)
1385        return True
1386
1387    @utils.glib_call(False)
1388    def remove_service(self, handle):
1389        """Removes GATT service.
1390
1391        Args:
1392            handle: Service record handle.
1393
1394        Returns:
1395            True on success, False otherwise.
1396        """
1397        self.proxy().RemoveService(self.server_id, handle)
1398        return True
1399
1400    @utils.glib_call(False)
1401    def clear_services(self):
1402        """Clears GATT services.
1403
1404        Returns:
1405            True on success, False otherwise.
1406        """
1407        self.proxy().ClearServices(self.server_id)
1408        return True
1409
1410    @utils.glib_call(None)
1411    def send_response(self, addr, request_id, status, offset, value):
1412        """Sends GATT response.
1413
1414        Args:
1415            addr: Remote device MAC address.
1416            request_id: Request id.
1417            status: floss_enums.GattStatus.
1418            offset: The offset value to be sent in the response.
1419            value: The attribute value to be sent in the response.
1420
1421        Returns:
1422            Response send as boolean on success, None otherwise.
1423        """
1424        return self.proxy().SendResponse(self.server_id, addr, request_id, status, offset, value)
1425
1426    @utils.glib_call(None)
1427    def send_notification(self, addr, handle, confirm, value):
1428        """Sends GATT notification.
1429
1430        Args:
1431            addr: Remote device MAC address.
1432            handle: The attribute handle of the attribute to send the notification for.
1433            confirm: A boolean value indicating whether the client should send a confirmation in response to
1434                     the notification.
1435            value: The notification data to send.
1436
1437        Returns:
1438            Notification send as boolean on success, None otherwise.
1439        """
1440        return self.proxy().SendNotification(self.server_id, addr, handle, confirm, value)
1441
1442    @utils.glib_call(False)
1443    def server_set_preferred_phy(self, addr, tx_phy, rx_phy, phy_options):
1444        """Sets preferred phy for server.
1445
1446        Args:
1447            addr: Remote device MAC address.
1448            tx_phy: Preferred PHY for transmitting data.
1449            rx_phy: Preferred PHY for receiving data.
1450            phy_options: Preferred Phy options.
1451
1452        Returns:
1453            True on success, False otherwise.
1454        """
1455        self.proxy().ServerSetPreferredPhy(self.server_id, addr, tx_phy, rx_phy, phy_options)
1456        return True
1457
1458    @utils.glib_call(False)
1459    def server_read_phy(self, addr):
1460        """Reads phy of server.
1461
1462        Args:
1463            addr: Remote device MAC address.
1464
1465        Returns:
1466            True on success, False otherwise.
1467        """
1468        self.proxy().ServerReadPhy(self.server_id, addr)
1469        return True
1470
1471    def register_callback_observer(self, name, observer):
1472        """Add an observer for all callbacks.
1473
1474        Args:
1475            name: Name of the observer.
1476            observer: Observer that implements all callback classes.
1477        """
1478        if isinstance(observer, GattServerCallbacks):
1479            self.callbacks.add_observer(name, observer)
1480
1481    def unregister_callback_observer(self, name, observer):
1482        """Remove an observer for all callbacks.
1483
1484        Args:
1485            name: Name of the observer.
1486            observer: Observer that implements all callback classes.
1487        """
1488        if isinstance(observer, GattServerCallbacks):
1489            self.callbacks.remove_observer(name, observer)
1490
1491    def make_dbus_descriptor(self, uuid, instance_id, permissions):
1492        """Makes struct for descriptor D-Bus.
1493
1494        Args:
1495            uuid : Descriptor UUID as string.
1496            instance_id: Descriptor identifier.
1497            permissions: Descriptor permissions.
1498
1499        Returns:
1500            Dictionary of descriptor.
1501        """
1502        desc_uuid = utils.get_uuid_as_list(uuid)
1503        return {
1504            'uuid': GLib.Variant('ay', desc_uuid),
1505            'instance_id': GLib.Variant('i', instance_id),
1506            'permissions': GLib.Variant('i', permissions)
1507        }
1508
1509    def make_dbus_characteristic(self, uuid, instance_id, properties, permissions, key_size, write_type, descriptors):
1510        """Makes struct for characteristic D-Bus.
1511
1512        Args:
1513            uuid : Characteristic UUID as string.
1514            instance_id: Characteristic handle id.
1515            properties: Characteristic properties.
1516            permissions: Characteristic permissions.
1517            key_size: Characteristic key size.
1518            write_type: Characteristic write type.
1519            descriptors: Characteristic descriptors.
1520
1521        Returns:
1522            Dictionary of characteristic.
1523        """
1524        desc = []
1525        for d in descriptors:
1526            desc.append(self.make_dbus_descriptor(d['uuid'], d['instance_id'], d['permissions']))
1527        char_uuid = utils.get_uuid_as_list(uuid)
1528        return {
1529            'uuid': GLib.Variant('ay', char_uuid),
1530            'instance_id': GLib.Variant('i', instance_id),
1531            'properties': GLib.Variant('i', properties),
1532            'permissions': GLib.Variant('i', permissions),
1533            'key_size': GLib.Variant('i', key_size),
1534            'write_type': GLib.Variant('u', write_type),
1535            'descriptors': GLib.Variant('aa{sv}', desc)
1536        }
1537
1538    def make_dbus_service(self, service):
1539        """Makes struct for service D-Bus.
1540
1541        Args:
1542            service: The struct of BluetoothGattService.
1543
1544        Returns:
1545            Dictionary of service.
1546        """
1547        characteristics = []
1548        for c in service['characteristics']:
1549            characteristics.append(
1550                self.make_dbus_characteristic(c['uuid'], c['instance_id'], c['properties'], c['permissions'],
1551                                              c['key_size'], c['write_type'], c['descriptors']))
1552
1553        included_services = []
1554        for s in service['included_services']:
1555            included_services.append(self.make_dbus_service(s))
1556        service_uuid = utils.get_uuid_as_list(service['uuid'])
1557        return {
1558            'uuid': GLib.Variant('ay', service_uuid),
1559            'instance_id': GLib.Variant('i', service['instance_id']),
1560            'service_type': GLib.Variant('i', service['service_type']),
1561            'characteristics': GLib.Variant('aa{sv}', characteristics),
1562            'included_services': GLib.Variant('aa{sv}', included_services)
1563        }
1564