diff options
author | Charlie Boutier <charliebout@google.com> | 2023-08-29 18:23:58 +0000 |
---|---|---|
committer | Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com> | 2023-08-29 18:23:58 +0000 |
commit | a9afb581c7195dbfc67952a25e14125556d67c72 (patch) | |
tree | 15922af10b66d99570919809ae4d488b462404db | |
parent | 50c4cf533608aae985077b3fba13be5f2796024a (diff) | |
parent | e88edaa5370a2d92b474e432e29a1bce19567359 (diff) | |
download | bumble-a9afb581c7195dbfc67952a25e14125556d67c72.tar.gz |
Merge remote-tracking branch 'aosp/upstream-main' into main am: e88edaa537
Original change: https://android-review.googlesource.com/c/platform/external/python/bumble/+/2714703
Change-Id: I2d44a51f0dad4cb8c4604540b052c6923f8c1e99
Signed-off-by: Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
-rw-r--r-- | apps/pandora_server.py | 23 | ||||
-rw-r--r-- | bumble/at.py | 85 | ||||
-rw-r--r-- | bumble/device.py | 56 | ||||
-rw-r--r-- | bumble/hfp.py | 782 | ||||
-rw-r--r-- | bumble/pandora/config.py | 9 | ||||
-rw-r--r-- | bumble/pandora/security.py | 1 | ||||
-rw-r--r-- | bumble/sdp.py | 4 | ||||
-rw-r--r-- | bumble/smp.py | 15 | ||||
-rw-r--r-- | examples/run_hfp_gateway.py | 62 | ||||
-rw-r--r-- | examples/run_hfp_handsfree.py | 115 | ||||
-rw-r--r-- | rust/CHANGELOG.md | 7 | ||||
-rw-r--r-- | rust/Cargo.lock | 129 | ||||
-rw-r--r-- | rust/Cargo.toml | 9 | ||||
-rw-r--r-- | rust/README.md | 14 | ||||
-rw-r--r-- | rust/pytests/assigned_numbers.rs | 30 | ||||
-rw-r--r-- | rust/pytests/pytests.rs | 1 | ||||
-rw-r--r-- | rust/pytests/wrapper.rs | 10 | ||||
-rw-r--r-- | rust/src/wrapper/assigned_numbers/company_ids.rs | 2715 | ||||
-rw-r--r-- | rust/src/wrapper/assigned_numbers/mod.rs | 36 | ||||
-rw-r--r-- | rust/src/wrapper/core.rs | 2 | ||||
-rw-r--r-- | rust/tools/gen_assigned_numbers.rs | 97 | ||||
-rw-r--r-- | tests/at_test.py | 35 | ||||
-rw-r--r-- | tests/self_test.py | 31 |
23 files changed, 3937 insertions, 331 deletions
diff --git a/apps/pandora_server.py b/apps/pandora_server.py index 5f92309..b577f82 100644 --- a/apps/pandora_server.py +++ b/apps/pandora_server.py @@ -1,8 +1,10 @@ import asyncio import click import logging +import json from bumble.pandora import PandoraDevice, serve +from typing import Dict, Any BUMBLE_SERVER_GRPC_PORT = 7999 ROOTCANAL_PORT_CUTTLEFISH = 7300 @@ -18,13 +20,30 @@ ROOTCANAL_PORT_CUTTLEFISH = 7300 help='HCI transport', default=f'tcp-client:127.0.0.1:<rootcanal-port>', ) -def main(grpc_port: int, rootcanal_port: int, transport: str) -> None: +@click.option( + '--config', + help='Bumble json configuration file', +) +def main(grpc_port: int, rootcanal_port: int, transport: str, config: str) -> None: if '<rootcanal-port>' in transport: transport = transport.replace('<rootcanal-port>', str(rootcanal_port)) - device = PandoraDevice({'transport': transport}) + + bumble_config = retrieve_config(config) + if 'transport' not in bumble_config.keys(): + bumble_config.update({'transport': transport}) + device = PandoraDevice(bumble_config) + logging.basicConfig(level=logging.DEBUG) asyncio.run(serve(device, port=grpc_port)) +def retrieve_config(config: str) -> Dict[str, Any]: + if not config: + return {} + + with open(config, 'r') as f: + return json.load(f) + + if __name__ == '__main__': main() # pylint: disable=no-value-for-parameter diff --git a/bumble/at.py b/bumble/at.py new file mode 100644 index 0000000..78a4b08 --- /dev/null +++ b/bumble/at.py @@ -0,0 +1,85 @@ +# Copyright 2023 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. + +from typing import List, Union + + +def tokenize_parameters(buffer: bytes) -> List[bytes]: + """Split input parameters into tokens. + Removes space characters outside of double quote blocks: + T-rec-V-25 - 5.2.1 Command line general format: "Space characters (IA5 2/0) + are ignored [..], unless they are embedded in numeric or string constants" + Raises ValueError in case of invalid input string.""" + + tokens = [] + in_quotes = False + token = bytearray() + for b in buffer: + char = bytearray([b]) + + if in_quotes: + token.extend(char) + if char == b'\"': + in_quotes = False + tokens.append(token[1:-1]) + token = bytearray() + else: + if char == b' ': + pass + elif char == b',' or char == b')': + tokens.append(token) + tokens.append(char) + token = bytearray() + elif char == b'(': + if len(token) > 0: + raise ValueError("open_paren following regular character") + tokens.append(char) + elif char == b'"': + if len(token) > 0: + raise ValueError("quote following regular character") + in_quotes = True + token.extend(char) + else: + token.extend(char) + + tokens.append(token) + return [bytes(token) for token in tokens if len(token) > 0] + + +def parse_parameters(buffer: bytes) -> List[Union[bytes, list]]: + """Parse the parameters using the comma and parenthesis separators. + Raises ValueError in case of invalid input string.""" + + tokens = tokenize_parameters(buffer) + accumulator: List[list] = [[]] + current: Union[bytes, list] = bytes() + + for token in tokens: + if token == b',': + accumulator[-1].append(current) + current = bytes() + elif token == b'(': + accumulator.append([]) + elif token == b')': + if len(accumulator) < 2: + raise ValueError("close_paren without matching open_paren") + accumulator[-1].append(current) + current = accumulator.pop() + else: + current = token + + accumulator[-1].append(current) + if len(accumulator) > 1: + raise ValueError("missing close_paren") + return accumulator[0] diff --git a/bumble/device.py b/bumble/device.py index 031c071..6ab0a12 100644 --- a/bumble/device.py +++ b/bumble/device.py @@ -86,6 +86,7 @@ from .hci import ( HCI_LE_Extended_Create_Connection_Command, HCI_LE_Rand_Command, HCI_LE_Read_PHY_Command, + HCI_LE_Set_Address_Resolution_Enable_Command, HCI_LE_Set_Advertising_Data_Command, HCI_LE_Set_Advertising_Enable_Command, HCI_LE_Set_Advertising_Parameters_Command, @@ -778,6 +779,7 @@ class DeviceConfiguration: self.irk = bytes(16) # This really must be changed for any level of security self.keystore = None self.gatt_services: List[Dict[str, Any]] = [] + self.address_resolution_offload = False def load_from_dict(self, config: Dict[str, Any]) -> None: # Load simple properties @@ -1029,6 +1031,7 @@ class Device(CompositeEventEmitter): self.discoverable = config.discoverable self.connectable = config.connectable self.classic_accept_any = config.classic_accept_any + self.address_resolution_offload = config.address_resolution_offload for service in config.gatt_services: characteristics = [] @@ -1256,31 +1259,16 @@ class Device(CompositeEventEmitter): ) # Load the address resolving list - if self.keystore and self.host.supports_command( - HCI_LE_CLEAR_RESOLVING_LIST_COMMAND - ): - await self.send_command(HCI_LE_Clear_Resolving_List_Command()) # type: ignore[call-arg] - - resolving_keys = await self.keystore.get_resolving_keys() - for irk, address in resolving_keys: - await self.send_command( - HCI_LE_Add_Device_To_Resolving_List_Command( - peer_identity_address_type=address.address_type, - peer_identity_address=address, - peer_irk=irk, - local_irk=self.irk, - ) # type: ignore[call-arg] - ) - - # Enable address resolution - # await self.send_command( - # HCI_LE_Set_Address_Resolution_Enable_Command( - # address_resolution_enable=1) - # ) - # ) + if self.keystore: + await self.refresh_resolving_list() - # Create a host-side address resolver - self.address_resolver = smp.AddressResolver(resolving_keys) + # Enable address resolution + if self.address_resolution_offload: + await self.send_command( + HCI_LE_Set_Address_Resolution_Enable_Command( + address_resolution_enable=1 + ) # type: ignore[call-arg] + ) if self.classic_enabled: await self.send_command( @@ -1310,6 +1298,26 @@ class Device(CompositeEventEmitter): await self.host.flush() self.powered_on = False + async def refresh_resolving_list(self) -> None: + assert self.keystore is not None + + resolving_keys = await self.keystore.get_resolving_keys() + # Create a host-side address resolver + self.address_resolver = smp.AddressResolver(resolving_keys) + + if self.address_resolution_offload: + await self.send_command(HCI_LE_Clear_Resolving_List_Command()) # type: ignore[call-arg] + + for irk, address in resolving_keys: + await self.send_command( + HCI_LE_Add_Device_To_Resolving_List_Command( + peer_identity_address_type=address.address_type, + peer_identity_address=address, + peer_irk=irk, + local_irk=self.irk, + ) # type: ignore[call-arg] + ) + def supports_le_feature(self, feature): return self.host.supports_le_feature(feature) diff --git a/bumble/hfp.py b/bumble/hfp.py index 9080a55..6d9e428 100644 --- a/bumble/hfp.py +++ b/bumble/hfp.py @@ -1,4 +1,4 @@ -# Copyright 2021-2022 Google LLC +# Copyright 2023 Google LLC # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -17,11 +17,31 @@ # ----------------------------------------------------------------------------- import logging import asyncio -import collections -from typing import Union +import dataclasses +import enum +import traceback +from typing import Dict, List, Union, Set +from . import at from . import rfcomm -from .colors import color + +from bumble.core import ( + ProtocolError, + BT_GENERIC_AUDIO_SERVICE, + BT_HANDSFREE_SERVICE, + BT_L2CAP_PROTOCOL_ID, + BT_RFCOMM_PROTOCOL_ID, +) +from bumble.sdp import ( + DataElement, + ServiceAttribute, + SDP_SERVICE_RECORD_HANDLE_ATTRIBUTE_ID, + SDP_SERVICE_CLASS_ID_LIST_ATTRIBUTE_ID, + SDP_PROTOCOL_DESCRIPTOR_LIST_ATTRIBUTE_ID, + SDP_BLUETOOTH_PROFILE_DESCRIPTOR_LIST_ATTRIBUTE_ID, + SDP_SUPPORTED_FEATURES_ATTRIBUTE_ID, +) + # ----------------------------------------------------------------------------- # Logging @@ -30,72 +50,700 @@ logger = logging.getLogger(__name__) # ----------------------------------------------------------------------------- -# Protocol Support +# Normative protocol definitions # ----------------------------------------------------------------------------- + +# HF supported features (AT+BRSF=) (normative). +# Hands-Free Profile v1.8, 4.34.2, AT Capabilities Re-Used from GSM 07.07 +# and 3GPP 27.007 +class HfFeature(enum.IntFlag): + EC_NR = 0x001 # Echo Cancel & Noise reduction + THREE_WAY_CALLING = 0x002 + CLI_PRESENTATION_CAPABILITY = 0x004 + VOICE_RECOGNITION_ACTIVATION = 0x008 + REMOTE_VOLUME_CONTROL = 0x010 + ENHANCED_CALL_STATUS = 0x020 + ENHANCED_CALL_CONTROL = 0x040 + CODEC_NEGOTIATION = 0x080 + HF_INDICATORS = 0x100 + ESCO_S4_SETTINGS_SUPPORTED = 0x200 + ENHANCED_VOICE_RECOGNITION_STATUS = 0x400 + VOICE_RECOGNITION_TEST = 0x800 + + +# AG supported features (+BRSF:) (normative). +# Hands-Free Profile v1.8, 4.34.2, AT Capabilities Re-Used from GSM 07.07 +# and 3GPP 27.007 +class AgFeature(enum.IntFlag): + THREE_WAY_CALLING = 0x001 + EC_NR = 0x002 # Echo Cancel & Noise reduction + VOICE_RECOGNITION_FUNCTION = 0x004 + IN_BAND_RING_TONE_CAPABILITY = 0x008 + VOICE_TAG = 0x010 # Attach a number to voice tag + REJECT_CALL = 0x020 # Ability to reject a call + ENHANCED_CALL_STATUS = 0x040 + ENHANCED_CALL_CONTROL = 0x080 + EXTENDED_ERROR_RESULT_CODES = 0x100 + CODEC_NEGOTIATION = 0x200 + HF_INDICATORS = 0x400 + ESCO_S4_SETTINGS_SUPPORTED = 0x800 + ENHANCED_VOICE_RECOGNITION_STATUS = 0x1000 + VOICE_RECOGNITION_TEST = 0x2000 + + +# Audio Codec IDs (normative). +# Hands-Free Profile v1.8, 10 Appendix B +class AudioCodec(enum.IntEnum): + CVSD = 0x01 # Support for CVSD audio codec + MSBC = 0x02 # Support for mSBC audio codec + + +# HF Indicators (normative). +# Bluetooth Assigned Numbers, 6.10.1 HF Indicators +class HfIndicator(enum.IntEnum): + ENHANCED_SAFETY = 0x01 # Enhanced safety feature + BATTERY_LEVEL = 0x02 # Battery level feature + + +# Call Hold supported operations (normative). +# AT Commands Reference Guide, 3.5.2.3.12 +CHLD - Call Holding Services +class CallHoldOperation(enum.IntEnum): + RELEASE_ALL_HELD_CALLS = 0 # Release all held calls + RELEASE_ALL_ACTIVE_CALLS = 1 # Release all active calls, accept other + HOLD_ALL_ACTIVE_CALLS = 2 # Place all active calls on hold, accept other + ADD_HELD_CALL = 3 # Adds a held call to conversation + + +# Response Hold status (normative). +# Hands-Free Profile v1.8, 4.34.2, AT Capabilities Re-Used from GSM 07.07 +# and 3GPP 27.007 +class ResponseHoldStatus(enum.IntEnum): + INC_CALL_HELD = 0 # Put incoming call on hold + HELD_CALL_ACC = 1 # Accept a held incoming call + HELD_CALL_REJ = 2 # Reject a held incoming call + + +# Values for the Call Setup AG indicator (normative). +# Hands-Free Profile v1.8, 4.34.2, AT Capabilities Re-Used from GSM 07.07 +# and 3GPP 27.007 +class CallSetupAgIndicator(enum.IntEnum): + NOT_IN_CALL_SETUP = 0 + INCOMING_CALL_PROCESS = 1 + OUTGOING_CALL_SETUP = 2 + REMOTE_ALERTED = 3 # Remote party alerted in an outgoing call + + +# Values for the Call Held AG indicator (normative). +# Hands-Free Profile v1.8, 4.34.2, AT Capabilities Re-Used from GSM 07.07 +# and 3GPP 27.007 +class CallHeldAgIndicator(enum.IntEnum): + NO_CALLS_HELD = 0 + # Call is placed on hold or active/held calls swapped + # (The AG has both an active AND a held call) + CALL_ON_HOLD_AND_ACTIVE_CALL = 1 + CALL_ON_HOLD_NO_ACTIVE_CALL = 2 # Call on hold, no active call + + +# Call Info direction (normative). +# AT Commands Reference Guide, 3.5.2.3.15 +CLCC - List Current Calls +class CallInfoDirection(enum.IntEnum): + MOBILE_ORIGINATED_CALL = 0 + MOBILE_TERMINATED_CALL = 1 + + +# Call Info status (normative). +# AT Commands Reference Guide, 3.5.2.3.15 +CLCC - List Current Calls +class CallInfoStatus(enum.IntEnum): + ACTIVE = 0 + HELD = 1 + DIALING = 2 + ALERTING = 3 + INCOMING = 4 + WAITING = 5 + + +# Call Info mode (normative). +# AT Commands Reference Guide, 3.5.2.3.15 +CLCC - List Current Calls +class CallInfoMode(enum.IntEnum): + VOICE = 0 + DATA = 1 + FAX = 2 + UNKNOWN = 9 + + +# ----------------------------------------------------------------------------- +# Hands-Free Control Interoperability Requirements # ----------------------------------------------------------------------------- -class HfpProtocol: + +# Response codes. +RESPONSE_CODES = [ + "+APLSIRI", + "+BAC", + "+BCC", + "+BCS", + "+BIA", + "+BIEV", + "+BIND", + "+BINP", + "+BLDN", + "+BRSF", + "+BTRH", + "+BVRA", + "+CCWA", + "+CHLD", + "+CHUP", + "+CIND", + "+CLCC", + "+CLIP", + "+CMEE", + "+CMER", + "+CNUM", + "+COPS", + "+IPHONEACCEV", + "+NREC", + "+VGM", + "+VGS", + "+VTS", + "+XAPL", + "A", + "D", +] + +# Unsolicited responses and statuses. +UNSOLICITED_CODES = [ + "+APLSIRI", + "+BCS", + "+BIND", + "+BSIR", + "+BTRH", + "+BVRA", + "+CCWA", + "+CIEV", + "+CLIP", + "+VGM", + "+VGS", + "BLACKLISTED", + "BUSY", + "DELAYED", + "NO ANSWER", + "NO CARRIER", + "RING", +] + +# Status codes +STATUS_CODES = [ + "+CME ERROR", + "BLACKLISTED", + "BUSY", + "DELAYED", + "ERROR", + "NO ANSWER", + "NO CARRIER", + "OK", +] + + +@dataclasses.dataclass +class Configuration: + supported_hf_features: List[HfFeature] + supported_hf_indicators: List[HfIndicator] + supported_audio_codecs: List[AudioCodec] + + +class AtResponseType(enum.Enum): + """Indicate if a response is expected from an AT command, and if multiple + responses are accepted.""" + + NONE = 0 + SINGLE = 1 + MULTIPLE = 2 + + +class AtResponse: + code: str + parameters: list + + def __init__(self, response: bytearray): + code_and_parameters = response.split(b':') + parameters = ( + code_and_parameters[1] if len(code_and_parameters) > 1 else bytearray() + ) + self.code = code_and_parameters[0].decode() + self.parameters = at.parse_parameters(parameters) + + +@dataclasses.dataclass +class AgIndicatorState: + description: str + index: int + supported_values: Set[int] + current_status: int + + +@dataclasses.dataclass +class HfIndicatorState: + supported: bool = False + enabled: bool = False + + +class HfProtocol: + """Implementation for the Hands-Free side of the Hands-Free profile. + Reference specification Hands-Free Profile v1.8""" + + supported_hf_features: int + supported_audio_codecs: List[AudioCodec] + + supported_ag_features: int + supported_ag_call_hold_operations: List[CallHoldOperation] + + ag_indicators: List[AgIndicatorState] + hf_indicators: Dict[HfIndicator, HfIndicatorState] + dlc: rfcomm.DLC - buffer: str - lines: collections.deque - lines_available: asyncio.Event + command_lock: asyncio.Lock + response_queue: asyncio.Queue + unsolicited_queue: asyncio.Queue + read_buffer: bytearray - def __init__(self, dlc: rfcomm.DLC) -> None: + def __init__(self, dlc: rfcomm.DLC, configuration: Configuration): + # Configure internal state. self.dlc = dlc - self.buffer = '' - self.lines = collections.deque() - self.lines_available = asyncio.Event() - - dlc.sink = self.feed - - def feed(self, data: Union[bytes, str]) -> None: - # Convert the data to a string if needed - if isinstance(data, bytes): - data = data.decode('utf-8') - - logger.debug(f'<<< Data received: {data}') - - # Add to the buffer and look for lines - self.buffer += data - while (separator := self.buffer.find('\r')) >= 0: - line = self.buffer[:separator].strip() - self.buffer = self.buffer[separator + 1 :] - if len(line) > 0: - self.on_line(line) - - def on_line(self, line: str) -> None: - self.lines.append(line) - self.lines_available.set() - - def send_command_line(self, line: str) -> None: - logger.debug(color(f'>>> {line}', 'yellow')) - self.dlc.write(line + '\r') - - def send_response_line(self, line: str) -> None: - logger.debug(color(f'>>> {line}', 'yellow')) - self.dlc.write('\r\n' + line + '\r\n') - - async def next_line(self) -> str: - await self.lines_available.wait() - line = self.lines.popleft() - if not self.lines: - self.lines_available.clear() - logger.debug(color(f'<<< {line}', 'green')) - return line - - async def initialize_service(self) -> None: - # Perform Service Level Connection Initialization - self.send_command_line('AT+BRSF=2072') # Retrieve Supported Features - await (self.next_line()) - await (self.next_line()) - - self.send_command_line('AT+CIND=?') - await (self.next_line()) - await (self.next_line()) - - self.send_command_line('AT+CIND?') - await (self.next_line()) - await (self.next_line()) - - self.send_command_line('AT+CMER=3,0,0,1') - await (self.next_line()) + self.command_lock = asyncio.Lock() + self.response_queue = asyncio.Queue() + self.unsolicited_queue = asyncio.Queue() + self.read_buffer = bytearray() + + # Build local features. + self.supported_hf_features = sum(configuration.supported_hf_features) + self.supported_audio_codecs = configuration.supported_audio_codecs + + self.hf_indicators = { + indicator: HfIndicatorState() + for indicator in configuration.supported_hf_indicators + } + + # Clear remote features. + self.supported_ag_features = 0 + self.supported_ag_call_hold_operations = [] + self.ag_indicators = [] + + # Bind the AT reader to the RFCOMM channel. + self.dlc.sink = self._read_at + + def supports_hf_feature(self, feature: HfFeature) -> bool: + return (self.supported_hf_features & feature) != 0 + + def supports_ag_feature(self, feature: AgFeature) -> bool: + return (self.supported_ag_features & feature) != 0 + + # Read AT messages from the RFCOMM channel. + # Enqueue AT commands, responses, unsolicited responses to their + # respective queues, and set the corresponding event. + def _read_at(self, data: bytes): + # Append to the read buffer. + self.read_buffer.extend(data) + + # Locate header and trailer. + header = self.read_buffer.find(b'\r\n') + trailer = self.read_buffer.find(b'\r\n', header + 2) + if header == -1 or trailer == -1: + return + + # Isolate the AT response code and parameters. + raw_response = self.read_buffer[header + 2 : trailer] + response = AtResponse(raw_response) + logger.debug(f"<<< {raw_response.decode()}") + + # Consume the response bytes. + self.read_buffer = self.read_buffer[trailer + 2 :] + + # Forward the received code to the correct queue. + if self.command_lock.locked() and ( + response.code in STATUS_CODES or response.code in RESPONSE_CODES + ): + self.response_queue.put_nowait(response) + elif response.code in UNSOLICITED_CODES: + self.unsolicited_queue.put_nowait(response) + else: + logger.warning(f"dropping unexpected response with code '{response.code}'") + + # Send an AT command and wait for the peer resposne. + # Wait for the AT responses sent by the peer, to the status code. + # Raises asyncio.TimeoutError if the status is not received + # after a timeout (default 1 second). + # Raises ProtocolError if the status is not OK. + async def execute_command( + self, + cmd: str, + timeout: float = 1.0, + response_type: AtResponseType = AtResponseType.NONE, + ) -> Union[None, AtResponse, List[AtResponse]]: + async with self.command_lock: + logger.debug(f">>> {cmd}") + self.dlc.write(cmd + '\r') + responses: List[AtResponse] = [] + + while True: + result = await asyncio.wait_for( + self.response_queue.get(), timeout=timeout + ) + if result.code == 'OK': + if response_type == AtResponseType.SINGLE and len(responses) != 1: + raise ProtocolError("NO ANSWER") + + if response_type == AtResponseType.MULTIPLE: + return responses + if response_type == AtResponseType.SINGLE: + return responses[0] + return None + if result.code in STATUS_CODES: + raise ProtocolError(result.code) + responses.append(result) + + # 4.2.1 Service Level Connection Initialization. + async def initiate_slc(self): + # 4.2.1.1 Supported features exchange + # First, in the initialization procedure, the HF shall send the + # AT+BRSF=<HF supported features> command to the AG to both notify + # the AG of the supported features in the HF, as well as to retrieve the + # supported features in the AG using the +BRSF result code. + response = await self.execute_command( + f"AT+BRSF={self.supported_hf_features}", response_type=AtResponseType.SINGLE + ) + + self.supported_ag_features = int(response.parameters[0]) + logger.info(f"supported AG features: {self.supported_ag_features}") + for feature in AgFeature: + if self.supports_ag_feature(feature): + logger.info(f" - {feature.name}") + + # 4.2.1.2 Codec Negotiation + # Secondly, in the initialization procedure, if the HF supports the + # Codec Negotiation feature, it shall check if the AT+BRSF command + # response from the AG has indicated that it supports the Codec + # Negotiation feature. + if self.supports_hf_feature( + HfFeature.CODEC_NEGOTIATION + ) and self.supports_ag_feature(AgFeature.CODEC_NEGOTIATION): + # If both the HF and AG do support the Codec Negotiation feature + # then the HF shall send the AT+BAC=<HF available codecs> command to + # the AG to notify the AG of the available codecs in the HF. + codecs = [str(c) for c in self.supported_audio_codecs] + await self.execute_command(f"AT+BAC={','.join(codecs)}") + + # 4.2.1.3 AG Indicators + # After having retrieved the supported features in the AG, the HF shall + # determine which indicators are supported by the AG, as well as the + # ordering of the supported indicators. This is because, according to + # the 3GPP 27.007 specification [2], the AG may support additional + # indicators not provided for by the Hands-Free Profile, and because the + # ordering of the indicators is implementation specific. The HF uses + # the AT+CIND=? Test command to retrieve information about the supported + # indicators and their ordering. + response = await self.execute_command( + "AT+CIND=?", response_type=AtResponseType.SINGLE + ) + + self.ag_indicators = [] + for index, indicator in enumerate(response.parameters): + description = indicator[0].decode() + supported_values = [] + for value in indicator[1]: + value = value.split(b'-') + value = [int(v) for v in value] + value_min = value[0] + value_max = value[1] if len(value) > 1 else value[0] + supported_values.extend([v for v in range(value_min, value_max + 1)]) + + self.ag_indicators.append( + AgIndicatorState(description, index, set(supported_values), 0) + ) + + # Once the HF has the necessary supported indicator and ordering + # information, it shall retrieve the current status of the indicators + # in the AG using the AT+CIND? Read command. + response = await self.execute_command( + "AT+CIND?", response_type=AtResponseType.SINGLE + ) + + for index, indicator in enumerate(response.parameters): + self.ag_indicators[index].current_status = int(indicator) + + # After having retrieved the status of the indicators in the AG, the HF + # shall then enable the "Indicators status update" function in the AG by + # issuing the AT+CMER command, to which the AG shall respond with OK. + await self.execute_command("AT+CMER=3,,,1") + + if self.supports_hf_feature( + HfFeature.THREE_WAY_CALLING + ) and self.supports_ag_feature(HfFeature.THREE_WAY_CALLING): + # After the HF has enabled the “Indicators status update” function in + # the AG, and if the “Call waiting and 3-way calling” bit was set in the + # supported features bitmap by both the HF and the AG, the HF shall + # issue the AT+CHLD=? test command to retrieve the information about how + # the call hold and multiparty services are supported in the AG. The HF + # shall not issue the AT+CHLD=? test command in case either the HF or + # the AG does not support the "Three-way calling" feature. + response = await self.execute_command( + "AT+CHLD=?", response_type=AtResponseType.SINGLE + ) + + self.supported_ag_call_hold_operations = [ + CallHoldOperation(int(operation)) + for operation in response.parameters[0] + if not b'x' in operation + ] + + # 4.2.1.4 HF Indicators + # If the HF supports the HF indicator feature, it shall check the +BRSF + # response to see if the AG also supports the HF Indicator feature. + if self.supports_hf_feature( + HfFeature.HF_INDICATORS + ) and self.supports_ag_feature(AgFeature.HF_INDICATORS): + # If both the HF and AG support the HF Indicator feature, then the HF + # shall send the AT+BIND=<HF supported HF indicators> command to the AG + # to notify the AG of the supported indicators’ assigned numbers in the + # HF. The AG shall respond with OK + indicators = [str(i) for i in self.hf_indicators.keys()] + await self.execute_command(f"AT+BIND={','.join(indicators)}") + + # After having provided the AG with the HF indicators it supports, + # the HF shall send the AT+BIND=? to request HF indicators supported + # by the AG. The AG shall reply with the +BIND response listing all + # HF indicators that it supports followed by an OK. + response = await self.execute_command( + "AT+BIND=?", response_type=AtResponseType.SINGLE + ) + + logger.info("supported HF indicators:") + for indicator in response.parameters[0]: + indicator = HfIndicator(int(indicator)) + logger.info(f" - {indicator.name}") + if indicator in self.hf_indicators: + self.hf_indicators[indicator].supported = True + + # Once the HF receives the supported HF indicators list from the AG, + # the HF shall send the AT+BIND? command to determine which HF + # indicators are enabled. The AG shall respond with one or more + # +BIND responses. The AG shall terminate the list with OK. + # (See Section 4.36.1.3). + responses = await self.execute_command( + "AT+BIND?", response_type=AtResponseType.MULTIPLE + ) + + logger.info("enabled HF indicators:") + for response in responses: + indicator = HfIndicator(int(response.parameters[0])) + enabled = int(response.parameters[1]) != 0 + logger.info(f" - {indicator.name}: {enabled}") + if indicator in self.hf_indicators: + self.hf_indicators[indicator].enabled = True + + logger.info("SLC setup completed") + + # 4.11.2 Audio Connection Setup by HF + async def setup_audio_connection(self): + # When the HF triggers the establishment of the Codec Connection it + # shall send the AT command AT+BCC to the AG. The AG shall respond with + # OK if it will start the Codec Connection procedure, and with ERROR + # if it cannot start the Codec Connection procedure. + await self.execute_command("AT+BCC") + + # 4.11.3 Codec Connection Setup + async def setup_codec_connection(self, codec_id: int): + # The AG shall send a +BCS=<Codec ID> unsolicited response to the HF. + # The HF shall then respond to the incoming unsolicited response with + # the AT command AT+BCS=<Codec ID>. The ID shall be the same as in the + # unsolicited response code as long as the ID is supported. + # If the received ID is not available, the HF shall respond with + # AT+BAC with its available codecs. + if codec_id not in self.supported_audio_codecs: + codecs = [str(c) for c in self.supported_audio_codecs] + await self.execute_command(f"AT+BAC={','.join(codecs)}") + return + + await self.execute_command(f"AT+BCS={codec_id}") + + # After sending the OK response, the AG shall open the + # Synchronous Connection with the settings that are determined by the + # ID. The HF shall be ready to accept the synchronous connection + # establishment as soon as it has sent the AT commands AT+BCS=<Codec ID>. + + logger.info("codec connection setup completed") + + # 4.13.1 Answer Incoming Call from the HF – In-Band Ringing + async def answer_incoming_call(self): + # The user accepts the incoming voice call by using the proper means + # provided by the HF. The HF shall then send the ATA command + # (see Section 4.34) to the AG. The AG shall then begin the procedure for + # accepting the incoming call. + await self.execute_command("ATA") + + # 4.14.1 Reject an Incoming Call from the HF + async def reject_incoming_call(self): + # The user rejects the incoming call by using the User Interface on the + # Hands-Free unit. The HF shall then send the AT+CHUP command + # (see Section 4.34) to the AG. This may happen at any time during the + # procedures described in Sections 4.13.1 and 4.13.2. + await self.execute_command("AT+CHUP") + + # 4.15.1 Terminate a Call Process from the HF + async def terminate_call(self): + # The user may abort the ongoing call process using whatever means + # provided by the Hands-Free unit. The HF shall send AT+CHUP command + # (see Section 4.34) to the AG, and the AG shall then start the + # procedure to terminate or interrupt the current call procedure. + # The AG shall then send the OK indication followed by the +CIEV result + # code, with the value indicating (call=0). + await self.execute_command("AT+CHUP") + + async def update_ag_indicator(self, index: int, value: int): + self.ag_indicators[index].current_status = value + logger.info( + f"AG indicator updated: {self.ag_indicators[index].description}, {value}" + ) + + async def handle_unsolicited(self): + """Handle unsolicited result codes sent by the audio gateway.""" + result = await self.unsolicited_queue.get() + if result.code == "+BCS": + await self.setup_codec_connection(int(result.parameters[0])) + elif result.code == "+CIEV": + await self.update_ag_indicator( + int(result.parameters[0]), int(result.parameters[1]) + ) + else: + logging.info(f"unhandled unsolicited response {result.code}") + + async def run(self): + """Main rountine for the Hands-Free side of the HFP protocol. + Initiates the service level connection then loops handling + unsolicited AG responses.""" + + try: + await self.initiate_slc() + while True: + await self.handle_unsolicited() + except Exception: + logger.error("HFP-HF protocol failed with the following error:") + logger.error(traceback.format_exc()) + + +# ----------------------------------------------------------------------------- +# Normative SDP definitions +# ----------------------------------------------------------------------------- + + +# Profile version (normative). +# Hands-Free Profile v1.8, 5.3 SDP Interoperability Requirements +class ProfileVersion(enum.IntEnum): + V1_5 = 0x0105 + V1_6 = 0x0106 + V1_7 = 0x0107 + V1_8 = 0x0108 + V1_9 = 0x0109 + + +# HF supported features (normative). +# Hands-Free Profile v1.8, 5.3 SDP Interoperability Requirements +class HfSdpFeature(enum.IntFlag): + EC_NR = 0x01 # Echo Cancel & Noise reduction + THREE_WAY_CALLING = 0x02 + CLI_PRESENTATION_CAPABILITY = 0x04 + VOICE_RECOGNITION_ACTIVATION = 0x08 + REMOTE_VOLUME_CONTROL = 0x10 + WIDE_BAND = 0x20 # Wide band speech + ENHANCED_VOICE_RECOGNITION_STATUS = 0x40 + VOICE_RECOGNITION_TEST = 0x80 + + +# AG supported features (normative). +# Hands-Free Profile v1.8, 5.3 SDP Interoperability Requirements +class AgSdpFeature(enum.IntFlag): + THREE_WAY_CALLING = 0x01 + EC_NR = 0x02 # Echo Cancel & Noise reduction + VOICE_RECOGNITION_FUNCTION = 0x04 + IN_BAND_RING_TONE_CAPABILITY = 0x08 + VOICE_TAG = 0x10 # Attach a number to voice tag + WIDE_BAND = 0x20 # Wide band speech + ENHANCED_VOICE_RECOGNITION_STATUS = 0x40 + VOICE_RECOGNITION_TEST = 0x80 + + +def sdp_records( + service_record_handle: int, rfcomm_channel: int, configuration: Configuration +) -> List[ServiceAttribute]: + """Generate the SDP record for HFP Hands-Free support. + The record exposes the features supported in the input configuration, + and the allocated RFCOMM channel.""" + + hf_supported_features = 0 + + if HfFeature.EC_NR in configuration.supported_hf_features: + hf_supported_features |= HfSdpFeature.EC_NR + if HfFeature.THREE_WAY_CALLING in configuration.supported_hf_features: + hf_supported_features |= HfSdpFeature.THREE_WAY_CALLING + if HfFeature.CLI_PRESENTATION_CAPABILITY in configuration.supported_hf_features: + hf_supported_features |= HfSdpFeature.CLI_PRESENTATION_CAPABILITY + if HfFeature.VOICE_RECOGNITION_ACTIVATION in configuration.supported_hf_features: + hf_supported_features |= HfSdpFeature.VOICE_RECOGNITION_ACTIVATION + if HfFeature.REMOTE_VOLUME_CONTROL in configuration.supported_hf_features: + hf_supported_features |= HfSdpFeature.REMOTE_VOLUME_CONTROL + if ( + HfFeature.ENHANCED_VOICE_RECOGNITION_STATUS + in configuration.supported_hf_features + ): + hf_supported_features |= HfSdpFeature.ENHANCED_VOICE_RECOGNITION_STATUS + if HfFeature.VOICE_RECOGNITION_TEST in configuration.supported_hf_features: + hf_supported_features |= HfSdpFeature.VOICE_RECOGNITION_TEST + + if AudioCodec.MSBC in configuration.supported_audio_codecs: + hf_supported_features |= HfSdpFeature.WIDE_BAND + + return [ + ServiceAttribute( + SDP_SERVICE_RECORD_HANDLE_ATTRIBUTE_ID, + DataElement.unsigned_integer_32(service_record_handle), + ), + ServiceAttribute( + SDP_SERVICE_CLASS_ID_LIST_ATTRIBUTE_ID, + DataElement.sequence( + [ + DataElement.uuid(BT_HANDSFREE_SERVICE), + DataElement.uuid(BT_GENERIC_AUDIO_SERVICE), + ] + ), + ), + ServiceAttribute( + SDP_PROTOCOL_DESCRIPTOR_LIST_ATTRIBUTE_ID, + DataElement.sequence( + [ + DataElement.sequence([DataElement.uuid(BT_L2CAP_PROTOCOL_ID)]), + DataElement.sequence( + [ + DataElement.uuid(BT_RFCOMM_PROTOCOL_ID), + DataElement.unsigned_integer_8(rfcomm_channel), + ] + ), + ] + ), + ), + ServiceAttribute( + SDP_BLUETOOTH_PROFILE_DESCRIPTOR_LIST_ATTRIBUTE_ID, + DataElement.sequence( + [ + DataElement.sequence( + [ + DataElement.uuid(BT_HANDSFREE_SERVICE), + DataElement.unsigned_integer_16(ProfileVersion.V1_8), + ] + ) + ] + ), + ), + ServiceAttribute( + SDP_SUPPORTED_FEATURES_ATTRIBUTE_ID, + DataElement.unsigned_integer_16(hf_supported_features), + ), + ] diff --git a/bumble/pandora/config.py b/bumble/pandora/config.py index 5edba55..fa448b8 100644 --- a/bumble/pandora/config.py +++ b/bumble/pandora/config.py @@ -12,7 +12,7 @@ # See the License for the specific language governing permissions and # limitations under the License. -from bumble.pairing import PairingDelegate +from bumble.pairing import PairingConfig, PairingDelegate from dataclasses import dataclass from typing import Any, Dict @@ -20,6 +20,7 @@ from typing import Any, Dict @dataclass class Config: io_capability: PairingDelegate.IoCapability = PairingDelegate.NO_OUTPUT_NO_INPUT + identity_address_type: PairingConfig.AddressType = PairingConfig.AddressType.RANDOM pairing_sc_enable: bool = True pairing_mitm_enable: bool = True pairing_bonding_enable: bool = True @@ -35,6 +36,12 @@ class Config: 'io_capability', 'no_output_no_input' ).upper() self.io_capability = getattr(PairingDelegate, io_capability_name) + identity_address_type_name: str = config.get( + 'identity_address_type', 'random' + ).upper() + self.identity_address_type = getattr( + PairingConfig.AddressType, identity_address_type_name + ) self.pairing_sc_enable = config.get('pairing_sc_enable', True) self.pairing_mitm_enable = config.get('pairing_mitm_enable', True) self.pairing_bonding_enable = config.get('pairing_bonding_enable', True) diff --git a/bumble/pandora/security.py b/bumble/pandora/security.py index 9f98f3f..fb6fd6f 100644 --- a/bumble/pandora/security.py +++ b/bumble/pandora/security.py @@ -232,6 +232,7 @@ class SecurityService(SecurityServicer): sc=config.pairing_sc_enable, mitm=config.pairing_mitm_enable, bonding=config.pairing_bonding_enable, + identity_address_type=config.identity_address_type, delegate=PairingDelegate( connection, self, diff --git a/bumble/sdp.py b/bumble/sdp.py index 019b8e6..1d4faf9 100644 --- a/bumble/sdp.py +++ b/bumble/sdp.py @@ -94,6 +94,10 @@ SDP_CLIENT_EXECUTABLE_URL_ATTRIBUTE_ID = 0X000B SDP_ICON_URL_ATTRIBUTE_ID = 0X000C SDP_ADDITIONAL_PROTOCOL_DESCRIPTOR_LIST_ATTRIBUTE_ID = 0X000D +# Attribute Identifier (cf. Assigned Numbers for Service Discovery) +# used by AVRCP, HFP and A2DP +SDP_SUPPORTED_FEATURES_ATTRIBUTE_ID = 0x0311 + SDP_ATTRIBUTE_ID_NAMES = { SDP_SERVICE_RECORD_HANDLE_ATTRIBUTE_ID: 'SDP_SERVICE_RECORD_HANDLE_ATTRIBUTE_ID', SDP_SERVICE_CLASS_ID_LIST_ATTRIBUTE_ID: 'SDP_SERVICE_CLASS_ID_LIST_ATTRIBUTE_ID', diff --git a/bumble/smp.py b/bumble/smp.py index c93ee9c..9588a5a 100644 --- a/bumble/smp.py +++ b/bumble/smp.py @@ -1272,7 +1272,7 @@ class Session: keys.link_key = PairingKeys.Key( value=self.link_key, authenticated=authenticated ) - self.manager.on_pairing(self, peer_address, keys) + await self.manager.on_pairing(self, peer_address, keys) def on_pairing_failure(self, reason: int) -> None: logger.warning(f'pairing failure ({error_name(reason)})') @@ -1827,20 +1827,13 @@ class Manager(EventEmitter): def on_session_start(self, session: Session) -> None: self.device.on_pairing_start(session.connection) - def on_pairing( + async def on_pairing( self, session: Session, identity_address: Optional[Address], keys: PairingKeys ) -> None: # Store the keys in the key store if self.device.keystore and identity_address is not None: - - async def store_keys(): - try: - assert self.device.keystore - await self.device.keystore.update(str(identity_address), keys) - except Exception as error: - logger.warning(f'!!! error while storing keys: {error}') - - self.device.abort_on('flush', store_keys()) + await self.device.keystore.update(str(identity_address), keys) + await self.device.refresh_resolving_list() # Notify the device self.device.on_pairing(session.connection, identity_address, keys, session.sc) diff --git a/examples/run_hfp_gateway.py b/examples/run_hfp_gateway.py index 63a2a7c..eac5473 100644 --- a/examples/run_hfp_gateway.py +++ b/examples/run_hfp_gateway.py @@ -16,9 +16,11 @@ # Imports # ----------------------------------------------------------------------------- import asyncio +import collections import sys import os import logging +from typing import Union from bumble.colors import color @@ -30,6 +32,7 @@ from bumble.core import ( BT_RFCOMM_PROTOCOL_ID, BT_BR_EDR_TRANSPORT, ) +from bumble import rfcomm from bumble.rfcomm import Client from bumble.sdp import ( Client as SDP_Client, @@ -39,7 +42,64 @@ from bumble.sdp import ( SDP_SERVICE_CLASS_ID_LIST_ATTRIBUTE_ID, SDP_BLUETOOTH_PROFILE_DESCRIPTOR_LIST_ATTRIBUTE_ID, ) -from bumble.hfp import HfpProtocol + + +logger = logging.getLogger(__name__) + + +# ----------------------------------------------------------------------------- +# Protocol Support +# ----------------------------------------------------------------------------- + +# ----------------------------------------------------------------------------- +class HfpProtocol: + dlc: rfcomm.DLC + buffer: str + lines: collections.deque + lines_available: asyncio.Event + + def __init__(self, dlc: rfcomm.DLC) -> None: + self.dlc = dlc + self.buffer = '' + self.lines = collections.deque() + self.lines_available = asyncio.Event() + + dlc.sink = self.feed + + def feed(self, data: Union[bytes, str]) -> None: + # Convert the data to a string if needed + if isinstance(data, bytes): + data = data.decode('utf-8') + + logger.debug(f'<<< Data received: {data}') + + # Add to the buffer and look for lines + self.buffer += data + while (separator := self.buffer.find('\r')) >= 0: + line = self.buffer[:separator].strip() + self.buffer = self.buffer[separator + 1 :] + if len(line) > 0: + self.on_line(line) + + def on_line(self, line: str) -> None: + self.lines.append(line) + self.lines_available.set() + + def send_command_line(self, line: str) -> None: + logger.debug(color(f'>>> {line}', 'yellow')) + self.dlc.write(line + '\r') + + def send_response_line(self, line: str) -> None: + logger.debug(color(f'>>> {line}', 'yellow')) + self.dlc.write('\r\n' + line + '\r\n') + + async def next_line(self) -> str: + await self.lines_available.wait() + line = self.lines.popleft() + if not self.lines: + self.lines_available.clear() + logger.debug(color(f'<<< {line}', 'green')) + return line # ----------------------------------------------------------------------------- diff --git a/examples/run_hfp_handsfree.py b/examples/run_hfp_handsfree.py index cef29c0..5f747fc 100644 --- a/examples/run_hfp_handsfree.py +++ b/examples/run_hfp_handsfree.py @@ -21,82 +21,22 @@ import os import logging import json import websockets - +from typing import Optional from bumble.device import Device from bumble.transport import open_transport_or_link from bumble.rfcomm import Server as RfcommServer -from bumble.sdp import ( - DataElement, - ServiceAttribute, - SDP_SERVICE_RECORD_HANDLE_ATTRIBUTE_ID, - SDP_SERVICE_CLASS_ID_LIST_ATTRIBUTE_ID, - SDP_PROTOCOL_DESCRIPTOR_LIST_ATTRIBUTE_ID, - SDP_BLUETOOTH_PROFILE_DESCRIPTOR_LIST_ATTRIBUTE_ID, -) -from bumble.core import ( - BT_GENERIC_AUDIO_SERVICE, - BT_HANDSFREE_SERVICE, - BT_L2CAP_PROTOCOL_ID, - BT_RFCOMM_PROTOCOL_ID, -) -from bumble.hfp import HfpProtocol - - -# ----------------------------------------------------------------------------- -def make_sdp_records(rfcomm_channel): - return { - 0x00010001: [ - ServiceAttribute( - SDP_SERVICE_RECORD_HANDLE_ATTRIBUTE_ID, - DataElement.unsigned_integer_32(0x00010001), - ), - ServiceAttribute( - SDP_SERVICE_CLASS_ID_LIST_ATTRIBUTE_ID, - DataElement.sequence( - [ - DataElement.uuid(BT_HANDSFREE_SERVICE), - DataElement.uuid(BT_GENERIC_AUDIO_SERVICE), - ] - ), - ), - ServiceAttribute( - SDP_PROTOCOL_DESCRIPTOR_LIST_ATTRIBUTE_ID, - DataElement.sequence( - [ - DataElement.sequence([DataElement.uuid(BT_L2CAP_PROTOCOL_ID)]), - DataElement.sequence( - [ - DataElement.uuid(BT_RFCOMM_PROTOCOL_ID), - DataElement.unsigned_integer_8(rfcomm_channel), - ] - ), - ] - ), - ), - ServiceAttribute( - SDP_BLUETOOTH_PROFILE_DESCRIPTOR_LIST_ATTRIBUTE_ID, - DataElement.sequence( - [ - DataElement.sequence( - [ - DataElement.uuid(BT_HANDSFREE_SERVICE), - DataElement.unsigned_integer_16(0x0105), - ] - ) - ] - ), - ), - ] - } +from bumble import hfp +from bumble.hfp import HfProtocol # ----------------------------------------------------------------------------- class UiServer: - protocol = None + protocol: Optional[HfProtocol] = None async def start(self): - # Start a Websocket server to receive events from a web page + """Start a Websocket server to receive events from a web page.""" + async def serve(websocket, _path): while True: try: @@ -107,7 +47,7 @@ class UiServer: message_type = parsed['type'] if message_type == 'at_command': if self.protocol is not None: - self.protocol.send_command_line(parsed['command']) + await self.protocol.execute_command(parsed['command']) except websockets.exceptions.ConnectionClosedOK: pass @@ -117,19 +57,11 @@ class UiServer: # ----------------------------------------------------------------------------- -async def protocol_loop(protocol): - await protocol.initialize_service() - - while True: - await (protocol.next_line()) - - -# ----------------------------------------------------------------------------- -def on_dlc(dlc): +def on_dlc(dlc, configuration: hfp.Configuration): print('*** DLC connected', dlc) - protocol = HfpProtocol(dlc) + protocol = HfProtocol(dlc, configuration) UiServer.protocol = protocol - asyncio.create_task(protocol_loop(protocol)) + asyncio.create_task(protocol.run()) # ----------------------------------------------------------------------------- @@ -143,6 +75,27 @@ async def main(): async with await open_transport_or_link(sys.argv[2]) as (hci_source, hci_sink): print('<<< connected') + # Hands-Free profile configuration. + # TODO: load configuration from file. + configuration = hfp.Configuration( + supported_hf_features=[ + hfp.HfFeature.THREE_WAY_CALLING, + hfp.HfFeature.REMOTE_VOLUME_CONTROL, + hfp.HfFeature.ENHANCED_CALL_STATUS, + hfp.HfFeature.ENHANCED_CALL_CONTROL, + hfp.HfFeature.CODEC_NEGOTIATION, + hfp.HfFeature.HF_INDICATORS, + hfp.HfFeature.ESCO_S4_SETTINGS_SUPPORTED, + ], + supported_hf_indicators=[ + hfp.HfIndicator.BATTERY_LEVEL, + ], + supported_audio_codecs=[ + hfp.AudioCodec.CVSD, + hfp.AudioCodec.MSBC, + ], + ) + # Create a device device = Device.from_config_file_with_hci(sys.argv[1], hci_source, hci_sink) device.classic_enabled = True @@ -151,11 +104,13 @@ async def main(): rfcomm_server = RfcommServer(device) # Listen for incoming DLC connections - channel_number = rfcomm_server.listen(on_dlc) + channel_number = rfcomm_server.listen(lambda dlc: on_dlc(dlc, configuration)) print(f'### Listening for connection on channel {channel_number}') # Advertise the HFP RFComm channel in the SDP - device.sdp_service_records = make_sdp_records(channel_number) + device.sdp_service_records = { + 0x00010001: hfp.sdp_records(0x00010001, channel_number, configuration) + } # Let's go! await device.power_on() diff --git a/rust/CHANGELOG.md b/rust/CHANGELOG.md new file mode 100644 index 0000000..2cfed4e --- /dev/null +++ b/rust/CHANGELOG.md @@ -0,0 +1,7 @@ +# Next + +- Code-gen company ID table + +# 0.1.0 + +- Initial release
\ No newline at end of file diff --git a/rust/Cargo.lock b/rust/Cargo.lock index 1492cfb..399f916 100644 --- a/rust/Cargo.lock +++ b/rust/Cargo.lock @@ -130,7 +130,7 @@ name = "bumble" version = "0.1.0" dependencies = [ "anyhow", - "clap 4.3.17", + "clap 4.3.19", "env_logger", "hex", "itertools", @@ -158,9 +158,12 @@ checksum = "89b2fd2a0dcf38d7971e2194b6b6eebab45ae01067456a7fd93d5547a61b70be" [[package]] name = "cc" -version = "1.0.79" +version = "1.0.81" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "50d30906286121d95be3d479533b458f87493b30a4b5f79a607db8f5d11aa91f" +checksum = "6c6b2562119bf28c3439f7f02db99faf0aa1a8cdfe5772a2ee155d32227239f0" +dependencies = [ + "libc", +] [[package]] name = "cfg-if" @@ -185,9 +188,9 @@ dependencies = [ [[package]] name = "clap" -version = "4.3.17" +version = "4.3.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5b0827b011f6f8ab38590295339817b0d26f344aa4932c3ced71b45b0c54b4a9" +checksum = "5fd304a20bff958a57f04c4e96a2e7594cc4490a0e809cbd48bb6437edaa452d" dependencies = [ "clap_builder", "clap_derive", @@ -196,9 +199,9 @@ dependencies = [ [[package]] name = "clap_builder" -version = "4.3.17" +version = "4.3.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9441b403be87be858db6a23edb493e7f694761acdc3343d5a0fcaafd304cbc9e" +checksum = "01c6a3f08f1fe5662a35cfe393aec09c4df95f60ee93b7556505260f75eee9e1" dependencies = [ "anstream", "anstyle", @@ -215,7 +218,7 @@ dependencies = [ "heck", "proc-macro2", "quote", - "syn 2.0.26", + "syn 2.0.28", ] [[package]] @@ -241,9 +244,9 @@ checksum = "acbf1af155f9b9ef647e42cdc158db4b64a1b61f743629225fde6f3e0be2a7c7" [[package]] name = "either" -version = "1.8.1" +version = "1.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7fcaabb2fef8c910e7f4c7ce9f67a1283a1715879a7c230ca9d6d1ae31f16d91" +checksum = "a26ae43d7bcc3b814de94796a5e736d4029efb0ee900c12e2d54c993ad1a1e07" [[package]] name = "env_logger" @@ -260,9 +263,9 @@ dependencies = [ [[package]] name = "errno" -version = "0.3.1" +version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4bcfec3a70f97c962c307b2d2c56e358cf1d00b558d74262b5f929ee8cc7e73a" +checksum = "6b30f669a7961ef1631673d2766cc92f52d64f7ef354d4fe0ddfd30ed52f0f4f" dependencies = [ "errno-dragonfly", "libc", @@ -281,12 +284,9 @@ dependencies = [ [[package]] name = "fastrand" -version = "1.9.0" +version = "2.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e51093e27b0797c359783294ca4f0a911c270184cb10f85783b118614a1501be" -dependencies = [ - "instant", -] +checksum = "6999dc1837253364c2ebb0704ba97994bd874e8f195d665c50b7548f6ea92764" [[package]] name = "futures" @@ -344,7 +344,7 @@ checksum = "89ca545a94061b6365f2c7355b4b32bd20df3ff95f02da9329b34ccc3bd6ee72" dependencies = [ "proc-macro2", "quote", - "syn 2.0.26", + "syn 2.0.28", ] [[package]] @@ -450,30 +450,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bfa799dd5ed20a7e349f3b4639aa80d74549c81716d9ec4f994c9b5815598306" [[package]] -name = "instant" -version = "0.1.12" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7a5bbe824c507c5da5956355e86a746d82e0e1464f65d862cc5e71da70e94b2c" -dependencies = [ - "cfg-if", -] - -[[package]] name = "inventory" -version = "0.3.9" +version = "0.3.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "25b1d6b4b9fb75fc419bdef998b689df5080a32931cb3395b86202046b56a9ea" - -[[package]] -name = "io-lifetimes" -version = "1.0.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eae7b9aee968036d54dce06cebaefd919e4472e753296daccd6d344e3e2df0c2" -dependencies = [ - "hermit-abi 0.3.2", - "libc", - "windows-sys", -] +checksum = "a53088c87cf71c9d4f3372a2cb9eea1e7b8a0b1bf8b7f7d23fe5b76dbb07e63b" [[package]] name = "is-terminal" @@ -482,7 +462,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cb0889898416213fab133e1d33a0e5858a48177452750691bde3666d0fdbaf8b" dependencies = [ "hermit-abi 0.3.2", - "rustix 0.38.4", + "rustix", "windows-sys", ] @@ -521,15 +501,9 @@ dependencies = [ [[package]] name = "linux-raw-sys" -version = "0.3.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ef53942eb7bf7ff43a617b3e2c1c4a5ecf5944a7c1bc12d7ee39bbb15e5c1519" - -[[package]] -name = "linux-raw-sys" -version = "0.4.3" +version = "0.4.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "09fc20d2ca12cb9f044c93e3bd6d32d523e6e2ec3db4f7b2939cd99026ecd3f0" +checksum = "57bcfdad1b858c2db7c38303a6d2ad4dfaf5eb53dfeb0910128b2c26d6158503" [[package]] name = "lock_api" @@ -804,9 +778,9 @@ dependencies = [ [[package]] name = "quote" -version = "1.0.31" +version = "1.0.32" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5fe8a65d69dd0808184ebb5f836ab526bb259db23c657efa38711b1072ee47f0" +checksum = "50f3b39ccfb720540debaa0164757101c08ecb8d326b15358ce76a62c7e85965" dependencies = [ "proc-macro2", ] @@ -864,9 +838,9 @@ dependencies = [ [[package]] name = "regex-automata" -version = "0.3.3" +version = "0.3.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "39354c10dd07468c2e73926b23bb9c2caca74c5501e38a35da70406f1d923310" +checksum = "b7b6d6190b7594385f61bd3911cd1be99dfddcfc365a4160cc2ab5bff4aed294" dependencies = [ "aho-corasick", "memchr", @@ -897,28 +871,14 @@ checksum = "d626bb9dae77e28219937af045c257c28bfd3f69333c512553507f5f9798cb76" [[package]] name = "rustix" -version = "0.37.23" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4d69718bf81c6127a49dc64e44a742e8bb9213c0ff8869a22c308f84c1d4ab06" -dependencies = [ - "bitflags 1.3.2", - "errno", - "io-lifetimes", - "libc", - "linux-raw-sys 0.3.8", - "windows-sys", -] - -[[package]] -name = "rustix" -version = "0.38.4" +version = "0.38.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0a962918ea88d644592894bc6dc55acc6c0956488adcebbfb6e273506b7fd6e5" +checksum = "1ee020b1716f0a80e2ace9b03441a749e402e86712f15f16fe8a8f75afac732f" dependencies = [ "bitflags 2.3.3", "errno", "libc", - "linux-raw-sys 0.4.3", + "linux-raw-sys", "windows-sys", ] @@ -996,7 +956,7 @@ dependencies = [ "proc-macro2", "quote", "rustversion", - "syn 2.0.26", + "syn 2.0.28", ] [[package]] @@ -1012,9 +972,9 @@ dependencies = [ [[package]] name = "syn" -version = "2.0.26" +version = "2.0.28" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "45c3457aacde3c65315de5031ec191ce46604304d2446e803d71ade03308d970" +checksum = "04361975b3f5e348b2189d8dc55bc942f278b2d482a6a0365de5bdd62d351567" dependencies = [ "proc-macro2", "quote", @@ -1023,21 +983,20 @@ dependencies = [ [[package]] name = "target-lexicon" -version = "0.12.10" +version = "0.12.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1d2faeef5759ab89935255b1a4cd98e0baf99d1085e37d36599c625dac49ae8e" +checksum = "9d0e916b1148c8e263850e1ebcbd046f333e0683c724876bb0da63ea4373dc8a" [[package]] name = "tempfile" -version = "3.6.0" +version = "3.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "31c0432476357e58790aaa47a8efb0c5138f137343f3b5f23bd36a27e3b0a6d6" +checksum = "5486094ee78b2e5038a6382ed7645bc084dc2ec433426ca4c3cb61e2007b8998" dependencies = [ - "autocfg", "cfg-if", "fastrand", "redox_syscall", - "rustix 0.37.23", + "rustix", "windows-sys", ] @@ -1058,22 +1017,22 @@ checksum = "222a222a5bfe1bba4a77b45ec488a741b3cb8872e5e499451fd7d0129c9c7c3d" [[package]] name = "thiserror" -version = "1.0.43" +version = "1.0.44" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a35fc5b8971143ca348fa6df4f024d4d55264f3468c71ad1c2f365b0a4d58c42" +checksum = "611040a08a0439f8248d1990b111c95baa9c704c805fa1f62104b39655fd7f90" dependencies = [ "thiserror-impl", ] [[package]] name = "thiserror-impl" -version = "1.0.43" +version = "1.0.44" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "463fe12d7993d3b327787537ce8dd4dfa058de32fc2b195ef3cde03dc4771e8f" +checksum = "090198534930841fab3a5d1bb637cde49e339654e606195f8d9c76eeb081dc96" dependencies = [ "proc-macro2", "quote", - "syn 2.0.26", + "syn 2.0.28", ] [[package]] @@ -1104,7 +1063,7 @@ checksum = "630bdcf245f78637c13ec01ffae6187cca34625e8c63150d424b59e55af2675e" dependencies = [ "proc-macro2", "quote", - "syn 2.0.26", + "syn 2.0.28", ] [[package]] diff --git a/rust/Cargo.toml b/rust/Cargo.toml index 8b7c723..523074c 100644 --- a/rust/Cargo.toml +++ b/rust/Cargo.toml @@ -23,6 +23,7 @@ hex = "0.4.3" itertools = "0.11.0" lazy_static = "1.4.0" thiserror = "1.0.41" +anyhow = { version = "1.0.71", optional = true } [dev-dependencies] tokio = { version = "1.28.2", features = ["full"] } @@ -38,6 +39,11 @@ env_logger = "0.10.0" rusb = "0.9.2" rand = "0.8.5" +[[bin]] +name = "gen-assigned-numbers" +path = "tools/gen_assigned_numbers.rs" +required-features = ["bumble-dev-tools"] + # test entry point that uses pyo3_asyncio's test harness [[test]] name = "pytests" @@ -46,4 +52,5 @@ harness = false [features] anyhow = ["pyo3/anyhow"] -pyo3-asyncio-attributes = ["pyo3-asyncio/attributes"]
\ No newline at end of file +pyo3-asyncio-attributes = ["pyo3-asyncio/attributes"] +bumble-dev-tools = ["dep:anyhow"]
\ No newline at end of file diff --git a/rust/README.md b/rust/README.md index fd591c7..2684875 100644 --- a/rust/README.md +++ b/rust/README.md @@ -39,4 +39,18 @@ Check lints: ``` cargo clippy --all-targets +``` + +## Code gen + +To have the fastest startup while keeping the build simple, code gen for +assigned numbers is done with the `gen_assigned_numbers` tool. It should +be re-run whenever the Python assigned numbers are changed. To ensure that the +generated code is kept up to date, the Rust data is compared to the Python +in tests at `pytests/assigned_numbers.rs`. + +To regenerate the assigned number tables based on the Python codebase: + +``` +PYTHONPATH=.. cargo run --bin gen-assigned-numbers --features bumble-dev-tools ```
\ No newline at end of file diff --git a/rust/pytests/assigned_numbers.rs b/rust/pytests/assigned_numbers.rs new file mode 100644 index 0000000..10e7f3e --- /dev/null +++ b/rust/pytests/assigned_numbers.rs @@ -0,0 +1,30 @@ +use bumble::wrapper::{self, core::Uuid16}; +use pyo3::{intern, prelude::*, types::PyDict}; +use std::collections; + +#[pyo3_asyncio::tokio::test] +async fn company_ids_matches_python() -> PyResult<()> { + let ids_from_python = Python::with_gil(|py| { + PyModule::import(py, intern!(py, "bumble.company_ids"))? + .getattr(intern!(py, "COMPANY_IDENTIFIERS"))? + .downcast::<PyDict>()? + .into_iter() + .map(|(k, v)| { + Ok(( + Uuid16::from_be_bytes(k.extract::<u16>()?.to_be_bytes()), + v.str()?.to_str()?.to_string(), + )) + }) + .collect::<PyResult<collections::HashMap<_, _>>>() + })?; + + assert_eq!( + wrapper::assigned_numbers::COMPANY_IDS + .iter() + .map(|(id, name)| (*id, name.to_string())) + .collect::<collections::HashMap<_, _>>(), + ids_from_python, + "Company ids do not match -- re-run gen_assigned_numbers?" + ); + Ok(()) +} diff --git a/rust/pytests/pytests.rs b/rust/pytests/pytests.rs index da331f3..4a30e8d 100644 --- a/rust/pytests/pytests.rs +++ b/rust/pytests/pytests.rs @@ -17,4 +17,5 @@ async fn main() -> pyo3::PyResult<()> { pyo3_asyncio::testing::main().await } +mod assigned_numbers; mod wrapper; diff --git a/rust/pytests/wrapper.rs b/rust/pytests/wrapper.rs index 1c1f9d0..333005b 100644 --- a/rust/pytests/wrapper.rs +++ b/rust/pytests/wrapper.rs @@ -12,9 +12,9 @@ // See the License for the specific language governing permissions and // limitations under the License. -use bumble::{wrapper, wrapper::transport::Transport}; +use bumble::wrapper::transport::Transport; use nix::sys::stat::Mode; -use pyo3::prelude::*; +use pyo3::PyResult; #[pyo3_asyncio::tokio::test] async fn fifo_transport_can_open() -> PyResult<()> { @@ -29,9 +29,3 @@ async fn fifo_transport_can_open() -> PyResult<()> { Ok(()) } - -#[pyo3_asyncio::tokio::test] -async fn company_ids() -> PyResult<()> { - assert!(wrapper::assigned_numbers::COMPANY_IDS.len() > 2000); - Ok(()) -} diff --git a/rust/src/wrapper/assigned_numbers/company_ids.rs b/rust/src/wrapper/assigned_numbers/company_ids.rs new file mode 100644 index 0000000..2eebcd5 --- /dev/null +++ b/rust/src/wrapper/assigned_numbers/company_ids.rs @@ -0,0 +1,2715 @@ +// Copyright 2023 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 +// +// http://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. + +// auto-generated by gen_assigned_numbers, do not edit + +use crate::wrapper::core::Uuid16; +use lazy_static::lazy_static; +use std::collections; + +lazy_static! { + /// Assigned company IDs + pub static ref COMPANY_IDS: collections::HashMap<Uuid16, &'static str> = [ + (0_u16, r#"Ericsson Technology Licensing"#), + (1_u16, r#"Nokia Mobile Phones"#), + (2_u16, r#"Intel Corp."#), + (3_u16, r#"IBM Corp."#), + (4_u16, r#"Toshiba Corp."#), + (5_u16, r#"3Com"#), + (6_u16, r#"Microsoft"#), + (7_u16, r#"Lucent"#), + (8_u16, r#"Motorola"#), + (9_u16, r#"Infineon Technologies AG"#), + (10_u16, r#"Qualcomm Technologies International, Ltd. (QTIL)"#), + (11_u16, r#"Silicon Wave"#), + (12_u16, r#"Digianswer A/S"#), + (13_u16, r#"Texas Instruments Inc."#), + (14_u16, r#"Parthus Technologies Inc."#), + (15_u16, r#"Broadcom Corporation"#), + (16_u16, r#"Mitel Semiconductor"#), + (17_u16, r#"Widcomm, Inc."#), + (18_u16, r#"Zeevo, Inc."#), + (19_u16, r#"Atmel Corporation"#), + (20_u16, r#"Mitsubishi Electric Corporation"#), + (21_u16, r#"RTX Telecom A/S"#), + (22_u16, r#"KC Technology Inc."#), + (23_u16, r#"Newlogic"#), + (24_u16, r#"Transilica, Inc."#), + (25_u16, r#"Rohde & Schwarz GmbH & Co. KG"#), + (26_u16, r#"TTPCom Limited"#), + (27_u16, r#"Signia Technologies, Inc."#), + (28_u16, r#"Conexant Systems Inc."#), + (29_u16, r#"Qualcomm"#), + (30_u16, r#"Inventel"#), + (31_u16, r#"AVM Berlin"#), + (32_u16, r#"BandSpeed, Inc."#), + (33_u16, r#"Mansella Ltd"#), + (34_u16, r#"NEC Corporation"#), + (35_u16, r#"WavePlus Technology Co., Ltd."#), + (36_u16, r#"Alcatel"#), + (37_u16, r#"NXP Semiconductors (formerly Philips Semiconductors)"#), + (38_u16, r#"C Technologies"#), + (39_u16, r#"Open Interface"#), + (40_u16, r#"R F Micro Devices"#), + (41_u16, r#"Hitachi Ltd"#), + (42_u16, r#"Symbol Technologies, Inc."#), + (43_u16, r#"Tenovis"#), + (44_u16, r#"Macronix International Co. Ltd."#), + (45_u16, r#"GCT Semiconductor"#), + (46_u16, r#"Norwood Systems"#), + (47_u16, r#"MewTel Technology Inc."#), + (48_u16, r#"ST Microelectronics"#), + (49_u16, r#"Synopsys, Inc."#), + (50_u16, r#"Red-M (Communications) Ltd"#), + (51_u16, r#"Commil Ltd"#), + (52_u16, r#"Computer Access Technology Corporation (CATC)"#), + (53_u16, r#"Eclipse (HQ Espana) S.L."#), + (54_u16, r#"Renesas Electronics Corporation"#), + (55_u16, r#"Mobilian Corporation"#), + (56_u16, r#"Syntronix Corporation"#), + (57_u16, r#"Integrated System Solution Corp."#), + (58_u16, r#"Panasonic Corporation (formerly Matsushita Electric Industrial Co., Ltd.)"#), + (59_u16, r#"Gennum Corporation"#), + (60_u16, r#"BlackBerry Limited (formerly Research In Motion)"#), + (61_u16, r#"IPextreme, Inc."#), + (62_u16, r#"Systems and Chips, Inc"#), + (63_u16, r#"Bluetooth SIG, Inc"#), + (64_u16, r#"Seiko Epson Corporation"#), + (65_u16, r#"Integrated Silicon Solution Taiwan, Inc."#), + (66_u16, r#"CONWISE Technology Corporation Ltd"#), + (67_u16, r#"PARROT AUTOMOTIVE SAS"#), + (68_u16, r#"Socket Mobile"#), + (69_u16, r#"Atheros Communications, Inc."#), + (70_u16, r#"MediaTek, Inc."#), + (71_u16, r#"Bluegiga"#), + (72_u16, r#"Marvell Technology Group Ltd."#), + (73_u16, r#"3DSP Corporation"#), + (74_u16, r#"Accel Semiconductor Ltd."#), + (75_u16, r#"Continental Automotive Systems"#), + (76_u16, r#"Apple, Inc."#), + (77_u16, r#"Staccato Communications, Inc."#), + (78_u16, r#"Avago Technologies"#), + (79_u16, r#"APT Ltd."#), + (80_u16, r#"SiRF Technology, Inc."#), + (81_u16, r#"Tzero Technologies, Inc."#), + (82_u16, r#"J&M Corporation"#), + (83_u16, r#"Free2move AB"#), + (84_u16, r#"3DiJoy Corporation"#), + (85_u16, r#"Plantronics, Inc."#), + (86_u16, r#"Sony Ericsson Mobile Communications"#), + (87_u16, r#"Harman International Industries, Inc."#), + (88_u16, r#"Vizio, Inc."#), + (89_u16, r#"Nordic Semiconductor ASA"#), + (90_u16, r#"EM Microelectronic-Marin SA"#), + (91_u16, r#"Ralink Technology Corporation"#), + (92_u16, r#"Belkin International, Inc."#), + (93_u16, r#"Realtek Semiconductor Corporation"#), + (94_u16, r#"Stonestreet One, LLC"#), + (95_u16, r#"Wicentric, Inc."#), + (96_u16, r#"RivieraWaves S.A.S"#), + (97_u16, r#"RDA Microelectronics"#), + (98_u16, r#"Gibson Guitars"#), + (99_u16, r#"MiCommand Inc."#), + (100_u16, r#"Band XI International, LLC"#), + (101_u16, r#"Hewlett-Packard Company"#), + (102_u16, r#"9Solutions Oy"#), + (103_u16, r#"GN Netcom A/S"#), + (104_u16, r#"General Motors"#), + (105_u16, r#"A&D Engineering, Inc."#), + (106_u16, r#"MindTree Ltd."#), + (107_u16, r#"Polar Electro OY"#), + (108_u16, r#"Beautiful Enterprise Co., Ltd."#), + (109_u16, r#"BriarTek, Inc"#), + (110_u16, r#"Summit Data Communications, Inc."#), + (111_u16, r#"Sound ID"#), + (112_u16, r#"Monster, LLC"#), + (113_u16, r#"connectBlue AB"#), + (114_u16, r#"ShangHai Super Smart Electronics Co. Ltd."#), + (115_u16, r#"Group Sense Ltd."#), + (116_u16, r#"Zomm, LLC"#), + (117_u16, r#"Samsung Electronics Co. Ltd."#), + (118_u16, r#"Creative Technology Ltd."#), + (119_u16, r#"Laird Technologies"#), + (120_u16, r#"Nike, Inc."#), + (121_u16, r#"lesswire AG"#), + (122_u16, r#"MStar Semiconductor, Inc."#), + (123_u16, r#"Hanlynn Technologies"#), + (124_u16, r#"A & R Cambridge"#), + (125_u16, r#"Seers Technology Co., Ltd."#), + (126_u16, r#"Sports Tracking Technologies Ltd."#), + (127_u16, r#"Autonet Mobile"#), + (128_u16, r#"DeLorme Publishing Company, Inc."#), + (129_u16, r#"WuXi Vimicro"#), + (130_u16, r#"Sennheiser Communications A/S"#), + (131_u16, r#"TimeKeeping Systems, Inc."#), + (132_u16, r#"Ludus Helsinki Ltd."#), + (133_u16, r#"BlueRadios, Inc."#), + (134_u16, r#"Equinux AG"#), + (135_u16, r#"Garmin International, Inc."#), + (136_u16, r#"Ecotest"#), + (137_u16, r#"GN ReSound A/S"#), + (138_u16, r#"Jawbone"#), + (139_u16, r#"Topcon Positioning Systems, LLC"#), + (140_u16, r#"Gimbal Inc. (formerly Qualcomm Labs, Inc. and Qualcomm Retail Solutions, Inc.)"#), + (141_u16, r#"Zscan Software"#), + (142_u16, r#"Quintic Corp"#), + (143_u16, r#"Telit Wireless Solutions GmbH (formerly Stollmann E+V GmbH)"#), + (144_u16, r#"Funai Electric Co., Ltd."#), + (145_u16, r#"Advanced PANMOBIL systems GmbH & Co. KG"#), + (146_u16, r#"ThinkOptics, Inc."#), + (147_u16, r#"Universal Electronics, Inc."#), + (148_u16, r#"Airoha Technology Corp."#), + (149_u16, r#"NEC Lighting, Ltd."#), + (150_u16, r#"ODM Technology, Inc."#), + (151_u16, r#"ConnecteDevice Ltd."#), + (152_u16, r#"zero1.tv GmbH"#), + (153_u16, r#"i.Tech Dynamic Global Distribution Ltd."#), + (154_u16, r#"Alpwise"#), + (155_u16, r#"Jiangsu Toppower Automotive Electronics Co., Ltd."#), + (156_u16, r#"Colorfy, Inc."#), + (157_u16, r#"Geoforce Inc."#), + (158_u16, r#"Bose Corporation"#), + (159_u16, r#"Suunto Oy"#), + (160_u16, r#"Kensington Computer Products Group"#), + (161_u16, r#"SR-Medizinelektronik"#), + (162_u16, r#"Vertu Corporation Limited"#), + (163_u16, r#"Meta Watch Ltd."#), + (164_u16, r#"LINAK A/S"#), + (165_u16, r#"OTL Dynamics LLC"#), + (166_u16, r#"Panda Ocean Inc."#), + (167_u16, r#"Visteon Corporation"#), + (168_u16, r#"ARP Devices Limited"#), + (169_u16, r#"MARELLI EUROPE S.P.A. (formerly Magneti Marelli S.p.A.)"#), + (170_u16, r#"CAEN RFID srl"#), + (171_u16, r#"Ingenieur-Systemgruppe Zahn GmbH"#), + (172_u16, r#"Green Throttle Games"#), + (173_u16, r#"Peter Systemtechnik GmbH"#), + (174_u16, r#"Omegawave Oy"#), + (175_u16, r#"Cinetix"#), + (176_u16, r#"Passif Semiconductor Corp"#), + (177_u16, r#"Saris Cycling Group, Inc"#), + (178_u16, r#"Bekey A/S"#), + (179_u16, r#"Clarinox Technologies Pty. Ltd."#), + (180_u16, r#"BDE Technology Co., Ltd."#), + (181_u16, r#"Swirl Networks"#), + (182_u16, r#"Meso international"#), + (183_u16, r#"TreLab Ltd"#), + (184_u16, r#"Qualcomm Innovation Center, Inc. (QuIC)"#), + (185_u16, r#"Johnson Controls, Inc."#), + (186_u16, r#"Starkey Laboratories Inc."#), + (187_u16, r#"S-Power Electronics Limited"#), + (188_u16, r#"Ace Sensor Inc"#), + (189_u16, r#"Aplix Corporation"#), + (190_u16, r#"AAMP of America"#), + (191_u16, r#"Stalmart Technology Limited"#), + (192_u16, r#"AMICCOM Electronics Corporation"#), + (193_u16, r#"Shenzhen Excelsecu Data Technology Co.,Ltd"#), + (194_u16, r#"Geneq Inc."#), + (195_u16, r#"adidas AG"#), + (196_u16, r#"LG Electronics"#), + (197_u16, r#"Onset Computer Corporation"#), + (198_u16, r#"Selfly BV"#), + (199_u16, r#"Quuppa Oy."#), + (200_u16, r#"GeLo Inc"#), + (201_u16, r#"Evluma"#), + (202_u16, r#"MC10"#), + (203_u16, r#"Binauric SE"#), + (204_u16, r#"Beats Electronics"#), + (205_u16, r#"Microchip Technology Inc."#), + (206_u16, r#"Elgato Systems GmbH"#), + (207_u16, r#"ARCHOS SA"#), + (208_u16, r#"Dexcom, Inc."#), + (209_u16, r#"Polar Electro Europe B.V."#), + (210_u16, r#"Dialog Semiconductor B.V."#), + (211_u16, r#"Taixingbang Technology (HK) Co,. LTD."#), + (212_u16, r#"Kawantech"#), + (213_u16, r#"Austco Communication Systems"#), + (214_u16, r#"Timex Group USA, Inc."#), + (215_u16, r#"Qualcomm Technologies, Inc."#), + (216_u16, r#"Qualcomm Connected Experiences, Inc."#), + (217_u16, r#"Voyetra Turtle Beach"#), + (218_u16, r#"txtr GmbH"#), + (219_u16, r#"Biosentronics"#), + (220_u16, r#"Procter & Gamble"#), + (221_u16, r#"Hosiden Corporation"#), + (222_u16, r#"Muzik LLC"#), + (223_u16, r#"Misfit Wearables Corp"#), + (224_u16, r#"Google"#), + (225_u16, r#"Danlers Ltd"#), + (226_u16, r#"Semilink Inc"#), + (227_u16, r#"inMusic Brands, Inc"#), + (228_u16, r#"Laird Connectivity, Inc. formerly L.S. Research Inc."#), + (229_u16, r#"Eden Software Consultants Ltd."#), + (230_u16, r#"Freshtemp"#), + (231_u16, r#"KS Technologies"#), + (232_u16, r#"ACTS Technologies"#), + (233_u16, r#"Vtrack Systems"#), + (234_u16, r#"Nielsen-Kellerman Company"#), + (235_u16, r#"Server Technology Inc."#), + (236_u16, r#"BioResearch Associates"#), + (237_u16, r#"Jolly Logic, LLC"#), + (238_u16, r#"Above Average Outcomes, Inc."#), + (239_u16, r#"Bitsplitters GmbH"#), + (240_u16, r#"PayPal, Inc."#), + (241_u16, r#"Witron Technology Limited"#), + (242_u16, r#"Morse Project Inc."#), + (243_u16, r#"Kent Displays Inc."#), + (244_u16, r#"Nautilus Inc."#), + (245_u16, r#"Smartifier Oy"#), + (246_u16, r#"Elcometer Limited"#), + (247_u16, r#"VSN Technologies, Inc."#), + (248_u16, r#"AceUni Corp., Ltd."#), + (249_u16, r#"StickNFind"#), + (250_u16, r#"Crystal Code AB"#), + (251_u16, r#"KOUKAAM a.s."#), + (252_u16, r#"Delphi Corporation"#), + (253_u16, r#"ValenceTech Limited"#), + (254_u16, r#"Stanley Black and Decker"#), + (255_u16, r#"Typo Products, LLC"#), + (256_u16, r#"TomTom International BV"#), + (257_u16, r#"Fugoo, Inc."#), + (258_u16, r#"Keiser Corporation"#), + (259_u16, r#"Bang & Olufsen A/S"#), + (260_u16, r#"PLUS Location Systems Pty Ltd"#), + (261_u16, r#"Ubiquitous Computing Technology Corporation"#), + (262_u16, r#"Innovative Yachtter Solutions"#), + (263_u16, r#"William Demant Holding A/S"#), + (264_u16, r#"Chicony Electronics Co., Ltd."#), + (265_u16, r#"Atus BV"#), + (266_u16, r#"Codegate Ltd"#), + (267_u16, r#"ERi, Inc"#), + (268_u16, r#"Transducers Direct, LLC"#), + (269_u16, r#"DENSO TEN LIMITED (formerly Fujitsu Ten LImited)"#), + (270_u16, r#"Audi AG"#), + (271_u16, r#"HiSilicon Technologies CO., LIMITED"#), + (272_u16, r#"Nippon Seiki Co., Ltd."#), + (273_u16, r#"Steelseries ApS"#), + (274_u16, r#"Visybl Inc."#), + (275_u16, r#"Openbrain Technologies, Co., Ltd."#), + (276_u16, r#"Xensr"#), + (277_u16, r#"e.solutions"#), + (278_u16, r#"10AK Technologies"#), + (279_u16, r#"Wimoto Technologies Inc"#), + (280_u16, r#"Radius Networks, Inc."#), + (281_u16, r#"Wize Technology Co., Ltd."#), + (282_u16, r#"Qualcomm Labs, Inc."#), + (283_u16, r#"Hewlett Packard Enterprise"#), + (284_u16, r#"Baidu"#), + (285_u16, r#"Arendi AG"#), + (286_u16, r#"Skoda Auto a.s."#), + (287_u16, r#"Volkswagen AG"#), + (288_u16, r#"Porsche AG"#), + (289_u16, r#"Sino Wealth Electronic Ltd."#), + (290_u16, r#"AirTurn, Inc."#), + (291_u16, r#"Kinsa, Inc"#), + (292_u16, r#"HID Global"#), + (293_u16, r#"SEAT es"#), + (294_u16, r#"Promethean Ltd."#), + (295_u16, r#"Salutica Allied Solutions"#), + (296_u16, r#"GPSI Group Pty Ltd"#), + (297_u16, r#"Nimble Devices Oy"#), + (298_u16, r#"Changzhou Yongse Infotech Co., Ltd."#), + (299_u16, r#"SportIQ"#), + (300_u16, r#"TEMEC Instruments B.V."#), + (301_u16, r#"Sony Corporation"#), + (302_u16, r#"ASSA ABLOY"#), + (303_u16, r#"Clarion Co. Inc."#), + (304_u16, r#"Warehouse Innovations"#), + (305_u16, r#"Cypress Semiconductor"#), + (306_u16, r#"MADS Inc"#), + (307_u16, r#"Blue Maestro Limited"#), + (308_u16, r#"Resolution Products, Ltd."#), + (309_u16, r#"Aireware LLC"#), + (310_u16, r#"Silvair, Inc."#), + (311_u16, r#"Prestigio Plaza Ltd."#), + (312_u16, r#"NTEO Inc."#), + (313_u16, r#"Focus Systems Corporation"#), + (314_u16, r#"Tencent Holdings Ltd."#), + (315_u16, r#"Allegion"#), + (316_u16, r#"Murata Manufacturing Co., Ltd."#), + (317_u16, r#"WirelessWERX"#), + (318_u16, r#"Nod, Inc."#), + (319_u16, r#"B&B Manufacturing Company"#), + (320_u16, r#"Alpine Electronics (China) Co., Ltd"#), + (321_u16, r#"FedEx Services"#), + (322_u16, r#"Grape Systems Inc."#), + (323_u16, r#"Bkon Connect"#), + (324_u16, r#"Lintech GmbH"#), + (325_u16, r#"Novatel Wireless"#), + (326_u16, r#"Ciright"#), + (327_u16, r#"Mighty Cast, Inc."#), + (328_u16, r#"Ambimat Electronics"#), + (329_u16, r#"Perytons Ltd."#), + (330_u16, r#"Tivoli Audio, LLC"#), + (331_u16, r#"Master Lock"#), + (332_u16, r#"Mesh-Net Ltd"#), + (333_u16, r#"HUIZHOU DESAY SV AUTOMOTIVE CO., LTD."#), + (334_u16, r#"Tangerine, Inc."#), + (335_u16, r#"B&W Group Ltd."#), + (336_u16, r#"Pioneer Corporation"#), + (337_u16, r#"OnBeep"#), + (338_u16, r#"Vernier Software & Technology"#), + (339_u16, r#"ROL Ergo"#), + (340_u16, r#"Pebble Technology"#), + (341_u16, r#"NETATMO"#), + (342_u16, r#"Accumulate AB"#), + (343_u16, r#"Anhui Huami Information Technology Co., Ltd."#), + (344_u16, r#"Inmite s.r.o."#), + (345_u16, r#"ChefSteps, Inc."#), + (346_u16, r#"micas AG"#), + (347_u16, r#"Biomedical Research Ltd."#), + (348_u16, r#"Pitius Tec S.L."#), + (349_u16, r#"Estimote, Inc."#), + (350_u16, r#"Unikey Technologies, Inc."#), + (351_u16, r#"Timer Cap Co."#), + (352_u16, r#"Awox formerly AwoX"#), + (353_u16, r#"yikes"#), + (354_u16, r#"MADSGlobalNZ Ltd."#), + (355_u16, r#"PCH International"#), + (356_u16, r#"Qingdao Yeelink Information Technology Co., Ltd."#), + (357_u16, r#"Milwaukee Tool (Formally Milwaukee Electric Tools)"#), + (358_u16, r#"MISHIK Pte Ltd"#), + (359_u16, r#"Ascensia Diabetes Care US Inc."#), + (360_u16, r#"Spicebox LLC"#), + (361_u16, r#"emberlight"#), + (362_u16, r#"Cooper-Atkins Corporation"#), + (363_u16, r#"Qblinks"#), + (364_u16, r#"MYSPHERA"#), + (365_u16, r#"LifeScan Inc"#), + (366_u16, r#"Volantic AB"#), + (367_u16, r#"Podo Labs, Inc"#), + (368_u16, r#"Roche Diabetes Care AG"#), + (369_u16, r#"Amazon.com Services, LLC (formerly Amazon Fulfillment Service)"#), + (370_u16, r#"Connovate Technology Private Limited"#), + (371_u16, r#"Kocomojo, LLC"#), + (372_u16, r#"Everykey Inc."#), + (373_u16, r#"Dynamic Controls"#), + (374_u16, r#"SentriLock"#), + (375_u16, r#"I-SYST inc."#), + (376_u16, r#"CASIO COMPUTER CO., LTD."#), + (377_u16, r#"LAPIS Technology Co., Ltd. formerly LAPIS Semiconductor Co., Ltd."#), + (378_u16, r#"Telemonitor, Inc."#), + (379_u16, r#"taskit GmbH"#), + (380_u16, r#"Daimler AG"#), + (381_u16, r#"BatAndCat"#), + (382_u16, r#"BluDotz Ltd"#), + (383_u16, r#"XTel Wireless ApS"#), + (384_u16, r#"Gigaset Communications GmbH"#), + (385_u16, r#"Gecko Health Innovations, Inc."#), + (386_u16, r#"HOP Ubiquitous"#), + (387_u16, r#"Walt Disney"#), + (388_u16, r#"Nectar"#), + (389_u16, r#"bel'apps LLC"#), + (390_u16, r#"CORE Lighting Ltd"#), + (391_u16, r#"Seraphim Sense Ltd"#), + (392_u16, r#"Unico RBC"#), + (393_u16, r#"Physical Enterprises Inc."#), + (394_u16, r#"Able Trend Technology Limited"#), + (395_u16, r#"Konica Minolta, Inc."#), + (396_u16, r#"Wilo SE"#), + (397_u16, r#"Extron Design Services"#), + (398_u16, r#"Fitbit, Inc."#), + (399_u16, r#"Fireflies Systems"#), + (400_u16, r#"Intelletto Technologies Inc."#), + (401_u16, r#"FDK CORPORATION"#), + (402_u16, r#"Cloudleaf, Inc"#), + (403_u16, r#"Maveric Automation LLC"#), + (404_u16, r#"Acoustic Stream Corporation"#), + (405_u16, r#"Zuli"#), + (406_u16, r#"Paxton Access Ltd"#), + (407_u16, r#"WiSilica Inc."#), + (408_u16, r#"VENGIT Korlatolt Felelossegu Tarsasag"#), + (409_u16, r#"SALTO SYSTEMS S.L."#), + (410_u16, r#"TRON Forum (formerly T-Engine Forum)"#), + (411_u16, r#"CUBETECH s.r.o."#), + (412_u16, r#"Cokiya Incorporated"#), + (413_u16, r#"CVS Health"#), + (414_u16, r#"Ceruus"#), + (415_u16, r#"Strainstall Ltd"#), + (416_u16, r#"Channel Enterprises (HK) Ltd."#), + (417_u16, r#"FIAMM"#), + (418_u16, r#"GIGALANE.CO.,LTD"#), + (419_u16, r#"EROAD"#), + (420_u16, r#"Mine Safety Appliances"#), + (421_u16, r#"Icon Health and Fitness"#), + (422_u16, r#"Wille Engineering (formely as Asandoo GmbH)"#), + (423_u16, r#"ENERGOUS CORPORATION"#), + (424_u16, r#"Taobao"#), + (425_u16, r#"Canon Inc."#), + (426_u16, r#"Geophysical Technology Inc."#), + (427_u16, r#"Facebook, Inc."#), + (428_u16, r#"Trividia Health, Inc."#), + (429_u16, r#"FlightSafety International"#), + (430_u16, r#"Earlens Corporation"#), + (431_u16, r#"Sunrise Micro Devices, Inc."#), + (432_u16, r#"Star Micronics Co., Ltd."#), + (433_u16, r#"Netizens Sp. z o.o."#), + (434_u16, r#"Nymi Inc."#), + (435_u16, r#"Nytec, Inc."#), + (436_u16, r#"Trineo Sp. z o.o."#), + (437_u16, r#"Nest Labs Inc."#), + (438_u16, r#"LM Technologies Ltd"#), + (439_u16, r#"General Electric Company"#), + (440_u16, r#"i+D3 S.L."#), + (441_u16, r#"HANA Micron"#), + (442_u16, r#"Stages Cycling LLC"#), + (443_u16, r#"Cochlear Bone Anchored Solutions AB"#), + (444_u16, r#"SenionLab AB"#), + (445_u16, r#"Syszone Co., Ltd"#), + (446_u16, r#"Pulsate Mobile Ltd."#), + (447_u16, r#"Hong Kong HunterSun Electronic Limited"#), + (448_u16, r#"pironex GmbH"#), + (449_u16, r#"BRADATECH Corp."#), + (450_u16, r#"Transenergooil AG"#), + (451_u16, r#"Bunch"#), + (452_u16, r#"DME Microelectronics"#), + (453_u16, r#"Bitcraze AB"#), + (454_u16, r#"HASWARE Inc."#), + (455_u16, r#"Abiogenix Inc."#), + (456_u16, r#"Poly-Control ApS"#), + (457_u16, r#"Avi-on"#), + (458_u16, r#"Laerdal Medical AS"#), + (459_u16, r#"Fetch My Pet"#), + (460_u16, r#"Sam Labs Ltd."#), + (461_u16, r#"Chengdu Synwing Technology Ltd"#), + (462_u16, r#"HOUWA SYSTEM DESIGN, k.k."#), + (463_u16, r#"BSH"#), + (464_u16, r#"Primus Inter Pares Ltd"#), + (465_u16, r#"August Home, Inc"#), + (466_u16, r#"Gill Electronics"#), + (467_u16, r#"Sky Wave Design"#), + (468_u16, r#"Newlab S.r.l."#), + (469_u16, r#"ELAD srl"#), + (470_u16, r#"G-wearables inc."#), + (471_u16, r#"Squadrone Systems Inc."#), + (472_u16, r#"Code Corporation"#), + (473_u16, r#"Savant Systems LLC"#), + (474_u16, r#"Logitech International SA"#), + (475_u16, r#"Innblue Consulting"#), + (476_u16, r#"iParking Ltd."#), + (477_u16, r#"Koninklijke Philips Electronics N.V."#), + (478_u16, r#"Minelab Electronics Pty Limited"#), + (479_u16, r#"Bison Group Ltd."#), + (480_u16, r#"Widex A/S"#), + (481_u16, r#"Jolla Ltd"#), + (482_u16, r#"Lectronix, Inc."#), + (483_u16, r#"Caterpillar Inc"#), + (484_u16, r#"Freedom Innovations"#), + (485_u16, r#"Dynamic Devices Ltd"#), + (486_u16, r#"Technology Solutions (UK) Ltd"#), + (487_u16, r#"IPS Group Inc."#), + (488_u16, r#"STIR"#), + (489_u16, r#"Sano, Inc."#), + (490_u16, r#"Advanced Application Design, Inc."#), + (491_u16, r#"AutoMap LLC"#), + (492_u16, r#"Spreadtrum Communications Shanghai Ltd"#), + (493_u16, r#"CuteCircuit LTD"#), + (494_u16, r#"Valeo Service"#), + (495_u16, r#"Fullpower Technologies, Inc."#), + (496_u16, r#"KloudNation"#), + (497_u16, r#"Zebra Technologies Corporation"#), + (498_u16, r#"Itron, Inc."#), + (499_u16, r#"The University of Tokyo"#), + (500_u16, r#"UTC Fire and Security"#), + (501_u16, r#"Cool Webthings Limited"#), + (502_u16, r#"DJO Global"#), + (503_u16, r#"Gelliner Limited"#), + (504_u16, r#"Anyka (Guangzhou) Microelectronics Technology Co, LTD"#), + (505_u16, r#"Medtronic Inc."#), + (506_u16, r#"Gozio Inc."#), + (507_u16, r#"Form Lifting, LLC"#), + (508_u16, r#"Wahoo Fitness, LLC"#), + (509_u16, r#"Kontakt Micro-Location Sp. z o.o."#), + (510_u16, r#"Radio Systems Corporation"#), + (511_u16, r#"Freescale Semiconductor, Inc."#), + (512_u16, r#"Verifone Systems Pte Ltd. Taiwan Branch"#), + (513_u16, r#"AR Timing"#), + (514_u16, r#"Rigado LLC"#), + (515_u16, r#"Kemppi Oy"#), + (516_u16, r#"Tapcentive Inc."#), + (517_u16, r#"Smartbotics Inc."#), + (518_u16, r#"Otter Products, LLC"#), + (519_u16, r#"STEMP Inc."#), + (520_u16, r#"LumiGeek LLC"#), + (521_u16, r#"InvisionHeart Inc."#), + (522_u16, r#"Macnica Inc."#), + (523_u16, r#"Jaguar Land Rover Limited"#), + (524_u16, r#"CoroWare Technologies, Inc"#), + (525_u16, r#"Simplo Technology Co., LTD"#), + (526_u16, r#"Omron Healthcare Co., LTD"#), + (527_u16, r#"Comodule GMBH"#), + (528_u16, r#"ikeGPS"#), + (529_u16, r#"Telink Semiconductor Co. Ltd"#), + (530_u16, r#"Interplan Co., Ltd"#), + (531_u16, r#"Wyler AG"#), + (532_u16, r#"IK Multimedia Production srl"#), + (533_u16, r#"Lukoton Experience Oy"#), + (534_u16, r#"MTI Ltd"#), + (535_u16, r#"Tech4home, Lda"#), + (536_u16, r#"Hiotech AB"#), + (537_u16, r#"DOTT Limited"#), + (538_u16, r#"Blue Speck Labs, LLC"#), + (539_u16, r#"Cisco Systems, Inc"#), + (540_u16, r#"Mobicomm Inc"#), + (541_u16, r#"Edamic"#), + (542_u16, r#"Goodnet, Ltd"#), + (543_u16, r#"Luster Leaf Products Inc"#), + (544_u16, r#"Manus Machina BV"#), + (545_u16, r#"Mobiquity Networks Inc"#), + (546_u16, r#"Praxis Dynamics"#), + (547_u16, r#"Philip Morris Products S.A."#), + (548_u16, r#"Comarch SA"#), + (549_u16, r#"Nestlé Nespresso S.A."#), + (550_u16, r#"Merlinia A/S"#), + (551_u16, r#"LifeBEAM Technologies"#), + (552_u16, r#"Twocanoes Labs, LLC"#), + (553_u16, r#"Muoverti Limited"#), + (554_u16, r#"Stamer Musikanlagen GMBH"#), + (555_u16, r#"Tesla Motors"#), + (556_u16, r#"Pharynks Corporation"#), + (557_u16, r#"Lupine"#), + (558_u16, r#"Siemens AG"#), + (559_u16, r#"Huami (Shanghai) Culture Communication CO., LTD"#), + (560_u16, r#"Foster Electric Company, Ltd"#), + (561_u16, r#"ETA SA"#), + (562_u16, r#"x-Senso Solutions Kft"#), + (563_u16, r#"Shenzhen SuLong Communication Ltd"#), + (564_u16, r#"FengFan (BeiJing) Technology Co, Ltd"#), + (565_u16, r#"Qrio Inc"#), + (566_u16, r#"Pitpatpet Ltd"#), + (567_u16, r#"MSHeli s.r.l."#), + (568_u16, r#"Trakm8 Ltd"#), + (569_u16, r#"JIN CO, Ltd"#), + (570_u16, r#"Alatech Tehnology"#), + (571_u16, r#"Beijing CarePulse Electronic Technology Co, Ltd"#), + (572_u16, r#"Awarepoint"#), + (573_u16, r#"ViCentra B.V."#), + (574_u16, r#"Raven Industries"#), + (575_u16, r#"WaveWare Technologies Inc."#), + (576_u16, r#"Argenox Technologies"#), + (577_u16, r#"Bragi GmbH"#), + (578_u16, r#"16Lab Inc"#), + (579_u16, r#"Masimo Corp"#), + (580_u16, r#"Iotera Inc"#), + (581_u16, r#"Endress+Hauser "#), + (582_u16, r#"ACKme Networks, Inc."#), + (583_u16, r#"FiftyThree Inc."#), + (584_u16, r#"Parker Hannifin Corp"#), + (585_u16, r#"Transcranial Ltd"#), + (586_u16, r#"Uwatec AG"#), + (587_u16, r#"Orlan LLC"#), + (588_u16, r#"Blue Clover Devices"#), + (589_u16, r#"M-Way Solutions GmbH"#), + (590_u16, r#"Microtronics Engineering GmbH"#), + (591_u16, r#"Schneider Schreibgeräte GmbH"#), + (592_u16, r#"Sapphire Circuits LLC"#), + (593_u16, r#"Lumo Bodytech Inc."#), + (594_u16, r#"UKC Technosolution"#), + (595_u16, r#"Xicato Inc."#), + (596_u16, r#"Playbrush"#), + (597_u16, r#"Dai Nippon Printing Co., Ltd."#), + (598_u16, r#"G24 Power Limited"#), + (599_u16, r#"AdBabble Local Commerce Inc."#), + (600_u16, r#"Devialet SA"#), + (601_u16, r#"ALTYOR"#), + (602_u16, r#"University of Applied Sciences Valais/Haute Ecole Valaisanne"#), + (603_u16, r#"Five Interactive, LLC dba Zendo"#), + (604_u16, r#"NetEase(Hangzhou)Network co.Ltd."#), + (605_u16, r#"Lexmark International Inc."#), + (606_u16, r#"Fluke Corporation"#), + (607_u16, r#"Yardarm Technologies"#), + (608_u16, r#"SensaRx"#), + (609_u16, r#"SECVRE GmbH"#), + (610_u16, r#"Glacial Ridge Technologies"#), + (611_u16, r#"Identiv, Inc."#), + (612_u16, r#"DDS, Inc."#), + (613_u16, r#"SMK Corporation"#), + (614_u16, r#"Schawbel Technologies LLC"#), + (615_u16, r#"XMI Systems SA"#), + (616_u16, r#"Cerevo"#), + (617_u16, r#"Torrox GmbH & Co KG"#), + (618_u16, r#"Gemalto"#), + (619_u16, r#"DEKA Research & Development Corp."#), + (620_u16, r#"Domster Tadeusz Szydlowski"#), + (621_u16, r#"Technogym SPA"#), + (622_u16, r#"FLEURBAEY BVBA"#), + (623_u16, r#"Aptcode Solutions"#), + (624_u16, r#"LSI ADL Technology"#), + (625_u16, r#"Animas Corp"#), + (626_u16, r#"Alps Alpine Co., Ltd."#), + (627_u16, r#"OCEASOFT"#), + (628_u16, r#"Motsai Research"#), + (629_u16, r#"Geotab"#), + (630_u16, r#"E.G.O. Elektro-Geraetebau GmbH"#), + (631_u16, r#"bewhere inc"#), + (632_u16, r#"Johnson Outdoors Inc"#), + (633_u16, r#"steute Schaltgerate GmbH & Co. KG"#), + (634_u16, r#"Ekomini inc."#), + (635_u16, r#"DEFA AS"#), + (636_u16, r#"Aseptika Ltd"#), + (637_u16, r#"HUAWEI Technologies Co., Ltd."#), + (638_u16, r#"HabitAware, LLC"#), + (639_u16, r#"ruwido austria gmbh"#), + (640_u16, r#"ITEC corporation"#), + (641_u16, r#"StoneL"#), + (642_u16, r#"Sonova AG"#), + (643_u16, r#"Maven Machines, Inc."#), + (644_u16, r#"Synapse Electronics"#), + (645_u16, r#"Standard Innovation Inc."#), + (646_u16, r#"RF Code, Inc."#), + (647_u16, r#"Wally Ventures S.L."#), + (648_u16, r#"Willowbank Electronics Ltd"#), + (649_u16, r#"SK Telecom"#), + (650_u16, r#"Jetro AS"#), + (651_u16, r#"Code Gears LTD"#), + (652_u16, r#"NANOLINK APS"#), + (653_u16, r#"IF, LLC"#), + (654_u16, r#"RF Digital Corp"#), + (655_u16, r#"Church & Dwight Co., Inc"#), + (656_u16, r#"Multibit Oy"#), + (657_u16, r#"CliniCloud Inc"#), + (658_u16, r#"SwiftSensors"#), + (659_u16, r#"Blue Bite"#), + (660_u16, r#"ELIAS GmbH"#), + (661_u16, r#"Sivantos GmbH"#), + (662_u16, r#"Petzl"#), + (663_u16, r#"storm power ltd"#), + (664_u16, r#"EISST Ltd"#), + (665_u16, r#"Inexess Technology Simma KG"#), + (666_u16, r#"Currant, Inc."#), + (667_u16, r#"C2 Development, Inc."#), + (668_u16, r#"Blue Sky Scientific, LLC"#), + (669_u16, r#"ALOTTAZS LABS, LLC"#), + (670_u16, r#"Kupson spol. s r.o."#), + (671_u16, r#"Areus Engineering GmbH"#), + (672_u16, r#"Impossible Camera GmbH"#), + (673_u16, r#"InventureTrack Systems"#), + (674_u16, r#"LockedUp"#), + (675_u16, r#"Itude"#), + (676_u16, r#"Pacific Lock Company"#), + (677_u16, r#"Tendyron Corporation ( 天地融科技股份有限公司 )"#), + (678_u16, r#"Robert Bosch GmbH"#), + (679_u16, r#"Illuxtron international B.V."#), + (680_u16, r#"miSport Ltd."#), + (681_u16, r#"Chargelib"#), + (682_u16, r#"Doppler Lab"#), + (683_u16, r#"BBPOS Limited"#), + (684_u16, r#"RTB Elektronik GmbH & Co. KG"#), + (685_u16, r#"Rx Networks, Inc."#), + (686_u16, r#"WeatherFlow, Inc."#), + (687_u16, r#"Technicolor USA Inc."#), + (688_u16, r#"Bestechnic(Shanghai),Ltd"#), + (689_u16, r#"Raden Inc"#), + (690_u16, r#"JouZen Oy"#), + (691_u16, r#"CLABER S.P.A."#), + (692_u16, r#"Hyginex, Inc."#), + (693_u16, r#"HANSHIN ELECTRIC RAILWAY CO.,LTD."#), + (694_u16, r#"Schneider Electric"#), + (695_u16, r#"Oort Technologies LLC"#), + (696_u16, r#"Chrono Therapeutics"#), + (697_u16, r#"Rinnai Corporation"#), + (698_u16, r#"Swissprime Technologies AG"#), + (699_u16, r#"Koha.,Co.Ltd"#), + (700_u16, r#"Genevac Ltd"#), + (701_u16, r#"Chemtronics"#), + (702_u16, r#"Seguro Technology Sp. z o.o."#), + (703_u16, r#"Redbird Flight Simulations"#), + (704_u16, r#"Dash Robotics"#), + (705_u16, r#"LINE Corporation"#), + (706_u16, r#"Guillemot Corporation"#), + (707_u16, r#"Techtronic Power Tools Technology Limited"#), + (708_u16, r#"Wilson Sporting Goods"#), + (709_u16, r#"Lenovo (Singapore) Pte Ltd. ( 联想(新加坡) )"#), + (710_u16, r#"Ayatan Sensors"#), + (711_u16, r#"Electronics Tomorrow Limited"#), + (712_u16, r#"VASCO Data Security International, Inc."#), + (713_u16, r#"PayRange Inc."#), + (714_u16, r#"ABOV Semiconductor"#), + (715_u16, r#"AINA-Wireless Inc."#), + (716_u16, r#"Eijkelkamp Soil & Water"#), + (717_u16, r#"BMA ergonomics b.v."#), + (718_u16, r#"Teva Branded Pharmaceutical Products R&D, Inc."#), + (719_u16, r#"Anima"#), + (720_u16, r#"3M"#), + (721_u16, r#"Empatica Srl"#), + (722_u16, r#"Afero, Inc."#), + (723_u16, r#"Powercast Corporation"#), + (724_u16, r#"Secuyou ApS"#), + (725_u16, r#"OMRON Corporation"#), + (726_u16, r#"Send Solutions"#), + (727_u16, r#"NIPPON SYSTEMWARE CO.,LTD."#), + (728_u16, r#"Neosfar"#), + (729_u16, r#"Fliegl Agrartechnik GmbH"#), + (730_u16, r#"Gilvader"#), + (731_u16, r#"Digi International Inc (R)"#), + (732_u16, r#"DeWalch Technologies, Inc."#), + (733_u16, r#"Flint Rehabilitation Devices, LLC"#), + (734_u16, r#"Samsung SDS Co., Ltd."#), + (735_u16, r#"Blur Product Development"#), + (736_u16, r#"University of Michigan"#), + (737_u16, r#"Victron Energy BV"#), + (738_u16, r#"NTT docomo"#), + (739_u16, r#"Carmanah Technologies Corp."#), + (740_u16, r#"Bytestorm Ltd."#), + (741_u16, r#"Espressif Incorporated ( 乐鑫信息科技(上海)有限公司 )"#), + (742_u16, r#"Unwire"#), + (743_u16, r#"Connected Yard, Inc."#), + (744_u16, r#"American Music Environments"#), + (745_u16, r#"Sensogram Technologies, Inc."#), + (746_u16, r#"Fujitsu Limited"#), + (747_u16, r#"Ardic Technology"#), + (748_u16, r#"Delta Systems, Inc"#), + (749_u16, r#"HTC Corporation "#), + (750_u16, r#"Citizen Holdings Co., Ltd. "#), + (751_u16, r#"SMART-INNOVATION.inc"#), + (752_u16, r#"Blackrat Software "#), + (753_u16, r#"The Idea Cave, LLC"#), + (754_u16, r#"GoPro, Inc."#), + (755_u16, r#"AuthAir, Inc"#), + (756_u16, r#"Vensi, Inc."#), + (757_u16, r#"Indagem Tech LLC"#), + (758_u16, r#"Intemo Technologies"#), + (759_u16, r#"DreamVisions co., Ltd."#), + (760_u16, r#"Runteq Oy Ltd"#), + (761_u16, r#"IMAGINATION TECHNOLOGIES LTD "#), + (762_u16, r#"CoSTAR TEchnologies"#), + (763_u16, r#"Clarius Mobile Health Corp."#), + (764_u16, r#"Shanghai Frequen Microelectronics Co., Ltd."#), + (765_u16, r#"Uwanna, Inc."#), + (766_u16, r#"Lierda Science & Technology Group Co., Ltd."#), + (767_u16, r#"Silicon Laboratories"#), + (768_u16, r#"World Moto Inc."#), + (769_u16, r#"Giatec Scientific Inc."#), + (770_u16, r#"Loop Devices, Inc"#), + (771_u16, r#"IACA electronique"#), + (772_u16, r#"Proxy Technologies, Inc."#), + (773_u16, r#"Swipp ApS"#), + (774_u16, r#"Life Laboratory Inc. "#), + (775_u16, r#"FUJI INDUSTRIAL CO.,LTD."#), + (776_u16, r#"Surefire, LLC"#), + (777_u16, r#"Dolby Labs"#), + (778_u16, r#"Ellisys"#), + (779_u16, r#"Magnitude Lighting Converters"#), + (780_u16, r#"Hilti AG"#), + (781_u16, r#"Devdata S.r.l."#), + (782_u16, r#"Deviceworx"#), + (783_u16, r#"Shortcut Labs"#), + (784_u16, r#"SGL Italia S.r.l."#), + (785_u16, r#"PEEQ DATA"#), + (786_u16, r#"Ducere Technologies Pvt Ltd "#), + (787_u16, r#"DiveNav, Inc. "#), + (788_u16, r#"RIIG AI Sp. z o.o."#), + (789_u16, r#"Thermo Fisher Scientific "#), + (790_u16, r#"AG Measurematics Pvt. Ltd. "#), + (791_u16, r#"CHUO Electronics CO., LTD. "#), + (792_u16, r#"Aspenta International "#), + (793_u16, r#"Eugster Frismag AG "#), + (794_u16, r#"Amber wireless GmbH "#), + (795_u16, r#"HQ Inc "#), + (796_u16, r#"Lab Sensor Solutions "#), + (797_u16, r#"Enterlab ApS "#), + (798_u16, r#"Eyefi, Inc."#), + (799_u16, r#"MetaSystem S.p.A. "#), + (800_u16, r#"SONO ELECTRONICS. CO., LTD "#), + (801_u16, r#"Jewelbots "#), + (802_u16, r#"Compumedics Limited "#), + (803_u16, r#"Rotor Bike Components "#), + (804_u16, r#"Astro, Inc. "#), + (805_u16, r#"Amotus Solutions "#), + (806_u16, r#"Healthwear Technologies (Changzhou)Ltd "#), + (807_u16, r#"Essex Electronics "#), + (808_u16, r#"Grundfos A/S"#), + (809_u16, r#"Eargo, Inc. "#), + (810_u16, r#"Electronic Design Lab "#), + (811_u16, r#"ESYLUX "#), + (812_u16, r#"NIPPON SMT.CO.,Ltd"#), + (813_u16, r#"BM innovations GmbH "#), + (814_u16, r#"indoormap"#), + (815_u16, r#"OttoQ Inc "#), + (816_u16, r#"North Pole Engineering "#), + (817_u16, r#"3flares Technologies Inc."#), + (818_u16, r#"Electrocompaniet A.S. "#), + (819_u16, r#"Mul-T-Lock"#), + (820_u16, r#"Corentium AS "#), + (821_u16, r#"Enlighted Inc"#), + (822_u16, r#"GISTIC"#), + (823_u16, r#"AJP2 Holdings, LLC"#), + (824_u16, r#"COBI GmbH "#), + (825_u16, r#"Blue Sky Scientific, LLC "#), + (826_u16, r#"Appception, Inc."#), + (827_u16, r#"Courtney Thorne Limited "#), + (828_u16, r#"Virtuosys"#), + (829_u16, r#"TPV Technology Limited "#), + (830_u16, r#"Monitra SA"#), + (831_u16, r#"Automation Components, Inc. "#), + (832_u16, r#"Letsense s.r.l. "#), + (833_u16, r#"Etesian Technologies LLC "#), + (834_u16, r#"GERTEC BRASIL LTDA. "#), + (835_u16, r#"Drekker Development Pty. Ltd."#), + (836_u16, r#"Whirl Inc "#), + (837_u16, r#"Locus Positioning "#), + (838_u16, r#"Acuity Brands Lighting, Inc "#), + (839_u16, r#"Prevent Biometrics "#), + (840_u16, r#"Arioneo"#), + (841_u16, r#"VersaMe "#), + (842_u16, r#"Vaddio "#), + (843_u16, r#"Libratone A/S "#), + (844_u16, r#"HM Electronics, Inc. "#), + (845_u16, r#"TASER International, Inc."#), + (846_u16, r#"SafeTrust Inc. "#), + (847_u16, r#"Heartland Payment Systems "#), + (848_u16, r#"Bitstrata Systems Inc. "#), + (849_u16, r#"Pieps GmbH "#), + (850_u16, r#"iRiding(Xiamen)Technology Co.,Ltd."#), + (851_u16, r#"Alpha Audiotronics, Inc. "#), + (852_u16, r#"TOPPAN FORMS CO.,LTD. "#), + (853_u16, r#"Sigma Designs, Inc. "#), + (854_u16, r#"Spectrum Brands, Inc. "#), + (855_u16, r#"Polymap Wireless "#), + (856_u16, r#"MagniWare Ltd."#), + (857_u16, r#"Novotec Medical GmbH "#), + (858_u16, r#"Medicom Innovation Partner a/s "#), + (859_u16, r#"Matrix Inc. "#), + (860_u16, r#"Eaton Corporation "#), + (861_u16, r#"KYS"#), + (862_u16, r#"Naya Health, Inc. "#), + (863_u16, r#"Acromag "#), + (864_u16, r#"Insulet Corporation "#), + (865_u16, r#"Wellinks Inc. "#), + (866_u16, r#"ON Semiconductor"#), + (867_u16, r#"FREELAP SA "#), + (868_u16, r#"Favero Electronics Srl "#), + (869_u16, r#"BioMech Sensor LLC "#), + (870_u16, r#"BOLTT Sports technologies Private limited"#), + (871_u16, r#"Saphe International "#), + (872_u16, r#"Metormote AB "#), + (873_u16, r#"littleBits "#), + (874_u16, r#"SetPoint Medical "#), + (875_u16, r#"BRControls Products BV "#), + (876_u16, r#"Zipcar "#), + (877_u16, r#"AirBolt Pty Ltd "#), + (878_u16, r#"KeepTruckin Inc "#), + (879_u16, r#"Motiv, Inc. "#), + (880_u16, r#"Wazombi Labs OÜ "#), + (881_u16, r#"ORBCOMM"#), + (882_u16, r#"Nixie Labs, Inc."#), + (883_u16, r#"AppNearMe Ltd"#), + (884_u16, r#"Holman Industries"#), + (885_u16, r#"Expain AS"#), + (886_u16, r#"Electronic Temperature Instruments Ltd"#), + (887_u16, r#"Plejd AB"#), + (888_u16, r#"Propeller Health"#), + (889_u16, r#"Shenzhen iMCO Electronic Technology Co.,Ltd"#), + (890_u16, r#"Algoria"#), + (891_u16, r#"Apption Labs Inc."#), + (892_u16, r#"Cronologics Corporation"#), + (893_u16, r#"MICRODIA Ltd."#), + (894_u16, r#"lulabytes S.L."#), + (895_u16, r#"Société des Produits Nestlé S.A. (formerly Nestec S.A.)"#), + (896_u16, r#"LLC "MEGA-F service""#), + (897_u16, r#"Sharp Corporation"#), + (898_u16, r#"Precision Outcomes Ltd"#), + (899_u16, r#"Kronos Incorporated"#), + (900_u16, r#"OCOSMOS Co., Ltd."#), + (901_u16, r#"Embedded Electronic Solutions Ltd. dba e2Solutions"#), + (902_u16, r#"Aterica Inc."#), + (903_u16, r#"BluStor PMC, Inc."#), + (904_u16, r#"Kapsch TrafficCom AB"#), + (905_u16, r#"ActiveBlu Corporation"#), + (906_u16, r#"Kohler Mira Limited"#), + (907_u16, r#"Noke"#), + (908_u16, r#"Appion Inc."#), + (909_u16, r#"Resmed Ltd"#), + (910_u16, r#"Crownstone B.V."#), + (911_u16, r#"Xiaomi Inc."#), + (912_u16, r#"INFOTECH s.r.o."#), + (913_u16, r#"Thingsquare AB"#), + (914_u16, r#"T&D"#), + (915_u16, r#"LAVAZZA S.p.A."#), + (916_u16, r#"Netclearance Systems, Inc."#), + (917_u16, r#"SDATAWAY"#), + (918_u16, r#"BLOKS GmbH"#), + (919_u16, r#"LEGO System A/S"#), + (920_u16, r#"Thetatronics Ltd"#), + (921_u16, r#"Nikon Corporation"#), + (922_u16, r#"NeST"#), + (923_u16, r#"South Silicon Valley Microelectronics"#), + (924_u16, r#"ALE International"#), + (925_u16, r#"CareView Communications, Inc."#), + (926_u16, r#"SchoolBoard Limited"#), + (927_u16, r#"Molex Corporation"#), + (928_u16, r#"IVT Wireless Limited"#), + (929_u16, r#"Alpine Labs LLC"#), + (930_u16, r#"Candura Instruments"#), + (931_u16, r#"SmartMovt Technology Co., Ltd"#), + (932_u16, r#"Token Zero Ltd"#), + (933_u16, r#"ACE CAD Enterprise Co., Ltd. (ACECAD)"#), + (934_u16, r#"Medela, Inc"#), + (935_u16, r#"AeroScout"#), + (936_u16, r#"Esrille Inc."#), + (937_u16, r#"THINKERLY SRL"#), + (938_u16, r#"Exon Sp. z o.o."#), + (939_u16, r#"Meizu Technology Co., Ltd."#), + (940_u16, r#"Smablo LTD"#), + (941_u16, r#"XiQ"#), + (942_u16, r#"Allswell Inc."#), + (943_u16, r#"Comm-N-Sense Corp DBA Verigo"#), + (944_u16, r#"VIBRADORM GmbH"#), + (945_u16, r#"Otodata Wireless Network Inc."#), + (946_u16, r#"Propagation Systems Limited"#), + (947_u16, r#"Midwest Instruments & Controls"#), + (948_u16, r#"Alpha Nodus, inc."#), + (949_u16, r#"petPOMM, Inc"#), + (950_u16, r#"Mattel"#), + (951_u16, r#"Airbly Inc."#), + (952_u16, r#"A-Safe Limited"#), + (953_u16, r#"FREDERIQUE CONSTANT SA"#), + (954_u16, r#"Maxscend Microelectronics Company Limited"#), + (955_u16, r#"Abbott"#), + (956_u16, r#"ASB Bank Ltd"#), + (957_u16, r#"amadas"#), + (958_u16, r#"Applied Science, Inc."#), + (959_u16, r#"iLumi Solutions Inc."#), + (960_u16, r#"Arch Systems Inc."#), + (961_u16, r#"Ember Technologies, Inc."#), + (962_u16, r#"Snapchat Inc"#), + (963_u16, r#"Casambi Technologies Oy"#), + (964_u16, r#"Pico Technology Inc."#), + (965_u16, r#"St. Jude Medical, Inc."#), + (966_u16, r#"Intricon"#), + (967_u16, r#"Structural Health Systems, Inc."#), + (968_u16, r#"Avvel International"#), + (969_u16, r#"Gallagher Group"#), + (970_u16, r#"In2things Automation Pvt. Ltd."#), + (971_u16, r#"SYSDEV Srl"#), + (972_u16, r#"Vonkil Technologies Ltd"#), + (973_u16, r#"Wynd Technologies, Inc."#), + (974_u16, r#"CONTRINEX S.A."#), + (975_u16, r#"MIRA, Inc."#), + (976_u16, r#"Watteam Ltd"#), + (977_u16, r#"Density Inc."#), + (978_u16, r#"IOT Pot India Private Limited"#), + (979_u16, r#"Sigma Connectivity AB"#), + (980_u16, r#"PEG PEREGO SPA"#), + (981_u16, r#"Wyzelink Systems Inc."#), + (982_u16, r#"Yota Devices LTD"#), + (983_u16, r#"FINSECUR"#), + (984_u16, r#"Zen-Me Labs Ltd"#), + (985_u16, r#"3IWare Co., Ltd."#), + (986_u16, r#"EnOcean GmbH"#), + (987_u16, r#"Instabeat, Inc"#), + (988_u16, r#"Nima Labs"#), + (989_u16, r#"Andreas Stihl AG & Co. KG"#), + (990_u16, r#"Nathan Rhoades LLC"#), + (991_u16, r#"Grob Technologies, LLC"#), + (992_u16, r#"Actions (Zhuhai) Technology Co., Limited"#), + (993_u16, r#"SPD Development Company Ltd"#), + (994_u16, r#"Sensoan Oy"#), + (995_u16, r#"Qualcomm Life Inc"#), + (996_u16, r#"Chip-ing AG"#), + (997_u16, r#"ffly4u"#), + (998_u16, r#"IoT Instruments Oy"#), + (999_u16, r#"TRUE Fitness Technology"#), + (1000_u16, r#"Reiner Kartengeraete GmbH & Co. KG."#), + (1001_u16, r#"SHENZHEN LEMONJOY TECHNOLOGY CO., LTD."#), + (1002_u16, r#"Hello Inc."#), + (1003_u16, r#"Evollve Inc."#), + (1004_u16, r#"Jigowatts Inc."#), + (1005_u16, r#"BASIC MICRO.COM,INC."#), + (1006_u16, r#"CUBE TECHNOLOGIES"#), + (1007_u16, r#"foolography GmbH"#), + (1008_u16, r#"CLINK"#), + (1009_u16, r#"Hestan Smart Cooking Inc."#), + (1010_u16, r#"WindowMaster A/S"#), + (1011_u16, r#"Flowscape AB"#), + (1012_u16, r#"PAL Technologies Ltd"#), + (1013_u16, r#"WHERE, Inc."#), + (1014_u16, r#"Iton Technology Corp."#), + (1015_u16, r#"Owl Labs Inc."#), + (1016_u16, r#"Rockford Corp."#), + (1017_u16, r#"Becon Technologies Co.,Ltd."#), + (1018_u16, r#"Vyassoft Technologies Inc"#), + (1019_u16, r#"Nox Medical"#), + (1020_u16, r#"Kimberly-Clark"#), + (1021_u16, r#"Trimble Navigation Ltd."#), + (1022_u16, r#"Littelfuse"#), + (1023_u16, r#"Withings"#), + (1024_u16, r#"i-developer IT Beratung UG"#), + (1025_u16, r#"Relations Inc."#), + (1026_u16, r#"Sears Holdings Corporation"#), + (1027_u16, r#"Gantner Electronic GmbH"#), + (1028_u16, r#"Authomate Inc"#), + (1029_u16, r#"Vertex International, Inc."#), + (1030_u16, r#"Airtago"#), + (1031_u16, r#"Swiss Audio SA"#), + (1032_u16, r#"ToGetHome Inc."#), + (1033_u16, r#"AXIS"#), + (1034_u16, r#"Openmatics"#), + (1035_u16, r#"Jana Care Inc."#), + (1036_u16, r#"Senix Corporation"#), + (1037_u16, r#"NorthStar Battery Company, LLC"#), + (1038_u16, r#"SKF (U.K.) Limited"#), + (1039_u16, r#"CO-AX Technology, Inc."#), + (1040_u16, r#"Fender Musical Instruments"#), + (1041_u16, r#"Luidia Inc"#), + (1042_u16, r#"SEFAM"#), + (1043_u16, r#"Wireless Cables Inc"#), + (1044_u16, r#"Lightning Protection International Pty Ltd"#), + (1045_u16, r#"Uber Technologies Inc"#), + (1046_u16, r#"SODA GmbH"#), + (1047_u16, r#"Fatigue Science"#), + (1048_u16, r#"Reserved"#), + (1049_u16, r#"Novalogy LTD"#), + (1050_u16, r#"Friday Labs Limited"#), + (1051_u16, r#"OrthoAccel Technologies"#), + (1052_u16, r#"WaterGuru, Inc."#), + (1053_u16, r#"Benning Elektrotechnik und Elektronik GmbH & Co. KG"#), + (1054_u16, r#"Dell Computer Corporation"#), + (1055_u16, r#"Kopin Corporation"#), + (1056_u16, r#"TecBakery GmbH"#), + (1057_u16, r#"Backbone Labs, Inc."#), + (1058_u16, r#"DELSEY SA"#), + (1059_u16, r#"Chargifi Limited"#), + (1060_u16, r#"Trainesense Ltd."#), + (1061_u16, r#"Unify Software and Solutions GmbH & Co. KG"#), + (1062_u16, r#"Husqvarna AB"#), + (1063_u16, r#"Focus fleet and fuel management inc"#), + (1064_u16, r#"SmallLoop, LLC"#), + (1065_u16, r#"Prolon Inc."#), + (1066_u16, r#"BD Medical"#), + (1067_u16, r#"iMicroMed Incorporated"#), + (1068_u16, r#"Ticto N.V."#), + (1069_u16, r#"Meshtech AS"#), + (1070_u16, r#"MemCachier Inc."#), + (1071_u16, r#"Danfoss A/S"#), + (1072_u16, r#"SnapStyk Inc."#), + (1073_u16, r#"Amway Corporation"#), + (1074_u16, r#"Silk Labs, Inc."#), + (1075_u16, r#"Pillsy Inc."#), + (1076_u16, r#"Hatch Baby, Inc."#), + (1077_u16, r#"Blocks Wearables Ltd."#), + (1078_u16, r#"Drayson Technologies (Europe) Limited"#), + (1079_u16, r#"eBest IOT Inc."#), + (1080_u16, r#"Helvar Ltd"#), + (1081_u16, r#"Radiance Technologies"#), + (1082_u16, r#"Nuheara Limited"#), + (1083_u16, r#"Appside co., ltd."#), + (1084_u16, r#"DeLaval"#), + (1085_u16, r#"Coiler Corporation"#), + (1086_u16, r#"Thermomedics, Inc."#), + (1087_u16, r#"Tentacle Sync GmbH"#), + (1088_u16, r#"Valencell, Inc."#), + (1089_u16, r#"iProtoXi Oy"#), + (1090_u16, r#"SECOM CO., LTD."#), + (1091_u16, r#"Tucker International LLC"#), + (1092_u16, r#"Metanate Limited"#), + (1093_u16, r#"Kobian Canada Inc."#), + (1094_u16, r#"NETGEAR, Inc."#), + (1095_u16, r#"Fabtronics Australia Pty Ltd"#), + (1096_u16, r#"Grand Centrix GmbH"#), + (1097_u16, r#"1UP USA.com llc"#), + (1098_u16, r#"SHIMANO INC."#), + (1099_u16, r#"Nain Inc."#), + (1100_u16, r#"LifeStyle Lock, LLC"#), + (1101_u16, r#"VEGA Grieshaber KG"#), + (1102_u16, r#"Xtrava Inc."#), + (1103_u16, r#"TTS Tooltechnic Systems AG & Co. KG"#), + (1104_u16, r#"Teenage Engineering AB"#), + (1105_u16, r#"Tunstall Nordic AB"#), + (1106_u16, r#"Svep Design Center AB"#), + (1107_u16, r#"Qorvo Utrecht B.V. formerly GreenPeak Technologies BV"#), + (1108_u16, r#"Sphinx Electronics GmbH & Co KG"#), + (1109_u16, r#"Atomation"#), + (1110_u16, r#"Nemik Consulting Inc"#), + (1111_u16, r#"RF INNOVATION"#), + (1112_u16, r#"Mini Solution Co., Ltd."#), + (1113_u16, r#"Lumenetix, Inc"#), + (1114_u16, r#"2048450 Ontario Inc"#), + (1115_u16, r#"SPACEEK LTD"#), + (1116_u16, r#"Delta T Corporation"#), + (1117_u16, r#"Boston Scientific Corporation"#), + (1118_u16, r#"Nuviz, Inc."#), + (1119_u16, r#"Real Time Automation, Inc."#), + (1120_u16, r#"Kolibree"#), + (1121_u16, r#"vhf elektronik GmbH"#), + (1122_u16, r#"Bonsai Systems GmbH"#), + (1123_u16, r#"Fathom Systems Inc."#), + (1124_u16, r#"Bellman & Symfon"#), + (1125_u16, r#"International Forte Group LLC"#), + (1126_u16, r#"CycleLabs Solutions inc."#), + (1127_u16, r#"Codenex Oy"#), + (1128_u16, r#"Kynesim Ltd"#), + (1129_u16, r#"Palago AB"#), + (1130_u16, r#"INSIGMA INC."#), + (1131_u16, r#"PMD Solutions"#), + (1132_u16, r#"Qingdao Realtime Technology Co., Ltd."#), + (1133_u16, r#"BEGA Gantenbrink-Leuchten KG"#), + (1134_u16, r#"Pambor Ltd."#), + (1135_u16, r#"Develco Products A/S"#), + (1136_u16, r#"iDesign s.r.l."#), + (1137_u16, r#"TiVo Corp"#), + (1138_u16, r#"Control-J Pty Ltd"#), + (1139_u16, r#"Steelcase, Inc."#), + (1140_u16, r#"iApartment co., ltd."#), + (1141_u16, r#"Icom inc."#), + (1142_u16, r#"Oxstren Wearable Technologies Private Limited"#), + (1143_u16, r#"Blue Spark Technologies"#), + (1144_u16, r#"FarSite Communications Limited"#), + (1145_u16, r#"mywerk system GmbH"#), + (1146_u16, r#"Sinosun Technology Co., Ltd."#), + (1147_u16, r#"MIYOSHI ELECTRONICS CORPORATION"#), + (1148_u16, r#"POWERMAT LTD"#), + (1149_u16, r#"Occly LLC"#), + (1150_u16, r#"OurHub Dev IvS"#), + (1151_u16, r#"Pro-Mark, Inc."#), + (1152_u16, r#"Dynometrics Inc."#), + (1153_u16, r#"Quintrax Limited"#), + (1154_u16, r#"POS Tuning Udo Vosshenrich GmbH & Co. KG"#), + (1155_u16, r#"Multi Care Systems B.V."#), + (1156_u16, r#"Revol Technologies Inc"#), + (1157_u16, r#"SKIDATA AG"#), + (1158_u16, r#"DEV TECNOLOGIA INDUSTRIA, COMERCIO E MANUTENCAO DE EQUIPAMENTOS LTDA. - ME"#), + (1159_u16, r#"Centrica Connected Home"#), + (1160_u16, r#"Automotive Data Solutions Inc"#), + (1161_u16, r#"Igarashi Engineering"#), + (1162_u16, r#"Taelek Oy"#), + (1163_u16, r#"CP Electronics Limited"#), + (1164_u16, r#"Vectronix AG"#), + (1165_u16, r#"S-Labs Sp. z o.o."#), + (1166_u16, r#"Companion Medical, Inc."#), + (1167_u16, r#"BlueKitchen GmbH"#), + (1168_u16, r#"Matting AB"#), + (1169_u16, r#"SOREX - Wireless Solutions GmbH"#), + (1170_u16, r#"ADC Technology, Inc."#), + (1171_u16, r#"Lynxemi Pte Ltd"#), + (1172_u16, r#"SENNHEISER electronic GmbH & Co. KG"#), + (1173_u16, r#"LMT Mercer Group, Inc"#), + (1174_u16, r#"Polymorphic Labs LLC"#), + (1175_u16, r#"Cochlear Limited"#), + (1176_u16, r#"METER Group, Inc. USA"#), + (1177_u16, r#"Ruuvi Innovations Ltd."#), + (1178_u16, r#"Situne AS"#), + (1179_u16, r#"nVisti, LLC"#), + (1180_u16, r#"DyOcean"#), + (1181_u16, r#"Uhlmann & Zacher GmbH"#), + (1182_u16, r#"AND!XOR LLC"#), + (1183_u16, r#"tictote AB"#), + (1184_u16, r#"Vypin, LLC"#), + (1185_u16, r#"PNI Sensor Corporation"#), + (1186_u16, r#"ovrEngineered, LLC"#), + (1187_u16, r#"GT-tronics HK Ltd"#), + (1188_u16, r#"Herbert Waldmann GmbH & Co. KG"#), + (1189_u16, r#"Guangzhou FiiO Electronics Technology Co.,Ltd"#), + (1190_u16, r#"Vinetech Co., Ltd"#), + (1191_u16, r#"Dallas Logic Corporation"#), + (1192_u16, r#"BioTex, Inc."#), + (1193_u16, r#"DISCOVERY SOUND TECHNOLOGY, LLC"#), + (1194_u16, r#"LINKIO SAS"#), + (1195_u16, r#"Harbortronics, Inc."#), + (1196_u16, r#"Undagrid B.V."#), + (1197_u16, r#"Shure Inc"#), + (1198_u16, r#"ERM Electronic Systems LTD"#), + (1199_u16, r#"BIOROWER Handelsagentur GmbH"#), + (1200_u16, r#"Weba Sport und Med. Artikel GmbH"#), + (1201_u16, r#"Kartographers Technologies Pvt. Ltd."#), + (1202_u16, r#"The Shadow on the Moon"#), + (1203_u16, r#"mobike (Hong Kong) Limited"#), + (1204_u16, r#"Inuheat Group AB"#), + (1205_u16, r#"Swiftronix AB"#), + (1206_u16, r#"Diagnoptics Technologies"#), + (1207_u16, r#"Analog Devices, Inc."#), + (1208_u16, r#"Soraa Inc."#), + (1209_u16, r#"CSR Building Products Limited"#), + (1210_u16, r#"Crestron Electronics, Inc."#), + (1211_u16, r#"Neatebox Ltd"#), + (1212_u16, r#"Draegerwerk AG & Co. KGaA"#), + (1213_u16, r#"AlbynMedical"#), + (1214_u16, r#"Averos FZCO"#), + (1215_u16, r#"VIT Initiative, LLC"#), + (1216_u16, r#"Statsports International"#), + (1217_u16, r#"Sospitas, s.r.o."#), + (1218_u16, r#"Dmet Products Corp."#), + (1219_u16, r#"Mantracourt Electronics Limited"#), + (1220_u16, r#"TeAM Hutchins AB"#), + (1221_u16, r#"Seibert Williams Glass, LLC"#), + (1222_u16, r#"Insta GmbH"#), + (1223_u16, r#"Svantek Sp. z o.o."#), + (1224_u16, r#"Shanghai Flyco Electrical Appliance Co., Ltd."#), + (1225_u16, r#"Thornwave Labs Inc"#), + (1226_u16, r#"Steiner-Optik GmbH"#), + (1227_u16, r#"Novo Nordisk A/S"#), + (1228_u16, r#"Enflux Inc."#), + (1229_u16, r#"Safetech Products LLC"#), + (1230_u16, r#"GOOOLED S.R.L."#), + (1231_u16, r#"DOM Sicherheitstechnik GmbH & Co. KG"#), + (1232_u16, r#"Olympus Corporation"#), + (1233_u16, r#"KTS GmbH"#), + (1234_u16, r#"Anloq Technologies Inc."#), + (1235_u16, r#"Queercon, Inc"#), + (1236_u16, r#"5th Element Ltd"#), + (1237_u16, r#"Gooee Limited"#), + (1238_u16, r#"LUGLOC LLC"#), + (1239_u16, r#"Blincam, Inc."#), + (1240_u16, r#"FUJIFILM Corporation"#), + (1241_u16, r#"RandMcNally"#), + (1242_u16, r#"Franceschi Marina snc"#), + (1243_u16, r#"Engineered Audio, LLC."#), + (1244_u16, r#"IOTTIVE (OPC) PRIVATE LIMITED"#), + (1245_u16, r#"4MOD Technology"#), + (1246_u16, r#"Lutron Electronics Co., Inc."#), + (1247_u16, r#"Emerson"#), + (1248_u16, r#"Guardtec, Inc."#), + (1249_u16, r#"REACTEC LIMITED"#), + (1250_u16, r#"EllieGrid"#), + (1251_u16, r#"Under Armour"#), + (1252_u16, r#"Woodenshark"#), + (1253_u16, r#"Avack Oy"#), + (1254_u16, r#"Smart Solution Technology, Inc."#), + (1255_u16, r#"REHABTRONICS INC."#), + (1256_u16, r#"STABILO International"#), + (1257_u16, r#"Busch Jaeger Elektro GmbH"#), + (1258_u16, r#"Pacific Bioscience Laboratories, Inc"#), + (1259_u16, r#"Bird Home Automation GmbH"#), + (1260_u16, r#"Motorola Solutions"#), + (1261_u16, r#"R9 Technology, Inc."#), + (1262_u16, r#"Auxivia"#), + (1263_u16, r#"DaisyWorks, Inc"#), + (1264_u16, r#"Kosi Limited"#), + (1265_u16, r#"Theben AG"#), + (1266_u16, r#"InDreamer Techsol Private Limited"#), + (1267_u16, r#"Cerevast Medical"#), + (1268_u16, r#"ZanCompute Inc."#), + (1269_u16, r#"Pirelli Tyre S.P.A."#), + (1270_u16, r#"McLear Limited"#), + (1271_u16, r#"Shenzhen Huiding Technology Co.,Ltd."#), + (1272_u16, r#"Convergence Systems Limited"#), + (1273_u16, r#"Interactio"#), + (1274_u16, r#"Androtec GmbH"#), + (1275_u16, r#"Benchmark Drives GmbH & Co. KG"#), + (1276_u16, r#"SwingLync L. L. C."#), + (1277_u16, r#"Tapkey GmbH"#), + (1278_u16, r#"Woosim Systems Inc."#), + (1279_u16, r#"Microsemi Corporation"#), + (1280_u16, r#"Wiliot LTD."#), + (1281_u16, r#"Polaris IND"#), + (1282_u16, r#"Specifi-Kali LLC"#), + (1283_u16, r#"Locoroll, Inc"#), + (1284_u16, r#"PHYPLUS Inc"#), + (1285_u16, r#"Inplay Technologies LLC"#), + (1286_u16, r#"Hager"#), + (1287_u16, r#"Yellowcog"#), + (1288_u16, r#"Axes System sp. z o. o."#), + (1289_u16, r#"myLIFTER Inc."#), + (1290_u16, r#"Shake-on B.V."#), + (1291_u16, r#"Vibrissa Inc."#), + (1292_u16, r#"OSRAM GmbH"#), + (1293_u16, r#"TRSystems GmbH"#), + (1294_u16, r#"Yichip Microelectronics (Hangzhou) Co.,Ltd."#), + (1295_u16, r#"Foundation Engineering LLC"#), + (1296_u16, r#"UNI-ELECTRONICS, INC."#), + (1297_u16, r#"Brookfield Equinox LLC"#), + (1298_u16, r#"Soprod SA"#), + (1299_u16, r#"9974091 Canada Inc."#), + (1300_u16, r#"FIBRO GmbH"#), + (1301_u16, r#"RB Controls Co., Ltd."#), + (1302_u16, r#"Footmarks"#), + (1303_u16, r#"Amtronic Sverige AB (formerly Amcore AB)"#), + (1304_u16, r#"MAMORIO.inc"#), + (1305_u16, r#"Tyto Life LLC"#), + (1306_u16, r#"Leica Camera AG"#), + (1307_u16, r#"Angee Technologies Ltd."#), + (1308_u16, r#"EDPS"#), + (1309_u16, r#"OFF Line Co., Ltd."#), + (1310_u16, r#"Detect Blue Limited"#), + (1311_u16, r#"Setec Pty Ltd"#), + (1312_u16, r#"Target Corporation"#), + (1313_u16, r#"IAI Corporation"#), + (1314_u16, r#"NS Tech, Inc."#), + (1315_u16, r#"MTG Co., Ltd."#), + (1316_u16, r#"Hangzhou iMagic Technology Co., Ltd"#), + (1317_u16, r#"HONGKONG NANO IC TECHNOLOGIES CO., LIMITED"#), + (1318_u16, r#"Honeywell International Inc."#), + (1319_u16, r#"Albrecht JUNG"#), + (1320_u16, r#"Lunera Lighting Inc."#), + (1321_u16, r#"Lumen UAB"#), + (1322_u16, r#"Keynes Controls Ltd"#), + (1323_u16, r#"Novartis AG"#), + (1324_u16, r#"Geosatis SA"#), + (1325_u16, r#"EXFO, Inc."#), + (1326_u16, r#"LEDVANCE GmbH"#), + (1327_u16, r#"Center ID Corp."#), + (1328_u16, r#"Adolene, Inc."#), + (1329_u16, r#"D&M Holdings Inc."#), + (1330_u16, r#"CRESCO Wireless, Inc."#), + (1331_u16, r#"Nura Operations Pty Ltd"#), + (1332_u16, r#"Frontiergadget, Inc."#), + (1333_u16, r#"Smart Component Technologies Limited"#), + (1334_u16, r#"ZTR Control Systems LLC"#), + (1335_u16, r#"MetaLogics Corporation"#), + (1336_u16, r#"Medela AG"#), + (1337_u16, r#"OPPLE Lighting Co., Ltd"#), + (1338_u16, r#"Savitech Corp.,"#), + (1339_u16, r#"prodigy"#), + (1340_u16, r#"Screenovate Technologies Ltd"#), + (1341_u16, r#"TESA SA"#), + (1342_u16, r#"CLIM8 LIMITED"#), + (1343_u16, r#"Silergy Corp"#), + (1344_u16, r#"SilverPlus, Inc"#), + (1345_u16, r#"Sharknet srl"#), + (1346_u16, r#"Mist Systems, Inc."#), + (1347_u16, r#"MIWA LOCK CO.,Ltd"#), + (1348_u16, r#"OrthoSensor, Inc."#), + (1349_u16, r#"Candy Hoover Group s.r.l"#), + (1350_u16, r#"Apexar Technologies S.A."#), + (1351_u16, r#"LOGICDATA d.o.o."#), + (1352_u16, r#"Knick Elektronische Messgeraete GmbH & Co. KG"#), + (1353_u16, r#"Smart Technologies and Investment Limited"#), + (1354_u16, r#"Linough Inc."#), + (1355_u16, r#"Advanced Electronic Designs, Inc."#), + (1356_u16, r#"Carefree Scott Fetzer Co Inc"#), + (1357_u16, r#"Sensome"#), + (1358_u16, r#"FORTRONIK storitve d.o.o."#), + (1359_u16, r#"Sinnoz"#), + (1360_u16, r#"Versa Networks, Inc."#), + (1361_u16, r#"Sylero"#), + (1362_u16, r#"Avempace SARL"#), + (1363_u16, r#"Nintendo Co., Ltd."#), + (1364_u16, r#"National Instruments"#), + (1365_u16, r#"KROHNE Messtechnik GmbH"#), + (1366_u16, r#"Otodynamics Ltd"#), + (1367_u16, r#"Arwin Technology Limited"#), + (1368_u16, r#"benegear, inc."#), + (1369_u16, r#"Newcon Optik"#), + (1370_u16, r#"CANDY HOUSE, Inc."#), + (1371_u16, r#"FRANKLIN TECHNOLOGY INC"#), + (1372_u16, r#"Lely"#), + (1373_u16, r#"Valve Corporation"#), + (1374_u16, r#"Hekatron Vertriebs GmbH"#), + (1375_u16, r#"PROTECH S.A.S. DI GIRARDI ANDREA & C."#), + (1376_u16, r#"Sarita CareTech APS (formerly Sarita CareTech IVS)"#), + (1377_u16, r#"Finder S.p.A."#), + (1378_u16, r#"Thalmic Labs Inc."#), + (1379_u16, r#"Steinel Vertrieb GmbH"#), + (1380_u16, r#"Beghelli Spa"#), + (1381_u16, r#"Beijing Smartspace Technologies Inc."#), + (1382_u16, r#"CORE TRANSPORT TECHNOLOGIES NZ LIMITED"#), + (1383_u16, r#"Xiamen Everesports Goods Co., Ltd"#), + (1384_u16, r#"Bodyport Inc."#), + (1385_u16, r#"Audionics System, INC."#), + (1386_u16, r#"Flipnavi Co.,Ltd."#), + (1387_u16, r#"Rion Co., Ltd."#), + (1388_u16, r#"Long Range Systems, LLC"#), + (1389_u16, r#"Redmond Industrial Group LLC"#), + (1390_u16, r#"VIZPIN INC."#), + (1391_u16, r#"BikeFinder AS"#), + (1392_u16, r#"Consumer Sleep Solutions LLC"#), + (1393_u16, r#"PSIKICK, INC."#), + (1394_u16, r#"AntTail.com"#), + (1395_u16, r#"Lighting Science Group Corp."#), + (1396_u16, r#"AFFORDABLE ELECTRONICS INC"#), + (1397_u16, r#"Integral Memroy Plc"#), + (1398_u16, r#"Globalstar, Inc."#), + (1399_u16, r#"True Wearables, Inc."#), + (1400_u16, r#"Wellington Drive Technologies Ltd"#), + (1401_u16, r#"Ensemble Tech Private Limited"#), + (1402_u16, r#"OMNI Remotes"#), + (1403_u16, r#"Duracell U.S. Operations Inc."#), + (1404_u16, r#"Toor Technologies LLC"#), + (1405_u16, r#"Instinct Performance"#), + (1406_u16, r#"Beco, Inc"#), + (1407_u16, r#"Scuf Gaming International, LLC"#), + (1408_u16, r#"ARANZ Medical Limited"#), + (1409_u16, r#"LYS TECHNOLOGIES LTD"#), + (1410_u16, r#"Breakwall Analytics, LLC"#), + (1411_u16, r#"Code Blue Communications"#), + (1412_u16, r#"Gira Giersiepen GmbH & Co. KG"#), + (1413_u16, r#"Hearing Lab Technology"#), + (1414_u16, r#"LEGRAND"#), + (1415_u16, r#"Derichs GmbH"#), + (1416_u16, r#"ALT-TEKNIK LLC"#), + (1417_u16, r#"Star Technologies"#), + (1418_u16, r#"START TODAY CO.,LTD."#), + (1419_u16, r#"Maxim Integrated Products"#), + (1420_u16, r#"MERCK Kommanditgesellschaft auf Aktien"#), + (1421_u16, r#"Jungheinrich Aktiengesellschaft"#), + (1422_u16, r#"Oculus VR, LLC"#), + (1423_u16, r#"HENDON SEMICONDUCTORS PTY LTD"#), + (1424_u16, r#"Pur3 Ltd"#), + (1425_u16, r#"Viasat Group S.p.A."#), + (1426_u16, r#"IZITHERM"#), + (1427_u16, r#"Spaulding Clinical Research"#), + (1428_u16, r#"Kohler Company"#), + (1429_u16, r#"Inor Process AB"#), + (1430_u16, r#"My Smart Blinds"#), + (1431_u16, r#"RadioPulse Inc"#), + (1432_u16, r#"rapitag GmbH"#), + (1433_u16, r#"Lazlo326, LLC."#), + (1434_u16, r#"Teledyne Lecroy, Inc."#), + (1435_u16, r#"Dataflow Systems Limited"#), + (1436_u16, r#"Macrogiga Electronics"#), + (1437_u16, r#"Tandem Diabetes Care"#), + (1438_u16, r#"Polycom, Inc."#), + (1439_u16, r#"Fisher & Paykel Healthcare"#), + (1440_u16, r#"RCP Software Oy"#), + (1441_u16, r#"Shanghai Xiaoyi Technology Co.,Ltd."#), + (1442_u16, r#"ADHERIUM(NZ) LIMITED"#), + (1443_u16, r#"Axiomware Systems Incorporated"#), + (1444_u16, r#"O. E. M. Controls, Inc."#), + (1445_u16, r#"Kiiroo BV"#), + (1446_u16, r#"Telecon Mobile Limited"#), + (1447_u16, r#"Sonos Inc"#), + (1448_u16, r#"Tom Allebrandi Consulting"#), + (1449_u16, r#"Monidor"#), + (1450_u16, r#"Tramex Limited"#), + (1451_u16, r#"Nofence AS"#), + (1452_u16, r#"GoerTek Dynaudio Co., Ltd."#), + (1453_u16, r#"INIA"#), + (1454_u16, r#"CARMATE MFG.CO.,LTD"#), + (1455_u16, r#"OV LOOP, INC. (formerly ONvocal)"#), + (1456_u16, r#"NewTec GmbH"#), + (1457_u16, r#"Medallion Instrumentation Systems"#), + (1458_u16, r#"CAREL INDUSTRIES S.P.A."#), + (1459_u16, r#"Parabit Systems, Inc."#), + (1460_u16, r#"White Horse Scientific ltd"#), + (1461_u16, r#"verisilicon"#), + (1462_u16, r#"Elecs Industry Co.,Ltd."#), + (1463_u16, r#"Beijing Pinecone Electronics Co.,Ltd."#), + (1464_u16, r#"Ambystoma Labs Inc."#), + (1465_u16, r#"Suzhou Pairlink Network Technology"#), + (1466_u16, r#"igloohome"#), + (1467_u16, r#"Oxford Metrics plc"#), + (1468_u16, r#"Leviton Mfg. Co., Inc."#), + (1469_u16, r#"ULC Robotics Inc."#), + (1470_u16, r#"RFID Global by Softwork SrL"#), + (1471_u16, r#"Real-World-Systems Corporation"#), + (1472_u16, r#"Nalu Medical, Inc."#), + (1473_u16, r#"P.I.Engineering"#), + (1474_u16, r#"Grote Industries"#), + (1475_u16, r#"Runtime, Inc."#), + (1476_u16, r#"Codecoup sp. z o.o. sp. k."#), + (1477_u16, r#"SELVE GmbH & Co. KG"#), + (1478_u16, r#"Smart Animal Training Systems, LLC"#), + (1479_u16, r#"Lippert Components, INC"#), + (1480_u16, r#"SOMFY SAS"#), + (1481_u16, r#"TBS Electronics B.V."#), + (1482_u16, r#"MHL Custom Inc"#), + (1483_u16, r#"LucentWear LLC"#), + (1484_u16, r#"WATTS ELECTRONICS"#), + (1485_u16, r#"RJ Brands LLC"#), + (1486_u16, r#"V-ZUG Ltd"#), + (1487_u16, r#"Biowatch SA"#), + (1488_u16, r#"Anova Applied Electronics"#), + (1489_u16, r#"Lindab AB"#), + (1490_u16, r#"frogblue TECHNOLOGY GmbH"#), + (1491_u16, r#"Acurable Limited"#), + (1492_u16, r#"LAMPLIGHT Co., Ltd."#), + (1493_u16, r#"TEGAM, Inc."#), + (1494_u16, r#"Zhuhai Jieli technology Co.,Ltd"#), + (1495_u16, r#"modum.io AG"#), + (1496_u16, r#"Farm Jenny LLC"#), + (1497_u16, r#"Toyo Electronics Corporation"#), + (1498_u16, r#"Applied Neural Research Corp"#), + (1499_u16, r#"Avid Identification Systems, Inc."#), + (1500_u16, r#"Petronics Inc."#), + (1501_u16, r#"essentim GmbH"#), + (1502_u16, r#"QT Medical INC."#), + (1503_u16, r#"VIRTUALCLINIC.DIRECT LIMITED"#), + (1504_u16, r#"Viper Design LLC"#), + (1505_u16, r#"Human, Incorporated"#), + (1506_u16, r#"stAPPtronics GmbH"#), + (1507_u16, r#"Elemental Machines, Inc."#), + (1508_u16, r#"Taiyo Yuden Co., Ltd"#), + (1509_u16, r#"INEO ENERGY& SYSTEMS"#), + (1510_u16, r#"Motion Instruments Inc."#), + (1511_u16, r#"PressurePro"#), + (1512_u16, r#"COWBOY"#), + (1513_u16, r#"iconmobile GmbH"#), + (1514_u16, r#"ACS-Control-System GmbH"#), + (1515_u16, r#"Bayerische Motoren Werke AG"#), + (1516_u16, r#"Gycom Svenska AB"#), + (1517_u16, r#"Fuji Xerox Co., Ltd"#), + (1518_u16, r#"Glide Inc."#), + (1519_u16, r#"SIKOM AS"#), + (1520_u16, r#"beken"#), + (1521_u16, r#"The Linux Foundation"#), + (1522_u16, r#"Try and E CO.,LTD."#), + (1523_u16, r#"SeeScan"#), + (1524_u16, r#"Clearity, LLC"#), + (1525_u16, r#"GS TAG"#), + (1526_u16, r#"DPTechnics"#), + (1527_u16, r#"TRACMO, INC."#), + (1528_u16, r#"Anki Inc."#), + (1529_u16, r#"Hagleitner Hygiene International GmbH"#), + (1530_u16, r#"Konami Sports Life Co., Ltd."#), + (1531_u16, r#"Arblet Inc."#), + (1532_u16, r#"Masbando GmbH"#), + (1533_u16, r#"Innoseis"#), + (1534_u16, r#"Niko nv"#), + (1535_u16, r#"Wellnomics Ltd"#), + (1536_u16, r#"iRobot Corporation"#), + (1537_u16, r#"Schrader Electronics"#), + (1538_u16, r#"Geberit International AG"#), + (1539_u16, r#"Fourth Evolution Inc"#), + (1540_u16, r#"Cell2Jack LLC"#), + (1541_u16, r#"FMW electronic Futterer u. Maier-Wolf OHG"#), + (1542_u16, r#"John Deere"#), + (1543_u16, r#"Rookery Technology Ltd"#), + (1544_u16, r#"KeySafe-Cloud"#), + (1545_u16, r#"BUCHI Labortechnik AG"#), + (1546_u16, r#"IQAir AG"#), + (1547_u16, r#"Triax Technologies Inc"#), + (1548_u16, r#"Vuzix Corporation"#), + (1549_u16, r#"TDK Corporation"#), + (1550_u16, r#"Blueair AB"#), + (1551_u16, r#"Signify Netherlands"#), + (1552_u16, r#"ADH GUARDIAN USA LLC"#), + (1553_u16, r#"Beurer GmbH"#), + (1554_u16, r#"Playfinity AS"#), + (1555_u16, r#"Hans Dinslage GmbH"#), + (1556_u16, r#"OnAsset Intelligence, Inc."#), + (1557_u16, r#"INTER ACTION Corporation"#), + (1558_u16, r#"OS42 UG (haftungsbeschraenkt)"#), + (1559_u16, r#"WIZCONNECTED COMPANY LIMITED"#), + (1560_u16, r#"Audio-Technica Corporation"#), + (1561_u16, r#"Six Guys Labs, s.r.o."#), + (1562_u16, r#"R.W. Beckett Corporation"#), + (1563_u16, r#"silex technology, inc."#), + (1564_u16, r#"Univations Limited"#), + (1565_u16, r#"SENS Innovation ApS"#), + (1566_u16, r#"Diamond Kinetics, Inc."#), + (1567_u16, r#"Phrame Inc."#), + (1568_u16, r#"Forciot Oy"#), + (1569_u16, r#"Noordung d.o.o."#), + (1570_u16, r#"Beam Labs, LLC"#), + (1571_u16, r#"Philadelphia Scientific (U.K.) Limited"#), + (1572_u16, r#"Biovotion AG"#), + (1573_u16, r#"Square Panda, Inc."#), + (1574_u16, r#"Amplifico"#), + (1575_u16, r#"WEG S.A."#), + (1576_u16, r#"Ensto Oy"#), + (1577_u16, r#"PHONEPE PVT LTD"#), + (1578_u16, r#"Lunatico Astronomia SL"#), + (1579_u16, r#"MinebeaMitsumi Inc."#), + (1580_u16, r#"ASPion GmbH"#), + (1581_u16, r#"Vossloh-Schwabe Deutschland GmbH"#), + (1582_u16, r#"Procept"#), + (1583_u16, r#"ONKYO Corporation"#), + (1584_u16, r#"Asthrea D.O.O."#), + (1585_u16, r#"Fortiori Design LLC"#), + (1586_u16, r#"Hugo Muller GmbH & Co KG"#), + (1587_u16, r#"Wangi Lai PLT"#), + (1588_u16, r#"Fanstel Corp"#), + (1589_u16, r#"Crookwood"#), + (1590_u16, r#"ELECTRONICA INTEGRAL DE SONIDO S.A."#), + (1591_u16, r#"GiP Innovation Tools GmbH"#), + (1592_u16, r#"LX SOLUTIONS PTY LIMITED"#), + (1593_u16, r#"Shenzhen Minew Technologies Co., Ltd."#), + (1594_u16, r#"Prolojik Limited"#), + (1595_u16, r#"Kromek Group Plc"#), + (1596_u16, r#"Contec Medical Systems Co., Ltd."#), + (1597_u16, r#"Xradio Technology Co.,Ltd."#), + (1598_u16, r#"The Indoor Lab, LLC"#), + (1599_u16, r#"LDL TECHNOLOGY"#), + (1600_u16, r#"Parkifi"#), + (1601_u16, r#"Revenue Collection Systems FRANCE SAS"#), + (1602_u16, r#"Bluetrum Technology Co.,Ltd"#), + (1603_u16, r#"makita corporation"#), + (1604_u16, r#"Apogee Instruments"#), + (1605_u16, r#"BM3"#), + (1606_u16, r#"SGV Group Holding GmbH & Co. KG"#), + (1607_u16, r#"MED-EL"#), + (1608_u16, r#"Ultune Technologies"#), + (1609_u16, r#"Ryeex Technology Co.,Ltd."#), + (1610_u16, r#"Open Research Institute, Inc."#), + (1611_u16, r#"Scale-Tec, Ltd"#), + (1612_u16, r#"Zumtobel Group AG"#), + (1613_u16, r#"iLOQ Oy"#), + (1614_u16, r#"KRUXWorks Technologies Private Limited"#), + (1615_u16, r#"Digital Matter Pty Ltd"#), + (1616_u16, r#"Coravin, Inc."#), + (1617_u16, r#"Stasis Labs, Inc."#), + (1618_u16, r#"ITZ Innovations- und Technologiezentrum GmbH"#), + (1619_u16, r#"Meggitt SA"#), + (1620_u16, r#"Ledlenser GmbH & Co. KG"#), + (1621_u16, r#"Renishaw PLC"#), + (1622_u16, r#"ZhuHai AdvanPro Technology Company Limited"#), + (1623_u16, r#"Meshtronix Limited"#), + (1624_u16, r#"Payex Norge AS"#), + (1625_u16, r#"UnSeen Technologies Oy"#), + (1626_u16, r#"Zound Industries International AB"#), + (1627_u16, r#"Sesam Solutions BV"#), + (1628_u16, r#"PixArt Imaging Inc."#), + (1629_u16, r#"Panduit Corp."#), + (1630_u16, r#"Alo AB"#), + (1631_u16, r#"Ricoh Company Ltd"#), + (1632_u16, r#"RTC Industries, Inc."#), + (1633_u16, r#"Mode Lighting Limited"#), + (1634_u16, r#"Particle Industries, Inc."#), + (1635_u16, r#"Advanced Telemetry Systems, Inc."#), + (1636_u16, r#"RHA TECHNOLOGIES LTD"#), + (1637_u16, r#"Pure International Limited"#), + (1638_u16, r#"WTO Werkzeug-Einrichtungen GmbH"#), + (1639_u16, r#"Spark Technology Labs Inc."#), + (1640_u16, r#"Bleb Technology srl"#), + (1641_u16, r#"Livanova USA, Inc."#), + (1642_u16, r#"Brady Worldwide Inc."#), + (1643_u16, r#"DewertOkin GmbH"#), + (1644_u16, r#"Ztove ApS"#), + (1645_u16, r#"Venso EcoSolutions AB"#), + (1646_u16, r#"Eurotronik Kranj d.o.o."#), + (1647_u16, r#"Hug Technology Ltd"#), + (1648_u16, r#"Gema Switzerland GmbH"#), + (1649_u16, r#"Buzz Products Ltd."#), + (1650_u16, r#"Kopi"#), + (1651_u16, r#"Innova Ideas Limited"#), + (1652_u16, r#"BeSpoon"#), + (1653_u16, r#"Deco Enterprises, Inc."#), + (1654_u16, r#"Expai Solutions Private Limited"#), + (1655_u16, r#"Innovation First, Inc."#), + (1656_u16, r#"SABIK Offshore GmbH"#), + (1657_u16, r#"4iiii Innovations Inc."#), + (1658_u16, r#"The Energy Conservatory, Inc."#), + (1659_u16, r#"I.FARM, INC."#), + (1660_u16, r#"Tile, Inc."#), + (1661_u16, r#"Form Athletica Inc."#), + (1662_u16, r#"MbientLab Inc"#), + (1663_u16, r#"NETGRID S.N.C. DI BISSOLI MATTEO, CAMPOREALE SIMONE, TOGNETTI FEDERICO"#), + (1664_u16, r#"Mannkind Corporation"#), + (1665_u16, r#"Trade FIDES a.s."#), + (1666_u16, r#"Photron Limited"#), + (1667_u16, r#"Eltako GmbH"#), + (1668_u16, r#"Dermalapps, LLC"#), + (1669_u16, r#"Greenwald Industries"#), + (1670_u16, r#"inQs Co., Ltd."#), + (1671_u16, r#"Cherry GmbH"#), + (1672_u16, r#"Amsted Digital Solutions Inc."#), + (1673_u16, r#"Tacx b.v."#), + (1674_u16, r#"Raytac Corporation"#), + (1675_u16, r#"Jiangsu Teranovo Tech Co., Ltd."#), + (1676_u16, r#"Changzhou Sound Dragon Electronics and Acoustics Co., Ltd"#), + (1677_u16, r#"JetBeep Inc."#), + (1678_u16, r#"Razer Inc."#), + (1679_u16, r#"JRM Group Limited"#), + (1680_u16, r#"Eccrine Systems, Inc."#), + (1681_u16, r#"Curie Point AB"#), + (1682_u16, r#"Georg Fischer AG"#), + (1683_u16, r#"Hach - Danaher"#), + (1684_u16, r#"T&A Laboratories LLC"#), + (1685_u16, r#"Koki Holdings Co., Ltd."#), + (1686_u16, r#"Gunakar Private Limited"#), + (1687_u16, r#"Stemco Products Inc"#), + (1688_u16, r#"Wood IT Security, LLC"#), + (1689_u16, r#"RandomLab SAS"#), + (1690_u16, r#"Adero, Inc. (formerly as TrackR, Inc.)"#), + (1691_u16, r#"Dragonchip Limited"#), + (1692_u16, r#"Noomi AB"#), + (1693_u16, r#"Vakaros LLC"#), + (1694_u16, r#"Delta Electronics, Inc."#), + (1695_u16, r#"FlowMotion Technologies AS"#), + (1696_u16, r#"OBIQ Location Technology Inc."#), + (1697_u16, r#"Cardo Systems, Ltd"#), + (1698_u16, r#"Globalworx GmbH"#), + (1699_u16, r#"Nymbus, LLC"#), + (1700_u16, r#"Sanyo Techno Solutions Tottori Co., Ltd."#), + (1701_u16, r#"TEKZITEL PTY LTD"#), + (1702_u16, r#"Roambee Corporation"#), + (1703_u16, r#"Chipsea Technologies (ShenZhen) Corp."#), + (1704_u16, r#"GD Midea Air-Conditioning Equipment Co., Ltd."#), + (1705_u16, r#"Soundmax Electronics Limited"#), + (1706_u16, r#"Produal Oy"#), + (1707_u16, r#"HMS Industrial Networks AB"#), + (1708_u16, r#"Ingchips Technology Co., Ltd."#), + (1709_u16, r#"InnovaSea Systems Inc."#), + (1710_u16, r#"SenseQ Inc."#), + (1711_u16, r#"Shoof Technologies"#), + (1712_u16, r#"BRK Brands, Inc."#), + (1713_u16, r#"SimpliSafe, Inc."#), + (1714_u16, r#"Tussock Innovation 2013 Limited"#), + (1715_u16, r#"The Hablab ApS"#), + (1716_u16, r#"Sencilion Oy"#), + (1717_u16, r#"Wabilogic Ltd."#), + (1718_u16, r#"Sociometric Solutions, Inc."#), + (1719_u16, r#"iCOGNIZE GmbH"#), + (1720_u16, r#"ShadeCraft, Inc"#), + (1721_u16, r#"Beflex Inc."#), + (1722_u16, r#"Beaconzone Ltd"#), + (1723_u16, r#"Leaftronix Analogic Solutions Private Limited"#), + (1724_u16, r#"TWS Srl"#), + (1725_u16, r#"ABB Oy"#), + (1726_u16, r#"HitSeed Oy"#), + (1727_u16, r#"Delcom Products Inc."#), + (1728_u16, r#"CAME S.p.A."#), + (1729_u16, r#"Alarm.com Holdings, Inc"#), + (1730_u16, r#"Measurlogic Inc."#), + (1731_u16, r#"King I Electronics.Co.,Ltd"#), + (1732_u16, r#"Dream Labs GmbH"#), + (1733_u16, r#"Urban Compass, Inc"#), + (1734_u16, r#"Simm Tronic Limited"#), + (1735_u16, r#"Somatix Inc"#), + (1736_u16, r#"Storz & Bickel GmbH & Co. KG"#), + (1737_u16, r#"MYLAPS B.V."#), + (1738_u16, r#"Shenzhen Zhongguang Infotech Technology Development Co., Ltd"#), + (1739_u16, r#"Dyeware, LLC"#), + (1740_u16, r#"Dongguan SmartAction Technology Co.,Ltd."#), + (1741_u16, r#"DIG Corporation"#), + (1742_u16, r#"FIOR & GENTZ"#), + (1743_u16, r#"Belparts N.V."#), + (1744_u16, r#"Etekcity Corporation"#), + (1745_u16, r#"Meyer Sound Laboratories, Incorporated"#), + (1746_u16, r#"CeoTronics AG"#), + (1747_u16, r#"TriTeq Lock and Security, LLC"#), + (1748_u16, r#"DYNAKODE TECHNOLOGY PRIVATE LIMITED"#), + (1749_u16, r#"Sensirion AG"#), + (1750_u16, r#"JCT Healthcare Pty Ltd"#), + (1751_u16, r#"FUBA Automotive Electronics GmbH"#), + (1752_u16, r#"AW Company"#), + (1753_u16, r#"Shanghai Mountain View Silicon Co.,Ltd."#), + (1754_u16, r#"Zliide Technologies ApS"#), + (1755_u16, r#"Automatic Labs, Inc."#), + (1756_u16, r#"Industrial Network Controls, LLC"#), + (1757_u16, r#"Intellithings Ltd."#), + (1758_u16, r#"Navcast, Inc."#), + (1759_u16, r#"Hubbell Lighting, Inc."#), + (1760_u16, r#"Avaya "#), + (1761_u16, r#"Milestone AV Technologies LLC"#), + (1762_u16, r#"Alango Technologies Ltd"#), + (1763_u16, r#"Spinlock Ltd"#), + (1764_u16, r#"Aluna"#), + (1765_u16, r#"OPTEX CO.,LTD."#), + (1766_u16, r#"NIHON DENGYO KOUSAKU"#), + (1767_u16, r#"VELUX A/S"#), + (1768_u16, r#"Almendo Technologies GmbH"#), + (1769_u16, r#"Zmartfun Electronics, Inc."#), + (1770_u16, r#"SafeLine Sweden AB"#), + (1771_u16, r#"Houston Radar LLC"#), + (1772_u16, r#"Sigur"#), + (1773_u16, r#"J Neades Ltd"#), + (1774_u16, r#"Avantis Systems Limited"#), + (1775_u16, r#"ALCARE Co., Ltd."#), + (1776_u16, r#"Chargy Technologies, SL"#), + (1777_u16, r#"Shibutani Co., Ltd."#), + (1778_u16, r#"Trapper Data AB"#), + (1779_u16, r#"Alfred International Inc."#), + (1780_u16, r#"Near Field Solutions Ltd"#), + (1781_u16, r#"Vigil Technologies Inc."#), + (1782_u16, r#"Vitulo Plus BV"#), + (1783_u16, r#"WILKA Schliesstechnik GmbH"#), + (1784_u16, r#"BodyPlus Technology Co.,Ltd"#), + (1785_u16, r#"happybrush GmbH"#), + (1786_u16, r#"Enequi AB"#), + (1787_u16, r#"Sartorius AG"#), + (1788_u16, r#"Tom Communication Industrial Co.,Ltd."#), + (1789_u16, r#"ESS Embedded System Solutions Inc."#), + (1790_u16, r#"Mahr GmbH"#), + (1791_u16, r#"Redpine Signals Inc"#), + (1792_u16, r#"TraqFreq LLC"#), + (1793_u16, r#"PAFERS TECH"#), + (1794_u16, r#"Akciju sabiedriba "SAF TEHNIKA""#), + (1795_u16, r#"Beijing Jingdong Century Trading Co., Ltd."#), + (1796_u16, r#"JBX Designs Inc."#), + (1797_u16, r#"AB Electrolux"#), + (1798_u16, r#"Wernher von Braun Center for ASdvanced Research"#), + (1799_u16, r#"Essity Hygiene and Health Aktiebolag"#), + (1800_u16, r#"Be Interactive Co., Ltd"#), + (1801_u16, r#"Carewear Corp."#), + (1802_u16, r#"Huf Hülsbeck & Fürst GmbH & Co. KG"#), + (1803_u16, r#"Element Products, Inc."#), + (1804_u16, r#"Beijing Winner Microelectronics Co.,Ltd"#), + (1805_u16, r#"SmartSnugg Pty Ltd"#), + (1806_u16, r#"FiveCo Sarl"#), + (1807_u16, r#"California Things Inc."#), + (1808_u16, r#"Audiodo AB"#), + (1809_u16, r#"ABAX AS"#), + (1810_u16, r#"Bull Group Company Limited"#), + (1811_u16, r#"Respiri Limited"#), + (1812_u16, r#"MindPeace Safety LLC"#), + (1813_u16, r#"Vgyan Solutions"#), + (1814_u16, r#"Altonics"#), + (1815_u16, r#"iQsquare BV"#), + (1816_u16, r#"IDIBAIX enginneering"#), + (1817_u16, r#"ECSG"#), + (1818_u16, r#"REVSMART WEARABLE HK CO LTD"#), + (1819_u16, r#"Precor"#), + (1820_u16, r#"F5 Sports, Inc"#), + (1821_u16, r#"exoTIC Systems"#), + (1822_u16, r#"DONGGUAN HELE ELECTRONICS CO., LTD"#), + (1823_u16, r#"Dongguan Liesheng Electronic Co.Ltd"#), + (1824_u16, r#"Oculeve, Inc."#), + (1825_u16, r#"Clover Network, Inc."#), + (1826_u16, r#"Xiamen Eholder Electronics Co.Ltd"#), + (1827_u16, r#"Ford Motor Company"#), + (1828_u16, r#"Guangzhou SuperSound Information Technology Co.,Ltd"#), + (1829_u16, r#"Tedee Sp. z o.o."#), + (1830_u16, r#"PHC Corporation"#), + (1831_u16, r#"STALKIT AS"#), + (1832_u16, r#"Eli Lilly and Company"#), + (1833_u16, r#"SwaraLink Technologies"#), + (1834_u16, r#"JMR embedded systems GmbH"#), + (1835_u16, r#"Bitkey Inc."#), + (1836_u16, r#"GWA Hygiene GmbH"#), + (1837_u16, r#"Safera Oy"#), + (1838_u16, r#"Open Platform Systems LLC"#), + (1839_u16, r#"OnePlus Electronics (Shenzhen) Co., Ltd."#), + (1840_u16, r#"Wildlife Acoustics, Inc."#), + (1841_u16, r#"ABLIC Inc."#), + (1842_u16, r#"Dairy Tech, Inc."#), + (1843_u16, r#"Iguanavation, Inc."#), + (1844_u16, r#"DiUS Computing Pty Ltd"#), + (1845_u16, r#"UpRight Technologies LTD"#), + (1846_u16, r#"FrancisFund, LLC"#), + (1847_u16, r#"LLC Navitek"#), + (1848_u16, r#"Glass Security Pte Ltd"#), + (1849_u16, r#"Jiangsu Qinheng Co., Ltd."#), + (1850_u16, r#"Chandler Systems Inc."#), + (1851_u16, r#"Fantini Cosmi s.p.a."#), + (1852_u16, r#"Acubit ApS"#), + (1853_u16, r#"Beijing Hao Heng Tian Tech Co., Ltd."#), + (1854_u16, r#"Bluepack S.R.L."#), + (1855_u16, r#"Beijing Unisoc Technologies Co., Ltd."#), + (1856_u16, r#"HITIQ LIMITED"#), + (1857_u16, r#"MAC SRL"#), + (1858_u16, r#"DML LLC"#), + (1859_u16, r#"Sanofi"#), + (1860_u16, r#"SOCOMEC"#), + (1861_u16, r#"WIZNOVA, Inc."#), + (1862_u16, r#"Seitec Elektronik GmbH"#), + (1863_u16, r#"OR Technologies Pty Ltd"#), + (1864_u16, r#"GuangZhou KuGou Computer Technology Co.Ltd"#), + (1865_u16, r#"DIAODIAO (Beijing) Technology Co., Ltd."#), + (1866_u16, r#"Illusory Studios LLC"#), + (1867_u16, r#"Sarvavid Software Solutions LLP"#), + (1868_u16, r#"iopool s.a."#), + (1869_u16, r#"Amtech Systems, LLC"#), + (1870_u16, r#"EAGLE DETECTION SA"#), + (1871_u16, r#"MEDIATECH S.R.L."#), + (1872_u16, r#"Hamilton Professional Services of Canada Incorporated"#), + (1873_u16, r#"Changsha JEMO IC Design Co.,Ltd"#), + (1874_u16, r#"Elatec GmbH"#), + (1875_u16, r#"JLG Industries, Inc."#), + (1876_u16, r#"Michael Parkin"#), + (1877_u16, r#"Brother Industries, Ltd"#), + (1878_u16, r#"Lumens For Less, Inc"#), + (1879_u16, r#"ELA Innovation"#), + (1880_u16, r#"umanSense AB"#), + (1881_u16, r#"Shanghai InGeek Cyber Security Co., Ltd."#), + (1882_u16, r#"HARMAN CO.,LTD."#), + (1883_u16, r#"Smart Sensor Devices AB"#), + (1884_u16, r#"Antitronics Inc."#), + (1885_u16, r#"RHOMBUS SYSTEMS, INC."#), + (1886_u16, r#"Katerra Inc."#), + (1887_u16, r#"Remote Solution Co., LTD."#), + (1888_u16, r#"Vimar SpA"#), + (1889_u16, r#"Mantis Tech LLC"#), + (1890_u16, r#"TerOpta Ltd"#), + (1891_u16, r#"PIKOLIN S.L."#), + (1892_u16, r#"WWZN Information Technology Company Limited"#), + (1893_u16, r#"Voxx International"#), + (1894_u16, r#"ART AND PROGRAM, INC."#), + (1895_u16, r#"NITTO DENKO ASIA TECHNICAL CENTRE PTE. LTD."#), + (1896_u16, r#"Peloton Interactive Inc."#), + (1897_u16, r#"Force Impact Technologies"#), + (1898_u16, r#"Dmac Mobile Developments, LLC"#), + (1899_u16, r#"Engineered Medical Technologies"#), + (1900_u16, r#"Noodle Technology inc"#), + (1901_u16, r#"Graesslin GmbH"#), + (1902_u16, r#"WuQi technologies, Inc."#), + (1903_u16, r#"Successful Endeavours Pty Ltd"#), + (1904_u16, r#"InnoCon Medical ApS"#), + (1905_u16, r#"Corvex Connected Safety"#), + (1906_u16, r#"Thirdwayv Inc."#), + (1907_u16, r#"Echoflex Solutions Inc."#), + (1908_u16, r#"C-MAX Asia Limited"#), + (1909_u16, r#"4eBusiness GmbH"#), + (1910_u16, r#"Cyber Transport Control GmbH"#), + (1911_u16, r#"Cue"#), + (1912_u16, r#"KOAMTAC INC."#), + (1913_u16, r#"Loopshore Oy"#), + (1914_u16, r#"Niruha Systems Private Limited"#), + (1915_u16, r#"AmaterZ, Inc."#), + (1916_u16, r#"radius co., ltd."#), + (1917_u16, r#"Sensority, s.r.o."#), + (1918_u16, r#"Sparkage Inc."#), + (1919_u16, r#"Glenview Software Corporation"#), + (1920_u16, r#"Finch Technologies Ltd."#), + (1921_u16, r#"Qingping Technology (Beijing) Co., Ltd."#), + (1922_u16, r#"DeviceDrive AS"#), + (1923_u16, r#"ESEMBER LIMITED LIABILITY COMPANY"#), + (1924_u16, r#"audifon GmbH & Co. KG"#), + (1925_u16, r#"O2 Micro, Inc."#), + (1926_u16, r#"HLP Controls Pty Limited"#), + (1927_u16, r#"Pangaea Solution"#), + (1928_u16, r#"BubblyNet, LLC"#), + (1930_u16, r#"The Wildflower Foundation"#), + (1931_u16, r#"Optikam Tech Inc."#), + (1932_u16, r#"MINIBREW HOLDING B.V"#), + (1933_u16, r#"Cybex GmbH"#), + (1934_u16, r#"FUJIMIC NIIGATA, INC."#), + (1935_u16, r#"Hanna Instruments, Inc."#), + (1936_u16, r#"KOMPAN A/S"#), + (1937_u16, r#"Scosche Industries, Inc."#), + (1938_u16, r#"Provo Craft"#), + (1939_u16, r#"AEV spol. s r.o."#), + (1940_u16, r#"The Coca-Cola Company"#), + (1941_u16, r#"GASTEC CORPORATION"#), + (1942_u16, r#"StarLeaf Ltd"#), + (1943_u16, r#"Water-i.d. GmbH"#), + (1944_u16, r#"HoloKit, Inc."#), + (1945_u16, r#"PlantChoir Inc."#), + (1946_u16, r#"GuangDong Oppo Mobile Telecommunications Corp., Ltd."#), + (1947_u16, r#"CST ELECTRONICS (PROPRIETARY) LIMITED"#), + (1948_u16, r#"Sky UK Limited"#), + (1949_u16, r#"Digibale Pty Ltd"#), + (1950_u16, r#"Smartloxx GmbH"#), + (1951_u16, r#"Pune Scientific LLP"#), + (1952_u16, r#"Regent Beleuchtungskorper AG"#), + (1953_u16, r#"Apollo Neuroscience, Inc."#), + (1954_u16, r#"Roku, Inc."#), + (1955_u16, r#"Comcast Cable"#), + (1956_u16, r#"Xiamen Mage Information Technology Co., Ltd."#), + (1957_u16, r#"RAB Lighting, Inc."#), + (1958_u16, r#"Musen Connect, Inc."#), + (1959_u16, r#"Zume, Inc."#), + (1960_u16, r#"conbee GmbH"#), + (1961_u16, r#"Bruel & Kjaer Sound & Vibration"#), + (1962_u16, r#"The Kroger Co."#), + (1963_u16, r#"Granite River Solutions, Inc."#), + (1964_u16, r#"LoupeDeck Oy"#), + (1965_u16, r#"New H3C Technologies Co.,Ltd"#), + (1966_u16, r#"Aurea Solucoes Tecnologicas Ltda."#), + (1967_u16, r#"Hong Kong Bouffalo Lab Limited"#), + (1968_u16, r#"GV Concepts Inc."#), + (1969_u16, r#"Thomas Dynamics, LLC"#), + (1970_u16, r#"Moeco IOT Inc."#), + (1971_u16, r#"2N TELEKOMUNIKACE a.s."#), + (1972_u16, r#"Hormann KG Antriebstechnik"#), + (1973_u16, r#"CRONO CHIP, S.L."#), + (1974_u16, r#"Soundbrenner Limited"#), + (1975_u16, r#"ETABLISSEMENTS GEORGES RENAULT"#), + (1976_u16, r#"iSwip"#), + (1977_u16, r#"Epona Biotec Limited"#), + (1978_u16, r#"Battery-Biz Inc."#), + (1979_u16, r#"EPIC S.R.L."#), + (1980_u16, r#"KD CIRCUITS LLC"#), + (1981_u16, r#"Genedrive Diagnostics Ltd"#), + (1982_u16, r#"Axentia Technologies AB"#), + (1983_u16, r#"REGULA Ltd."#), + (1984_u16, r#"Biral AG"#), + (1985_u16, r#"A.W. Chesterton Company"#), + (1986_u16, r#"Radinn AB"#), + (1987_u16, r#"CIMTechniques, Inc."#), + (1988_u16, r#"Johnson Health Tech NA"#), + (1989_u16, r#"June Life, Inc."#), + (1990_u16, r#"Bluenetics GmbH"#), + (1991_u16, r#"iaconicDesign Inc."#), + (1992_u16, r#"WRLDS Creations AB"#), + (1993_u16, r#"Skullcandy, Inc."#), + (1994_u16, r#"Modul-System HH AB"#), + (1995_u16, r#"West Pharmaceutical Services, Inc."#), + (1996_u16, r#"Barnacle Systems Inc."#), + (1997_u16, r#"Smart Wave Technologies Canada Inc"#), + (1998_u16, r#"Shanghai Top-Chip Microelectronics Tech. Co., LTD"#), + (1999_u16, r#"NeoSensory, Inc."#), + (2000_u16, r#"Hangzhou Tuya Information Technology Co., Ltd"#), + (2001_u16, r#"Shanghai Panchip Microelectronics Co., Ltd"#), + (2002_u16, r#"React Accessibility Limited"#), + (2003_u16, r#"LIVNEX Co.,Ltd."#), + (2004_u16, r#"Kano Computing Limited"#), + (2005_u16, r#"hoots classic GmbH"#), + (2006_u16, r#"ecobee Inc."#), + (2007_u16, r#"Nanjing Qinheng Microelectronics Co., Ltd"#), + (2008_u16, r#"SOLUTIONS AMBRA INC."#), + (2009_u16, r#"Micro-Design, Inc."#), + (2010_u16, r#"STARLITE Co., Ltd."#), + (2011_u16, r#"Remedee Labs"#), + (2012_u16, r#"ThingOS GmbH"#), + (2013_u16, r#"Linear Circuits"#), + (2014_u16, r#"Unlimited Engineering SL"#), + (2015_u16, r#"Snap-on Incorporated"#), + (2016_u16, r#"Edifier International Limited"#), + (2017_u16, r#"Lucie Labs"#), + (2018_u16, r#"Alfred Kaercher SE & Co. KG"#), + (2019_u16, r#"Audiowise Technology Inc."#), + (2020_u16, r#"Geeksme S.L."#), + (2021_u16, r#"Minut, Inc."#), + (2022_u16, r#"Autogrow Systems Limited"#), + (2023_u16, r#"Komfort IQ, Inc."#), + (2024_u16, r#"Packetcraft, Inc."#), + (2025_u16, r#"Häfele GmbH & Co KG"#), + (2026_u16, r#"ShapeLog, Inc."#), + (2027_u16, r#"NOVABASE S.R.L."#), + (2028_u16, r#"Frecce LLC"#), + (2029_u16, r#"Joule IQ, INC."#), + (2030_u16, r#"KidzTek LLC"#), + (2031_u16, r#"Aktiebolaget Sandvik Coromant"#), + (2032_u16, r#"e-moola.com Pty Ltd"#), + (2033_u16, r#"GSM Innovations Pty Ltd"#), + (2034_u16, r#"SERENE GROUP, INC"#), + (2035_u16, r#"DIGISINE ENERGYTECH CO. LTD."#), + (2036_u16, r#"MEDIRLAB Orvosbiologiai Fejleszto Korlatolt Felelossegu Tarsasag"#), + (2037_u16, r#"Byton North America Corporation"#), + (2038_u16, r#"Shenzhen TonliScience and Technology Development Co.,Ltd"#), + (2039_u16, r#"Cesar Systems Ltd."#), + (2040_u16, r#"quip NYC Inc."#), + (2041_u16, r#"Direct Communication Solutions, Inc."#), + (2042_u16, r#"Klipsch Group, Inc."#), + (2043_u16, r#"Access Co., Ltd"#), + (2044_u16, r#"Renault SA"#), + (2045_u16, r#"JSK CO., LTD."#), + (2046_u16, r#"BIROTA"#), + (2047_u16, r#"maxon motor ltd."#), + (2048_u16, r#"Optek"#), + (2049_u16, r#"CRONUS ELECTRONICS LTD"#), + (2050_u16, r#"NantSound, Inc."#), + (2051_u16, r#"Domintell s.a."#), + (2052_u16, r#"Andon Health Co.,Ltd"#), + (2053_u16, r#"Urbanminded Ltd"#), + (2054_u16, r#"TYRI Sweden AB"#), + (2055_u16, r#"ECD Electronic Components GmbH Dresden"#), + (2056_u16, r#"SISTEMAS KERN, SOCIEDAD ANÓMINA"#), + (2057_u16, r#"Trulli Audio"#), + (2058_u16, r#"Altaneos"#), + (2059_u16, r#"Nanoleaf Canada Limited"#), + (2060_u16, r#"Ingy B.V."#), + (2061_u16, r#"Azbil Co."#), + (2062_u16, r#"TATTCOM LLC"#), + (2063_u16, r#"Paradox Engineering SA"#), + (2064_u16, r#"LECO Corporation"#), + (2065_u16, r#"Becker Antriebe GmbH"#), + (2066_u16, r#"Mstream Technologies., Inc."#), + (2067_u16, r#"Flextronics International USA Inc."#), + (2068_u16, r#"Ossur hf."#), + (2069_u16, r#"SKC Inc"#), + (2070_u16, r#"SPICA SYSTEMS LLC"#), + (2071_u16, r#"Wangs Alliance Corporation"#), + (2072_u16, r#"tatwah SA"#), + (2073_u16, r#"Hunter Douglas Inc"#), + (2074_u16, r#"Shenzhen Conex"#), + (2075_u16, r#"DIM3"#), + (2076_u16, r#"Bobrick Washroom Equipment, Inc."#), + (2077_u16, r#"Potrykus Holdings and Development LLC"#), + (2078_u16, r#"iNFORM Technology GmbH"#), + (2079_u16, r#"eSenseLab LTD"#), + (2080_u16, r#"Brilliant Home Technology, Inc."#), + (2081_u16, r#"INOVA Geophysical, Inc."#), + (2082_u16, r#"adafruit industries"#), + (2083_u16, r#"Nexite Ltd"#), + (2084_u16, r#"8Power Limited"#), + (2085_u16, r#"CME PTE. LTD."#), + (2086_u16, r#"Hyundai Motor Company"#), + (2087_u16, r#"Kickmaker"#), + (2088_u16, r#"Shanghai Suisheng Information Technology Co., Ltd."#), + (2089_u16, r#"HEXAGON"#), + (2090_u16, r#"Mitutoyo Corporation"#), + (2091_u16, r#"shenzhen fitcare electronics Co.,Ltd"#), + (2092_u16, r#"INGICS TECHNOLOGY CO., LTD."#), + (2093_u16, r#"INCUS PERFORMANCE LTD."#), + (2094_u16, r#"ABB S.p.A."#), + (2095_u16, r#"Blippit AB"#), + (2096_u16, r#"Core Health and Fitness LLC"#), + (2097_u16, r#"Foxble, LLC"#), + (2098_u16, r#"Intermotive,Inc."#), + (2099_u16, r#"Conneqtech B.V."#), + (2100_u16, r#"RIKEN KEIKI CO., LTD.,"#), + (2101_u16, r#"Canopy Growth Corporation"#), + (2102_u16, r#"Bitwards Oy"#), + (2103_u16, r#"vivo Mobile Communication Co., Ltd."#), + (2104_u16, r#"Etymotic Research, Inc."#), + (2105_u16, r#"A puissance 3"#), + (2106_u16, r#"BPW Bergische Achsen Kommanditgesellschaft"#), + (2107_u16, r#"Piaggio Fast Forward"#), + (2108_u16, r#"BeerTech LTD"#), + (2109_u16, r#"Tokenize, Inc."#), + (2110_u16, r#"Zorachka LTD"#), + (2111_u16, r#"D-Link Corp."#), + (2112_u16, r#"Down Range Systems LLC"#), + (2113_u16, r#"General Luminaire (Shanghai) Co., Ltd."#), + (2114_u16, r#"Tangshan HongJia electronic technology co., LTD."#), + (2115_u16, r#"FRAGRANCE DELIVERY TECHNOLOGIES LTD"#), + (2116_u16, r#"Pepperl + Fuchs GmbH"#), + (2117_u16, r#"Dometic Corporation"#), + (2118_u16, r#"USound GmbH"#), + (2119_u16, r#"DNANUDGE LIMITED"#), + (2120_u16, r#"JUJU JOINTS CANADA CORP."#), + (2121_u16, r#"Dopple Technologies B.V."#), + (2122_u16, r#"ARCOM"#), + (2123_u16, r#"Biotechware SRL"#), + (2124_u16, r#"ORSO Inc."#), + (2125_u16, r#"SafePort"#), + (2126_u16, r#"Carol Cole Company"#), + (2127_u16, r#"Embedded Fitness B.V."#), + (2128_u16, r#"Yealink (Xiamen) Network Technology Co.,LTD"#), + (2129_u16, r#"Subeca, Inc."#), + (2130_u16, r#"Cognosos, Inc."#), + (2131_u16, r#"Pektron Group Limited"#), + (2132_u16, r#"Tap Sound System"#), + (2133_u16, r#"Helios Hockey, Inc."#), + (2134_u16, r#"Canopy Growth Corporation"#), + (2135_u16, r#"Parsyl Inc"#), + (2136_u16, r#"SOUNDBOKS"#), + (2137_u16, r#"BlueUp"#), + (2138_u16, r#"DAKATECH"#), + (2139_u16, r#"RICOH ELECTRONIC DEVICES CO., LTD."#), + (2140_u16, r#"ACOS CO.,LTD."#), + (2141_u16, r#"Guilin Zhishen Information Technology Co.,Ltd."#), + (2142_u16, r#"Krog Systems LLC"#), + (2143_u16, r#"COMPEGPS TEAM,SOCIEDAD LIMITADA"#), + (2144_u16, r#"Alflex Products B.V."#), + (2145_u16, r#"SmartSensor Labs Ltd"#), + (2146_u16, r#"SmartDrive Inc."#), + (2147_u16, r#"Yo-tronics Technology Co., Ltd."#), + (2148_u16, r#"Rafaelmicro"#), + (2149_u16, r#"Emergency Lighting Products Limited"#), + (2150_u16, r#"LAONZ Co.,Ltd"#), + (2151_u16, r#"Western Digital Techologies, Inc."#), + (2152_u16, r#"WIOsense GmbH & Co. KG"#), + (2153_u16, r#"EVVA Sicherheitstechnologie GmbH"#), + (2154_u16, r#"Odic Incorporated"#), + (2155_u16, r#"Pacific Track, LLC"#), + (2156_u16, r#"Revvo Technologies, Inc."#), + (2157_u16, r#"Biometrika d.o.o."#), + (2158_u16, r#"Vorwerk Elektrowerke GmbH & Co. KG"#), + (2159_u16, r#"Trackunit A/S"#), + (2160_u16, r#"Wyze Labs, Inc"#), + (2161_u16, r#"Dension Elektronikai Kft. (formerly: Dension Audio Systems Ltd.)"#), + (2162_u16, r#"11 Health & Technologies Limited"#), + (2163_u16, r#"Innophase Incorporated"#), + (2164_u16, r#"Treegreen Limited"#), + (2165_u16, r#"Berner International LLC"#), + (2166_u16, r#"SmartResQ ApS"#), + (2167_u16, r#"Tome, Inc."#), + (2168_u16, r#"The Chamberlain Group, Inc."#), + (2169_u16, r#"MIZUNO Corporation"#), + (2170_u16, r#"ZRF, LLC"#), + (2171_u16, r#"BYSTAMP"#), + (2172_u16, r#"Crosscan GmbH"#), + (2173_u16, r#"Konftel AB"#), + (2174_u16, r#"1bar.net Limited"#), + (2175_u16, r#"Phillips Connect Technologies LLC"#), + (2176_u16, r#"imagiLabs AB"#), + (2177_u16, r#"Optalert"#), + (2178_u16, r#"PSYONIC, Inc."#), + (2179_u16, r#"Wintersteiger AG"#), + (2180_u16, r#"Controlid Industria, Comercio de Hardware e Servicos de Tecnologia Ltda"#), + (2181_u16, r#"LEVOLOR, INC."#), + (2182_u16, r#"Xsens Technologies B.V."#), + (2183_u16, r#"Hydro-Gear Limited Partnership"#), + (2184_u16, r#"EnPointe Fencing Pty Ltd"#), + (2185_u16, r#"XANTHIO"#), + (2186_u16, r#"sclak s.r.l."#), + (2187_u16, r#"Tricorder Arraay Technologies LLC"#), + (2188_u16, r#"GB Solution co.,Ltd"#), + (2189_u16, r#"Soliton Systems K.K."#), + (2190_u16, r#"GIGA-TMS INC"#), + (2191_u16, r#"Tait International Limited"#), + (2192_u16, r#"NICHIEI INTEC CO., LTD."#), + (2193_u16, r#"SmartWireless GmbH & Co. KG"#), + (2194_u16, r#"Ingenieurbuero Birnfeld UG (haftungsbeschraenkt)"#), + (2195_u16, r#"Maytronics Ltd"#), + (2196_u16, r#"EPIFIT"#), + (2197_u16, r#"Gimer medical"#), + (2198_u16, r#"Nokian Renkaat Oyj"#), + (2199_u16, r#"Current Lighting Solutions LLC"#), + (2200_u16, r#"Sensibo, Inc."#), + (2201_u16, r#"SFS unimarket AG"#), + (2202_u16, r#"Private limited company "Teltonika""#), + (2203_u16, r#"Saucon Technologies"#), + (2204_u16, r#"Embedded Devices Co. Company"#), + (2205_u16, r#"J-J.A.D.E. Enterprise LLC"#), + (2206_u16, r#"i-SENS, inc."#), + (2207_u16, r#"Witschi Electronic Ltd"#), + (2208_u16, r#"Aclara Technologies LLC"#), + (2209_u16, r#"EXEO TECH CORPORATION"#), + (2210_u16, r#"Epic Systems Co., Ltd."#), + (2211_u16, r#"Hoffmann SE"#), + (2212_u16, r#"Realme Chongqing Mobile Telecommunications Corp., Ltd."#), + (2213_u16, r#"UMEHEAL Ltd"#), + (2214_u16, r#"Intelligenceworks Inc."#), + (2215_u16, r#"TGR 1.618 Limited"#), + (2216_u16, r#"Shanghai Kfcube Inc"#), + (2217_u16, r#"Fraunhofer IIS"#), + (2218_u16, r#"SZ DJI TECHNOLOGY CO.,LTD"#), + (2219_u16, r#"Coburn Technology, LLC"#), + (2220_u16, r#"Topre Corporation"#), + (2221_u16, r#"Kayamatics Limited"#), + (2222_u16, r#"Moticon ReGo AG"#), + (2223_u16, r#"Polidea Sp. z o.o."#), + (2224_u16, r#"Trivedi Advanced Technologies LLC"#), + (2225_u16, r#"CORE|vision BV"#), + (2226_u16, r#"PF SCHWEISSTECHNOLOGIE GMBH"#), + (2227_u16, r#"IONIQ Skincare GmbH & Co. KG"#), + (2228_u16, r#"Sengled Co., Ltd."#), + (2229_u16, r#"TransferFi"#), + (2230_u16, r#"Boehringer Ingelheim Vetmedica GmbH"#), + (2231_u16, r#"ABB Inc"#), + (2232_u16, r#"Check Technology Solutions LLC"#), + (2233_u16, r#"U-Shin Ltd."#), + (2234_u16, r#"HYPER ICE, INC."#), + (2235_u16, r#"Tokai-rika co.,ltd."#), + (2236_u16, r#"Prevayl Limited"#), + (2237_u16, r#"bf1systems limited"#), + (2238_u16, r#"ubisys technologies GmbH"#), + (2239_u16, r#"SIRC Co., Ltd."#), + (2240_u16, r#"Accent Advanced Systems SLU"#), + (2241_u16, r#"Rayden.Earth LTD"#), + (2242_u16, r#"Lindinvent AB"#), + (2243_u16, r#"CHIPOLO d.o.o."#), + (2244_u16, r#"CellAssist, LLC"#), + (2245_u16, r#"J. Wagner GmbH"#), + (2246_u16, r#"Integra Optics Inc"#), + (2247_u16, r#"Monadnock Systems Ltd."#), + (2248_u16, r#"Liteboxer Technologies Inc."#), + (2249_u16, r#"Noventa AG"#), + (2250_u16, r#"Nubia Technology Co.,Ltd."#), + (2251_u16, r#"JT INNOVATIONS LIMITED"#), + (2252_u16, r#"TGM TECHNOLOGY CO., LTD."#), + (2253_u16, r#"ifly"#), + (2254_u16, r#"ZIMI CORPORATION"#), + (2255_u16, r#"betternotstealmybike UG (with limited liability)"#), + (2256_u16, r#"ESTOM Infotech Kft."#), + (2257_u16, r#"Sensovium Inc."#), + (2258_u16, r#"Virscient Limited"#), + (2259_u16, r#"Novel Bits, LLC"#), + (2260_u16, r#"ADATA Technology Co., LTD."#), + (2261_u16, r#"KEYes"#), + (2262_u16, r#"Nome Oy"#), + (2263_u16, r#"Inovonics Corp"#), + (2264_u16, r#"WARES"#), + (2265_u16, r#"Pointr Labs Limited"#), + (2266_u16, r#"Miridia Technology Incorporated"#), + (2267_u16, r#"Tertium Technology"#), + (2268_u16, r#"SHENZHEN AUKEY E BUSINESS CO., LTD"#), + (2269_u16, r#"code-Q"#), + (2270_u16, r#"Tyco Electronics Corporation a TE Connectivity Ltd Company"#), + (2271_u16, r#"IRIS OHYAMA CO.,LTD."#), + (2272_u16, r#"Philia Technology"#), + (2273_u16, r#"KOZO KEIKAKU ENGINEERING Inc."#), + (2274_u16, r#"Shenzhen Simo Technology co. LTD"#), + (2275_u16, r#"Republic Wireless, Inc."#), + (2276_u16, r#"Rashidov ltd"#), + (2277_u16, r#"Crowd Connected Ltd"#), + (2278_u16, r#"Eneso Tecnologia de Adaptacion S.L."#), + (2279_u16, r#"Barrot Technology Limited"#), + (2280_u16, r#"Naonext"#), + (2281_u16, r#"Taiwan Intelligent Home Corp."#), + (2282_u16, r#"COWBELL ENGINEERING CO.,LTD."#), + (2283_u16, r#"Beijing Big Moment Technology Co., Ltd."#), + (2284_u16, r#"Denso Corporation"#), + (2285_u16, r#"IMI Hydronic Engineering International SA"#), + (2286_u16, r#"ASKEY"#), + (2287_u16, r#"Cumulus Digital Systems, Inc"#), + (2288_u16, r#"Joovv, Inc."#), + (2289_u16, r#"The L.S. Starrett Company"#), + (2290_u16, r#"Microoled"#), + (2291_u16, r#"PSP - Pauli Services & Products GmbH"#), + (2292_u16, r#"Kodimo Technologies Company Limited"#), + (2293_u16, r#"Tymtix Technologies Private Limited"#), + (2294_u16, r#"Dermal Photonics Corporation"#), + (2295_u16, r#"MTD Products Inc & Affiliates"#), + (2296_u16, r#"instagrid GmbH"#), + (2297_u16, r#"Spacelabs Medical Inc."#), + (2298_u16, r#"Troo Corporation"#), + (2299_u16, r#"Darkglass Electronics Oy"#), + (2300_u16, r#"Hill-Rom"#), + (2301_u16, r#"BioIntelliSense, Inc."#), + (2302_u16, r#"Ketronixs Sdn Bhd"#), + (2303_u16, r#"Plastimold Products, Inc"#), + (2304_u16, r#"Beijing Zizai Technology Co., LTD."#), + (2305_u16, r#"Lucimed"#), + (2306_u16, r#"TSC Auto-ID Technology Co., Ltd."#), + (2307_u16, r#"DATAMARS, Inc."#), + (2308_u16, r#"SUNCORPORATION"#), + (2309_u16, r#"Yandex Services AG"#), + (2310_u16, r#"Scope Logistical Solutions"#), + (2311_u16, r#"User Hello, LLC"#), + (2312_u16, r#"Pinpoint Innovations Limited"#), + (2313_u16, r#"70mai Co.,Ltd."#), + (2314_u16, r#"Zhuhai Hoksi Technology CO.,LTD"#), + (2315_u16, r#"EMBR labs, INC"#), + (2316_u16, r#"Radiawave Technologies Co.,Ltd."#), + (2317_u16, r#"IOT Invent GmbH"#), + (2318_u16, r#"OPTIMUSIOT TECH LLP"#), + (2319_u16, r#"VC Inc."#), + (2320_u16, r#"ASR Microelectronics (Shanghai) Co., Ltd."#), + (2321_u16, r#"Douglas Lighting Controls Inc."#), + (2322_u16, r#"Nerbio Medical Software Platforms Inc"#), + (2323_u16, r#"Braveheart Wireless, Inc."#), + (2324_u16, r#"INEO-SENSE"#), + (2325_u16, r#"Honda Motor Co., Ltd."#), + (2326_u16, r#"Ambient Sensors LLC"#), + (2327_u16, r#"ASR Microelectronics(ShenZhen)Co., Ltd."#), + (2328_u16, r#"Technosphere Labs Pvt. Ltd."#), + (2329_u16, r#"NO SMD LIMITED"#), + (2330_u16, r#"Albertronic BV"#), + (2331_u16, r#"Luminostics, Inc."#), + (2332_u16, r#"Oblamatik AG"#), + (2333_u16, r#"Innokind, Inc."#), + (2334_u16, r#"Melbot Studios, Sociedad Limitada"#), + (2335_u16, r#"Myzee Technology"#), + (2336_u16, r#"Omnisense Limited"#), + (2337_u16, r#"KAHA PTE. LTD."#), + (2338_u16, r#"Shanghai MXCHIP Information Technology Co., Ltd."#), + (2339_u16, r#"JSB TECH PTE LTD"#), + (2340_u16, r#"Fundacion Tecnalia Research and Innovation"#), + (2341_u16, r#"Yukai Engineering Inc."#), + (2342_u16, r#"Gooligum Technologies Pty Ltd"#), + (2343_u16, r#"ROOQ GmbH"#), + (2344_u16, r#"AiRISTA"#), + (2345_u16, r#"Qingdao Haier Technology Co., Ltd."#), + (2346_u16, r#"Sappl Verwaltungs- und Betriebs GmbH"#), + (2347_u16, r#"TekHome"#), + (2348_u16, r#"PCI Private Limited"#), + (2349_u16, r#"Leggett & Platt, Incorporated"#), + (2350_u16, r#"PS GmbH"#), + (2351_u16, r#"C.O.B.O. SpA"#), + (2352_u16, r#"James Walker RotaBolt Limited"#), + (2353_u16, r#"BREATHINGS Co., Ltd."#), + (2354_u16, r#"BarVision, LLC"#), + (2355_u16, r#"SRAM"#), + (2356_u16, r#"KiteSpring Inc."#), + (2357_u16, r#"Reconnect, Inc."#), + (2358_u16, r#"Elekon AG"#), + (2359_u16, r#"RealThingks GmbH"#), + (2360_u16, r#"Henway Technologies, LTD."#), + (2361_u16, r#"ASTEM Co.,Ltd."#), + (2362_u16, r#"LinkedSemi Microelectronics (Xiamen) Co., Ltd"#), + (2363_u16, r#"ENSESO LLC"#), + (2364_u16, r#"Xenoma Inc."#), + (2365_u16, r#"Adolf Wuerth GmbH & Co KG"#), + (2366_u16, r#"Catalyft Labs, Inc."#), + (2367_u16, r#"JEPICO Corporation"#), + (2368_u16, r#"Hero Workout GmbH"#), + (2369_u16, r#"Rivian Automotive, LLC"#), + (2370_u16, r#"TRANSSION HOLDINGS LIMITED"#), + (2371_u16, r#"Inovonics Corp."#), + (2372_u16, r#"Agitron d.o.o."#), + (2373_u16, r#"Globe (Jiangsu) Co., Ltd"#), + (2374_u16, r#"AMC International Alfa Metalcraft Corporation AG"#), + (2375_u16, r#"First Light Technologies Ltd."#), + (2376_u16, r#"Wearable Link Limited"#), + (2377_u16, r#"Metronom Health Europe"#), + (2378_u16, r#"Zwift, Inc."#), + (2379_u16, r#"Kindeva Drug Delivery L.P."#), + (2380_u16, r#"GimmiSys GmbH"#), + (2381_u16, r#"tkLABS INC."#), + (2382_u16, r#"PassiveBolt, Inc."#), + (2383_u16, r#"Limited Liability Company "Mikrotikls""#), + (2384_u16, r#"Capetech"#), + (2385_u16, r#"PPRS"#), + (2386_u16, r#"Apptricity Corporation"#), + (2387_u16, r#"LogiLube, LLC"#), + (2388_u16, r#"Julbo"#), + (2389_u16, r#"Breville Group"#), + (2390_u16, r#"Kerlink"#), + (2391_u16, r#"Ohsung Electronics"#), + (2392_u16, r#"ZTE Corporation"#), + (2393_u16, r#"HerdDogg, Inc"#), + (2394_u16, r#"Selekt Bilgisayar, lletisim Urunleri lnsaat Sanayi ve Ticaret Limited Sirketi"#), + (2395_u16, r#"Lismore Instruments Limited"#), + (2396_u16, r#"LogiLube, LLC"#), + (2397_u16, r#"ETC"#), + (2398_u16, r#"BioEchoNet inc."#), + (2399_u16, r#"NUANCE HEARING LTD"#), + (2400_u16, r#"Sena Technologies Inc."#), + (2401_u16, r#"Linkura AB"#), + (2402_u16, r#"GL Solutions K.K."#), + (2403_u16, r#"Moonbird BV"#), + (2404_u16, r#"Countrymate Technology Limited"#), + (2405_u16, r#"Asahi Kasei Corporation"#), + (2406_u16, r#"PointGuard, LLC"#), + (2407_u16, r#"Neo Materials and Consulting Inc."#), + (2408_u16, r#"Actev Motors, Inc."#), + (2409_u16, r#"Woan Technology (Shenzhen) Co., Ltd."#), + (2410_u16, r#"dricos, Inc."#), + (2411_u16, r#"Guide ID B.V."#), + (2412_u16, r#"9374-7319 Quebec inc"#), + (2413_u16, r#"Gunwerks, LLC"#), + (2414_u16, r#"Band Industries, inc."#), + (2415_u16, r#"Lund Motion Products, Inc."#), + (2416_u16, r#"IBA Dosimetry GmbH"#), + (2417_u16, r#"GA"#), + (2418_u16, r#"Closed Joint Stock Company "Zavod Flometr" ("Zavod Flometr" CJSC)"#), + (2419_u16, r#"Popit Oy"#), + (2420_u16, r#"ABEYE"#), + (2421_u16, r#"BlueIOT(Beijing) Technology Co.,Ltd"#), + (2422_u16, r#"Fauna Audio GmbH"#), + (2423_u16, r#"TOYOTA motor corporation"#), + (2424_u16, r#"ZifferEins GmbH & Co. KG"#), + (2425_u16, r#"BIOTRONIK SE & Co. KG"#), + (2426_u16, r#"CORE CORPORATION"#), + (2427_u16, r#"CTEK Sweden AB"#), + (2428_u16, r#"Thorley Industries, LLC"#), + (2429_u16, r#"CLB B.V."#), + (2430_u16, r#"SonicSensory Inc"#), + (2431_u16, r#"ISEMAR S.R.L."#), + (2432_u16, r#"DEKRA TESTING AND CERTIFICATION, S.A.U."#), + (2433_u16, r#"Bernard Krone Holding SE & Co.KG"#), + (2434_u16, r#"ELPRO-BUCHS AG"#), + (2435_u16, r#"Feedback Sports LLC"#), + (2436_u16, r#"TeraTron GmbH"#), + (2437_u16, r#"Lumos Health Inc."#), + (2438_u16, r#"Cello Hill, LLC"#), + (2439_u16, r#"TSE BRAKES, INC."#), + (2440_u16, r#"BHM-Tech Produktionsgesellschaft m.b.H"#), + (2441_u16, r#"WIKA Alexander Wiegand SE & Co.KG"#), + (2442_u16, r#"Biovigil"#), + (2443_u16, r#"Mequonic Engineering, S.L."#), + (2444_u16, r#"bGrid B.V."#), + (2445_u16, r#"C3-WIRELESS, LLC"#), + (2446_u16, r#"ADVEEZ"#), + (2447_u16, r#"Aktiebolaget Regin"#), + (2448_u16, r#"Anton Paar GmbH"#), + (2449_u16, r#"Telenor ASA"#), + (2450_u16, r#"Big Kaiser Precision Tooling Ltd"#), + (2451_u16, r#"Absolute Audio Labs B.V."#), + (2452_u16, r#"VT42 Pty Ltd"#), + (2453_u16, r#"Bronkhorst High-Tech B.V."#), + (2454_u16, r#"C. & E. Fein GmbH"#), + (2455_u16, r#"NextMind"#), + (2456_u16, r#"Pixie Dust Technologies, Inc."#), + (2457_u16, r#"eTactica ehf"#), + (2458_u16, r#"New Audio LLC"#), + (2459_u16, r#"Sendum Wireless Corporation"#), + (2460_u16, r#"deister electronic GmbH"#), + (2461_u16, r#"YKK AP Inc."#), + (2462_u16, r#"Step One Limited"#), + (2463_u16, r#"Koya Medical, Inc."#), + (2464_u16, r#"Proof Diagnostics, Inc."#), + (2465_u16, r#"VOS Systems, LLC"#), + (2466_u16, r#"ENGAGENOW DATA SCIENCES PRIVATE LIMITED"#), + (2467_u16, r#"ARDUINO SA"#), + (2468_u16, r#"KUMHO ELECTRICS, INC"#), + (2469_u16, r#"Security Enhancement Systems, LLC"#), + (2470_u16, r#"BEIJING ELECTRIC VEHICLE CO.,LTD"#), + (2471_u16, r#"Paybuddy ApS"#), + (2472_u16, r#"KHN Solutions Inc"#), + (2473_u16, r#"Nippon Ceramic Co.,Ltd."#), + (2474_u16, r#"PHOTODYNAMIC INCORPORATED"#), + (2475_u16, r#"DashLogic, Inc."#), + (2476_u16, r#"Ambiq"#), + (2477_u16, r#"Narhwall Inc."#), + (2478_u16, r#"Pozyx NV"#), + (2479_u16, r#"ifLink Open Community"#), + (2480_u16, r#"Deublin Company, LLC"#), + (2481_u16, r#"BLINQY"#), + (2482_u16, r#"DYPHI"#), + (2483_u16, r#"BlueX Microelectronics Corp Ltd."#), + (2484_u16, r#"PentaLock Aps."#), + (2485_u16, r#"AUTEC Gesellschaft fuer Automationstechnik mbH"#), + (2486_u16, r#"Pegasus Technologies, Inc."#), + (2487_u16, r#"Bout Labs, LLC"#), + (2488_u16, r#"PlayerData Limited"#), + (2489_u16, r#"SAVOY ELECTRONIC LIGHTING"#), + (2490_u16, r#"Elimo Engineering Ltd"#), + (2491_u16, r#"SkyStream Corporation"#), + (2492_u16, r#"Aerosens LLC"#), + (2493_u16, r#"Centre Suisse d'Electronique et de Microtechnique SA"#), + (2494_u16, r#"Vessel Ltd."#), + (2495_u16, r#"Span.IO, Inc."#), + (2496_u16, r#"AnotherBrain inc."#), + (2497_u16, r#"Rosewill"#), + (2498_u16, r#"Universal Audio, Inc."#), + (2499_u16, r#"JAPAN TOBACCO INC."#), + (2500_u16, r#"UVISIO"#), + (2501_u16, r#"HungYi Microelectronics Co.,Ltd."#), + (2502_u16, r#"Honor Device Co., Ltd."#), + (2503_u16, r#"Combustion, LLC"#), + (2504_u16, r#"XUNTONG"#), + (2505_u16, r#"CrowdGlow Ltd"#), + (2506_u16, r#"Mobitrace"#), + (2507_u16, r#"Hx Engineering, LLC"#), + (2508_u16, r#"Senso4s d.o.o."#), + (2509_u16, r#"Blyott"#), + (2510_u16, r#"Julius Blum GmbH"#), + (2511_u16, r#"BlueStreak IoT, LLC"#), + (2512_u16, r#"Chess Wise B.V."#), + (2513_u16, r#"ABLEPAY TECHNOLOGIES AS"#), + (2514_u16, r#"Temperature Sensitive Solutions Systems Sweden AB"#), + (2515_u16, r#"HeartHero, inc."#), + (2516_u16, r#"ORBIS Inc."#), + (2517_u16, r#"GEAR RADIO ELECTRONICS CORP."#), + (2518_u16, r#"EAR TEKNIK ISITME VE ODIOMETRI CIHAZLARI SANAYI VE TICARET ANONIM SIRKETI"#), + (2519_u16, r#"Coyotta"#), + (2520_u16, r#"Synergy Tecnologia em Sistemas Ltda"#), + (2521_u16, r#"VivoSensMedical GmbH"#), + (2522_u16, r#"Nagravision SA"#), + (2523_u16, r#"Bionic Avionics Inc."#), + (2524_u16, r#"AON2 Ltd."#), + (2525_u16, r#"Innoware Development AB"#), + (2526_u16, r#"JLD Technology Solutions, LLC"#), + (2527_u16, r#"Magnus Technology Sdn Bhd"#), + (2528_u16, r#"Preddio Technologies Inc."#), + (2529_u16, r#"Tag-N-Trac Inc"#), + (2530_u16, r#"Wuhan Linptech Co.,Ltd."#), + (2531_u16, r#"Friday Home Aps"#), + (2532_u16, r#"CPS AS"#), + (2533_u16, r#"Mobilogix"#), + (2534_u16, r#"Masonite Corporation"#), + (2535_u16, r#"Kabushikigaisha HANERON"#), + (2536_u16, r#"Melange Systems Pvt. Ltd."#), + (2537_u16, r#"LumenRadio AB"#), + (2538_u16, r#"Athlos Oy"#), + (2539_u16, r#"KEAN ELECTRONICS PTY LTD"#), + (2540_u16, r#"Yukon advanced optics worldwide, UAB"#), + (2541_u16, r#"Sibel Inc."#), + (2542_u16, r#"OJMAR SA"#), + (2543_u16, r#"Steinel Solutions AG"#), + (2544_u16, r#"WatchGas B.V."#), + (2545_u16, r#"OM Digital Solutions Corporation"#), + (2546_u16, r#"Audeara Pty Ltd"#), + (2547_u16, r#"Beijing Zero Zero Infinity Technology Co.,Ltd."#), + (2548_u16, r#"Spectrum Technologies, Inc."#), + (2549_u16, r#"OKI Electric Industry Co., Ltd"#), + (2550_u16, r#"Mobile Action Technology Inc."#), + (2551_u16, r#"SENSATEC Co., Ltd."#), + (2552_u16, r#"R.O. S.R.L."#), + (2553_u16, r#"Hangzhou Yaguan Technology Co. LTD"#), + (2554_u16, r#"Listen Technologies Corporation"#), + (2555_u16, r#"TOITU CO., LTD."#), + (2556_u16, r#"Confidex"#), + (2557_u16, r#"Keep Technologies, Inc."#), + (2558_u16, r#"Lichtvision Engineering GmbH"#), + (2559_u16, r#"AIRSTAR"#), + (2560_u16, r#"Ampler Bikes OU"#), + (2561_u16, r#"Cleveron AS"#), + (2562_u16, r#"Ayxon-Dynamics GmbH"#), + (2563_u16, r#"donutrobotics Co., Ltd."#), + (2564_u16, r#"Flosonics Medical"#), + (2565_u16, r#"Southwire Company, LLC"#), + (2566_u16, r#"Shanghai wuqi microelectronics Co.,Ltd"#), + (2567_u16, r#"Reflow Pty Ltd"#), + (2568_u16, r#"Oras Oy"#), + (2569_u16, r#"ECCT"#), + (2570_u16, r#"Volan Technology Inc."#), + (2571_u16, r#"SIANA Systems"#), + (2572_u16, r#"Shanghai Yidian Intelligent Technology Co., Ltd."#), + (2573_u16, r#"Blue Peacock GmbH"#), + (2574_u16, r#"Roland Corporation"#), + (2575_u16, r#"LIXIL Corporation"#), + (2576_u16, r#"SUBARU Corporation"#), + (2577_u16, r#"Sensolus"#), + (2578_u16, r#"Dyson Technology Limited"#), + (2579_u16, r#"Tec4med LifeScience GmbH"#), + (2580_u16, r#"CROXEL, INC."#), + (2581_u16, r#"Syng Inc"#), + (2582_u16, r#"RIDE VISION LTD"#), + (2583_u16, r#"Plume Design Inc"#), + (2584_u16, r#"Cambridge Animal Technologies Ltd"#), + (2585_u16, r#"Maxell, Ltd."#), + (2586_u16, r#"Link Labs, Inc."#), + (2587_u16, r#"Embrava Pty Ltd"#), + (2588_u16, r#"INPEAK S.C."#), + (2589_u16, r#"API-K"#), + (2590_u16, r#"CombiQ AB"#), + (2591_u16, r#"DeVilbiss Healthcare LLC"#), + (2592_u16, r#"Jiangxi Innotech Technology Co., Ltd"#), + (2593_u16, r#"Apollogic Sp. z o.o."#), + (2594_u16, r#"DAIICHIKOSHO CO., LTD."#), + (2595_u16, r#"BIXOLON CO.,LTD"#), + (2596_u16, r#"Atmosic Technologies, Inc."#), + (2597_u16, r#"Eran Financial Services LLC"#), + (2598_u16, r#"Louis Vuitton"#), + (2599_u16, r#"AYU DEVICES PRIVATE LIMITED"#), + (2600_u16, r#"NanoFlex"#), + (2601_u16, r#"Worthcloud Technology Co.,Ltd"#), + (2602_u16, r#"Yamaha Corporation"#), + (2603_u16, r#"PaceBait IVS"#), + (2604_u16, r#"Shenzhen H&T Intelligent Control Co., Ltd"#), + (2605_u16, r#"Shenzhen Feasycom Technology Co., Ltd."#), + (2606_u16, r#"Zuma Array Limited"#), + (2607_u16, r#"Instamic, Inc."#), + (2608_u16, r#"Air-Weigh"#), + (2609_u16, r#"Nevro Corp."#), + (2610_u16, r#"Pinnacle Technology, Inc."#), + (2611_u16, r#"WMF AG"#), + (2612_u16, r#"Luxer Corporation"#), + (2613_u16, r#"safectory GmbH"#), + (2614_u16, r#"NGK SPARK PLUG CO., LTD."#), + (2615_u16, r#"2587702 Ontario Inc."#), + (2616_u16, r#"Bouffalo Lab (Nanjing)., Ltd."#), + (2617_u16, r#"BLUETICKETING SRL"#), + (2618_u16, r#"Incotex Co. Ltd."#), + (2619_u16, r#"Galileo Technology Limited"#), + (2620_u16, r#"Siteco GmbH"#), + (2621_u16, r#"DELABIE"#), + (2622_u16, r#"Hefei Yunlian Semiconductor Co., Ltd"#), + (2623_u16, r#"Shenzhen Yopeak Optoelectronics Technology Co., Ltd."#), + (2624_u16, r#"GEWISS S.p.A."#), + (2625_u16, r#"OPEX Corporation"#), + (2626_u16, r#"Motionalysis, Inc."#), + (2627_u16, r#"Busch Systems International Inc."#), + (2628_u16, r#"Novidan, Inc."#), + (2629_u16, r#"3SI Security Systems, Inc"#), + (2630_u16, r#"Beijing HC-Infinite Technology Limited"#), + (2631_u16, r#"The Wand Company Ltd"#), + (2632_u16, r#"JRC Mobility Inc."#), + (2633_u16, r#"Venture Research Inc."#), + (2634_u16, r#"Map Large, Inc."#), + (2635_u16, r#"MistyWest Energy and Transport Ltd."#), + (2636_u16, r#"SiFli Technologies (shanghai) Inc."#), + (2637_u16, r#"Lockn Technologies Private Limited"#), + (2638_u16, r#"Toytec Corporation"#), + (2639_u16, r#"VANMOOF Global Holding B.V."#), + (2640_u16, r#"Nextscape Inc."#), + (2641_u16, r#"CSIRO"#), + (2642_u16, r#"Follow Sense Europe B.V."#), + (2643_u16, r#"KKM COMPANY LIMITED"#), + (2644_u16, r#"SQL Technologies Corp."#), + (2645_u16, r#"Inugo Systems Limited"#), + (2646_u16, r#"ambie"#), + (2647_u16, r#"Meizhou Guo Wei Electronics Co., Ltd"#), + (2648_u16, r#"Indigo Diabetes"#), + (2649_u16, r#"TourBuilt, LLC"#), + (2650_u16, r#"Sontheim Industrie Elektronik GmbH"#), + (2651_u16, r#"LEGIC Identsystems AG"#), + (2652_u16, r#"Innovative Design Labs Inc."#), + (2653_u16, r#"MG Energy Systems B.V."#), + (2654_u16, r#"LaceClips llc"#), + (2655_u16, r#"stryker"#), + (2656_u16, r#"DATANG SEMICONDUCTOR TECHNOLOGY CO.,LTD"#), + (2657_u16, r#"Smart Parks B.V."#), + (2658_u16, r#"MOKO TECHNOLOGY Ltd"#), + (2659_u16, r#"Gremsy JSC"#), + (2660_u16, r#"Geopal system A/S"#), + (2661_u16, r#"Lytx, INC."#), + (2662_u16, r#"JUSTMORPH PTE. LTD."#), + (2663_u16, r#"Beijing SuperHexa Century Technology CO. Ltd"#), + (2664_u16, r#"Focus Ingenieria SRL"#), + (2665_u16, r#"HAPPIEST BABY, INC."#), + (2666_u16, r#"Scribble Design Inc."#), + (2667_u16, r#"Olympic Ophthalmics, Inc."#), + (2668_u16, r#"Pokkels"#), + (2669_u16, r#"KUUKANJYOKIN Co.,Ltd."#), + (2670_u16, r#"Pac Sane Limited"#), + (2671_u16, r#"Warner Bros."#), + (2672_u16, r#"Ooma"#), + (2673_u16, r#"Senquip Pty Ltd"#), + (2674_u16, r#"Jumo GmbH & Co. KG"#), + (2675_u16, r#"Innohome Oy"#), + (2676_u16, r#"MICROSON S.A."#), + (2677_u16, r#"Delta Cycle Corporation"#), + (2678_u16, r#"Synaptics Incorporated"#), + (2679_u16, r#"JMD PACIFIC PTE. LTD."#), + (2680_u16, r#"Shenzhen Sunricher Technology Limited"#), + (2681_u16, r#"Webasto SE"#), + (2682_u16, r#"Emlid Limited"#), + (2683_u16, r#"UniqAir Oy"#), + (2684_u16, r#"WAFERLOCK"#), + (2685_u16, r#"Freedman Electronics Pty Ltd"#), + (2686_u16, r#"Keba AG"#), + (2687_u16, r#"Intuity Medical"#), + ] + .into_iter() + .map(|(id, name)| (Uuid16::from_be_bytes(id.to_be_bytes()), name)) + .collect(); +} diff --git a/rust/src/wrapper/assigned_numbers/mod.rs b/rust/src/wrapper/assigned_numbers/mod.rs index becdc11..2584718 100644 --- a/rust/src/wrapper/assigned_numbers/mod.rs +++ b/rust/src/wrapper/assigned_numbers/mod.rs @@ -14,40 +14,8 @@ //! Assigned numbers from the Bluetooth spec. -use crate::wrapper::core::Uuid16; -use lazy_static::lazy_static; -use pyo3::{ - intern, - types::{PyDict, PyModule}, - PyResult, Python, -}; -use std::collections; - +mod company_ids; mod services; +pub use company_ids::COMPANY_IDS; pub use services::SERVICE_IDS; - -lazy_static! { - /// Assigned company IDs - pub static ref COMPANY_IDS: collections::HashMap<Uuid16, String> = load_company_ids() - .expect("Could not load company ids -- are Bumble's Python sources available?"); - -} - -fn load_company_ids() -> PyResult<collections::HashMap<Uuid16, String>> { - // this takes about 4ms on a fast machine -- slower than constructing in rust, but not slow - // enough to worry about - Python::with_gil(|py| { - PyModule::import(py, intern!(py, "bumble.company_ids"))? - .getattr(intern!(py, "COMPANY_IDENTIFIERS"))? - .downcast::<PyDict>()? - .into_iter() - .map(|(k, v)| { - Ok(( - Uuid16::from_be_bytes(k.extract::<u16>()?.to_be_bytes()), - v.str()?.to_str()?.to_string(), - )) - }) - .collect::<PyResult<collections::HashMap<_, _>>>() - }) -} diff --git a/rust/src/wrapper/core.rs b/rust/src/wrapper/core.rs index a55760d..bb171d1 100644 --- a/rust/src/wrapper/core.rs +++ b/rust/src/wrapper/core.rs @@ -59,7 +59,7 @@ impl AdvertisingData { } /// 16-bit UUID -#[derive(PartialEq, Eq, Hash)] +#[derive(PartialEq, Eq, Hash, Clone, Copy)] pub struct Uuid16 { /// Big-endian bytes uuid: [u8; 2], diff --git a/rust/tools/gen_assigned_numbers.rs b/rust/tools/gen_assigned_numbers.rs new file mode 100644 index 0000000..b2c525e --- /dev/null +++ b/rust/tools/gen_assigned_numbers.rs @@ -0,0 +1,97 @@ +// Copyright 2023 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 +// +// http://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. + +//! This tool generates Rust code with assigned number tables from the equivalent Python. + +use pyo3::{ + intern, + types::{PyDict, PyModule}, + PyResult, Python, +}; +use std::{collections, env, fs, path}; + +fn main() -> anyhow::Result<()> { + pyo3::prepare_freethreaded_python(); + let mut dir = path::Path::new(&env::var("CARGO_MANIFEST_DIR")?).to_path_buf(); + dir.push("src/wrapper/assigned_numbers"); + + company_ids(&dir)?; + + Ok(()) +} + +fn company_ids(base_dir: &path::Path) -> anyhow::Result<()> { + let mut sorted_ids = load_company_ids()?.into_iter().collect::<Vec<_>>(); + sorted_ids.sort_by_key(|(id, _name)| *id); + + let mut contents = String::new(); + contents.push_str(LICENSE_HEADER); + contents.push_str("\n\n"); + contents.push_str( + "// auto-generated by gen_assigned_numbers, do not edit + +use crate::wrapper::core::Uuid16; +use lazy_static::lazy_static; +use std::collections; + +lazy_static! { + /// Assigned company IDs + pub static ref COMPANY_IDS: collections::HashMap<Uuid16, &'static str> = [ +", + ); + + for (id, name) in sorted_ids { + contents.push_str(&format!(" ({id}_u16, r#\"{name}\"#),\n")) + } + + contents.push_str( + " ] + .into_iter() + .map(|(id, name)| (Uuid16::from_be_bytes(id.to_be_bytes()), name)) + .collect(); +} +", + ); + + let mut company_ids = base_dir.to_path_buf(); + company_ids.push("company_ids.rs"); + fs::write(&company_ids, contents)?; + + Ok(()) +} + +fn load_company_ids() -> PyResult<collections::HashMap<u16, String>> { + Python::with_gil(|py| { + PyModule::import(py, intern!(py, "bumble.company_ids"))? + .getattr(intern!(py, "COMPANY_IDENTIFIERS"))? + .downcast::<PyDict>()? + .into_iter() + .map(|(k, v)| Ok((k.extract::<u16>()?, v.str()?.to_str()?.to_string()))) + .collect::<PyResult<collections::HashMap<_, _>>>() + }) +} + +const LICENSE_HEADER: &str = r#"// Copyright 2023 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 +// +// http://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."#; diff --git a/tests/at_test.py b/tests/at_test.py new file mode 100644 index 0000000..a0f00dd --- /dev/null +++ b/tests/at_test.py @@ -0,0 +1,35 @@ +# Copyright 2023 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. + +from bumble import at + + +def test_tokenize_parameters(): + assert at.tokenize_parameters(b'1, 2, 3') == [b'1', b',', b'2', b',', b'3'] + assert at.tokenize_parameters(b'"1, 2, 3"') == [b'1, 2, 3'] + assert at.tokenize_parameters(b'(1, "2, 3")') == [b'(', b'1', b',', b'2, 3', b')'] + + +def test_parse_parameters(): + assert at.parse_parameters(b'1, 2, 3') == [b'1', b'2', b'3'] + assert at.parse_parameters(b'1,, 3') == [b'1', b'', b'3'] + assert at.parse_parameters(b'"1, 2, 3"') == [b'1, 2, 3'] + assert at.parse_parameters(b'1, (2, (3))') == [b'1', [b'2', [b'3']]] + assert at.parse_parameters(b'1, (2, "3, 4"), 5') == [b'1', [b'2', b'3, 4'], b'5'] + + +# ----------------------------------------------------------------------------- +if __name__ == '__main__': + test_tokenize_parameters() + test_parse_parameters() diff --git a/tests/self_test.py b/tests/self_test.py index 4c35045..98ce5e8 100644 --- a/tests/self_test.py +++ b/tests/self_test.py @@ -68,13 +68,16 @@ class TwoDevices: ), ] - self.paired = [None, None] + self.paired = [ + asyncio.get_event_loop().create_future(), + asyncio.get_event_loop().create_future(), + ] def on_connection(self, which, connection): self.connections[which] = connection - def on_paired(self, which, keys): - self.paired[which] = keys + def on_paired(self, which: int, keys: PairingKeys): + self.paired[which].set_result(keys) # ----------------------------------------------------------------------------- @@ -323,8 +326,8 @@ async def _test_self_smp_with_configs(pairing_config1, pairing_config2): # Pair await two_devices.devices[0].pair(connection) assert connection.is_encrypted - assert two_devices.paired[0] is not None - assert two_devices.paired[1] is not None + assert await two_devices.paired[0] is not None + assert await two_devices.paired[1] is not None # ----------------------------------------------------------------------------- @@ -527,16 +530,12 @@ async def test_self_smp_over_classic(): two_devices.connections[0].encryption = 1 two_devices.connections[1].encryption = 1 - paired = [ - asyncio.get_event_loop().create_future(), - asyncio.get_event_loop().create_future(), - ] - - def on_pairing(which: int, keys: PairingKeys): - paired[which].set_result(keys) - - two_devices.connections[0].on('pairing', lambda keys: on_pairing(0, keys)) - two_devices.connections[1].on('pairing', lambda keys: on_pairing(1, keys)) + two_devices.connections[0].on( + 'pairing', lambda keys: two_devices.on_paired(0, keys) + ) + two_devices.connections[1].on( + 'pairing', lambda keys: two_devices.on_paired(1, keys) + ) # Mock SMP with patch('bumble.smp.Session', spec=True) as MockSmpSession: @@ -547,7 +546,7 @@ async def test_self_smp_over_classic(): # Start CTKD await two_devices.connections[0].pair() - await asyncio.gather(*paired) + await asyncio.gather(*two_devices.paired) # Phase 2 commands should not be invoked MockSmpSession.send_pairing_confirm_command.assert_not_called() |