Loading android/pandora/mmi2grpc/mmi2grpc/__init__.py +9 −0 Original line number Diff line number Diff line Loading @@ -22,6 +22,7 @@ import sys import grpc from mmi2grpc.a2dp import A2DPProxy from mmi2grpc.gatt import GATTProxy from mmi2grpc.hfp import HFPProxy from mmi2grpc.sdp import SDPProxy from mmi2grpc.sm import SMProxy Loading Loading @@ -53,6 +54,7 @@ class IUT: # Profile proxies. self._a2dp = None self._gatt = None self._hfp = None self._sdp = None self._sm = None Loading @@ -66,8 +68,10 @@ class IUT: def __exit__(self, exc_type, exc_value, exc_traceback): self._a2dp = None self._gatt = None self._hfp = None self._sdp = None self._sm = None def _retry(self, func): Loading Loading @@ -111,6 +115,11 @@ class IUT: if not self._a2dp: self._a2dp = A2DPProxy(grpc.insecure_channel(f'localhost:{self.port}')) return self._a2dp.interact(test, interaction, description, pts_address) # Handles GATT MMIs. if profile in ('GATT'): if not self._gatt: self._gatt = GATTProxy(grpc.insecure_channel(f'localhost:{self.port}')) return self._gatt.interact(test, interaction, description, pts_address) # Handles HFP MMIs. if profile in ('HFP'): if not self._hfp: Loading android/pandora/mmi2grpc/mmi2grpc/gatt.py 0 → 100644 +88 −0 Original line number Diff line number Diff line # Copyright 2022 Google LLC # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # https://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. import re from mmi2grpc._helpers import assert_description from mmi2grpc._proxy import ProfileProxy from pandora.gatt_grpc import GATT from pandora.host_grpc import Host class GATTProxy(ProfileProxy): def __init__(self, channel): super().__init__() self.gatt = GATT(channel) self.host = Host(channel) self.connection = None @assert_description def MMI_IUT_INITIATE_CONNECTION(self, pts_addr: bytes, **kwargs): """ Please initiate a GATT connection to the PTS. Description: Verify that the Implementation Under Test (IUT) can initiate GATT connect request to PTS. """ self.connection = self.host.ConnectLE(address=pts_addr).connection return "OK" @assert_description def MMI_IUT_MTU_EXCHANGE(self, **kwargs): """ Please send exchange MTU command to the PTS. Description: Verify that the Implementation Under Test (IUT) can send Exchange MTU command to the tester. """ assert self.connection is not None self.gatt.ExchangeMTU(mtu=512, connection=self.connection) return "OK" def MMI_IUT_SEND_PREPARE_WRITE_REQUEST_VALID_SIZE(self, description: str, **kwargs): """ Please send prepare write request with handle = 'FFFF'O and size = 'XXX' to the PTS. Description: Verify that the Implementation Under Test (IUT) can send data according to negotiate MTU size. """ assert self.connection is not None matches = re.findall("'([a0-Z9]*)'O and size = '([a0-Z9]*)'", description) handle = int(matches[0][0], 16) data = bytes([1]) * int(matches[0][1]) self.gatt.WriteCharacteristicFromHandle(connection=self.connection, handle=handle, value=data) return "OK" @assert_description def MMI_IUT_INITIATE_DISCONNECTION(self, **kwargs): """ Please initiate a GATT disconnection to the PTS. Description: Verify that the Implementation Under Test (IUT) can initiate GATT disconnect request to PTS. """ assert self.connection is not None self.host.DisconnectLE(connection=self.connection) self.connection = None return "OK" android/pandora/server/Android.bp +5 −2 Original line number Diff line number Diff line Loading @@ -99,18 +99,21 @@ genrule { " $(in)", srcs: [ "proto/pandora/a2dp.proto", "proto/pandora/gatt.proto", "proto/pandora/hfp.proto", "proto/pandora/host.proto", "proto/pandora/sm.proto" "proto/pandora/sm.proto", ], out: [ "pandora/a2dp_grpc.py", "pandora/a2dp_pb2.py", "pandora/gatt_grpc.py", "pandora/gatt_pb2.py", "pandora/hfp_grpc.py", "pandora/hfp_pb2.py", "pandora/host_grpc.py", "pandora/host_pb2.py", "pandora/sm_pb2.py", "pandora/sm_grpc.py", "pandora/sm_pb2.py", ] } android/pandora/server/configs/PtsBotTest.xml +1 −0 Original line number Diff line number Diff line Loading @@ -22,6 +22,7 @@ <option name="physical" value="false" /> <option name="profile" value="A2DP/SRC" /> <option name="profile" value="AVDTP/SRC" /> <option name="profile" value="GATT/CL/GAC" /> <option name="profile" value="HFP/AG/DIS" /> <option name="profile" value="HFP/AG/HFI" /> <option name="profile" value="HFP/AG/SLC" /> Loading android/pandora/server/proto/pandora/gatt.proto 0 → 100644 +29 −0 Original line number Diff line number Diff line syntax = "proto3"; option java_outer_classname = "GattProto"; package pandora; import "pandora/host.proto"; import "google/protobuf/empty.proto"; service GATT { // Request an MTU size. rpc ExchangeMTU(ExchangeMTURequest) returns (google.protobuf.Empty); // Writes on a characteristic. rpc WriteCharacteristicFromHandle(WriteCharacteristicRequest) returns (google.protobuf.Empty); } // Request for the `ExchangeMTU` method. message ExchangeMTURequest { Connection connection = 1; int32 mtu = 2; } // Request for the `writeCharacteristicFromHandle` method. message WriteCharacteristicRequest { Connection connection = 1; uint32 handle = 2; bytes value = 3; } Loading
android/pandora/mmi2grpc/mmi2grpc/__init__.py +9 −0 Original line number Diff line number Diff line Loading @@ -22,6 +22,7 @@ import sys import grpc from mmi2grpc.a2dp import A2DPProxy from mmi2grpc.gatt import GATTProxy from mmi2grpc.hfp import HFPProxy from mmi2grpc.sdp import SDPProxy from mmi2grpc.sm import SMProxy Loading Loading @@ -53,6 +54,7 @@ class IUT: # Profile proxies. self._a2dp = None self._gatt = None self._hfp = None self._sdp = None self._sm = None Loading @@ -66,8 +68,10 @@ class IUT: def __exit__(self, exc_type, exc_value, exc_traceback): self._a2dp = None self._gatt = None self._hfp = None self._sdp = None self._sm = None def _retry(self, func): Loading Loading @@ -111,6 +115,11 @@ class IUT: if not self._a2dp: self._a2dp = A2DPProxy(grpc.insecure_channel(f'localhost:{self.port}')) return self._a2dp.interact(test, interaction, description, pts_address) # Handles GATT MMIs. if profile in ('GATT'): if not self._gatt: self._gatt = GATTProxy(grpc.insecure_channel(f'localhost:{self.port}')) return self._gatt.interact(test, interaction, description, pts_address) # Handles HFP MMIs. if profile in ('HFP'): if not self._hfp: Loading
android/pandora/mmi2grpc/mmi2grpc/gatt.py 0 → 100644 +88 −0 Original line number Diff line number Diff line # Copyright 2022 Google LLC # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # https://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. import re from mmi2grpc._helpers import assert_description from mmi2grpc._proxy import ProfileProxy from pandora.gatt_grpc import GATT from pandora.host_grpc import Host class GATTProxy(ProfileProxy): def __init__(self, channel): super().__init__() self.gatt = GATT(channel) self.host = Host(channel) self.connection = None @assert_description def MMI_IUT_INITIATE_CONNECTION(self, pts_addr: bytes, **kwargs): """ Please initiate a GATT connection to the PTS. Description: Verify that the Implementation Under Test (IUT) can initiate GATT connect request to PTS. """ self.connection = self.host.ConnectLE(address=pts_addr).connection return "OK" @assert_description def MMI_IUT_MTU_EXCHANGE(self, **kwargs): """ Please send exchange MTU command to the PTS. Description: Verify that the Implementation Under Test (IUT) can send Exchange MTU command to the tester. """ assert self.connection is not None self.gatt.ExchangeMTU(mtu=512, connection=self.connection) return "OK" def MMI_IUT_SEND_PREPARE_WRITE_REQUEST_VALID_SIZE(self, description: str, **kwargs): """ Please send prepare write request with handle = 'FFFF'O and size = 'XXX' to the PTS. Description: Verify that the Implementation Under Test (IUT) can send data according to negotiate MTU size. """ assert self.connection is not None matches = re.findall("'([a0-Z9]*)'O and size = '([a0-Z9]*)'", description) handle = int(matches[0][0], 16) data = bytes([1]) * int(matches[0][1]) self.gatt.WriteCharacteristicFromHandle(connection=self.connection, handle=handle, value=data) return "OK" @assert_description def MMI_IUT_INITIATE_DISCONNECTION(self, **kwargs): """ Please initiate a GATT disconnection to the PTS. Description: Verify that the Implementation Under Test (IUT) can initiate GATT disconnect request to PTS. """ assert self.connection is not None self.host.DisconnectLE(connection=self.connection) self.connection = None return "OK"
android/pandora/server/Android.bp +5 −2 Original line number Diff line number Diff line Loading @@ -99,18 +99,21 @@ genrule { " $(in)", srcs: [ "proto/pandora/a2dp.proto", "proto/pandora/gatt.proto", "proto/pandora/hfp.proto", "proto/pandora/host.proto", "proto/pandora/sm.proto" "proto/pandora/sm.proto", ], out: [ "pandora/a2dp_grpc.py", "pandora/a2dp_pb2.py", "pandora/gatt_grpc.py", "pandora/gatt_pb2.py", "pandora/hfp_grpc.py", "pandora/hfp_pb2.py", "pandora/host_grpc.py", "pandora/host_pb2.py", "pandora/sm_pb2.py", "pandora/sm_grpc.py", "pandora/sm_pb2.py", ] }
android/pandora/server/configs/PtsBotTest.xml +1 −0 Original line number Diff line number Diff line Loading @@ -22,6 +22,7 @@ <option name="physical" value="false" /> <option name="profile" value="A2DP/SRC" /> <option name="profile" value="AVDTP/SRC" /> <option name="profile" value="GATT/CL/GAC" /> <option name="profile" value="HFP/AG/DIS" /> <option name="profile" value="HFP/AG/HFI" /> <option name="profile" value="HFP/AG/SLC" /> Loading
android/pandora/server/proto/pandora/gatt.proto 0 → 100644 +29 −0 Original line number Diff line number Diff line syntax = "proto3"; option java_outer_classname = "GattProto"; package pandora; import "pandora/host.proto"; import "google/protobuf/empty.proto"; service GATT { // Request an MTU size. rpc ExchangeMTU(ExchangeMTURequest) returns (google.protobuf.Empty); // Writes on a characteristic. rpc WriteCharacteristicFromHandle(WriteCharacteristicRequest) returns (google.protobuf.Empty); } // Request for the `ExchangeMTU` method. message ExchangeMTURequest { Connection connection = 1; int32 mtu = 2; } // Request for the `writeCharacteristicFromHandle` method. message WriteCharacteristicRequest { Connection connection = 1; uint32 handle = 2; bytes value = 3; }