2 * Copyright (c) 2010-2023 Contributors to the openHAB project
4 * See the NOTICE file(s) distributed with this work for additional
7 * This program and the accompanying materials are made available under the
8 * terms of the Eclipse Public License 2.0 which is available at
9 * http://www.eclipse.org/legal/epl-2.0
11 * SPDX-License-Identifier: EPL-2.0
13 package org.openhab.binding.bluetooth.bluegiga.internal;
15 import java.lang.reflect.Constructor;
16 import java.lang.reflect.InvocationTargetException;
17 import java.util.HashMap;
19 import java.util.Objects;
21 import org.eclipse.jdt.annotation.NonNullByDefault;
22 import org.eclipse.jdt.annotation.Nullable;
23 import org.openhab.binding.bluetooth.bluegiga.internal.command.attributeclient.BlueGigaAttributeValueEvent;
24 import org.openhab.binding.bluetooth.bluegiga.internal.command.attributeclient.BlueGigaAttributeWriteResponse;
25 import org.openhab.binding.bluetooth.bluegiga.internal.command.attributeclient.BlueGigaExecuteWriteResponse;
26 import org.openhab.binding.bluetooth.bluegiga.internal.command.attributeclient.BlueGigaFindByTypeValueResponse;
27 import org.openhab.binding.bluetooth.bluegiga.internal.command.attributeclient.BlueGigaFindInformationFoundEvent;
28 import org.openhab.binding.bluetooth.bluegiga.internal.command.attributeclient.BlueGigaFindInformationResponse;
29 import org.openhab.binding.bluetooth.bluegiga.internal.command.attributeclient.BlueGigaGroupFoundEvent;
30 import org.openhab.binding.bluetooth.bluegiga.internal.command.attributeclient.BlueGigaIndicateConfirmResponse;
31 import org.openhab.binding.bluetooth.bluegiga.internal.command.attributeclient.BlueGigaIndicatedEvent;
32 import org.openhab.binding.bluetooth.bluegiga.internal.command.attributeclient.BlueGigaPrepareWriteResponse;
33 import org.openhab.binding.bluetooth.bluegiga.internal.command.attributeclient.BlueGigaProcedureCompletedEvent;
34 import org.openhab.binding.bluetooth.bluegiga.internal.command.attributeclient.BlueGigaReadByGroupTypeResponse;
35 import org.openhab.binding.bluetooth.bluegiga.internal.command.attributeclient.BlueGigaReadByHandleResponse;
36 import org.openhab.binding.bluetooth.bluegiga.internal.command.attributeclient.BlueGigaReadByTypeResponse;
37 import org.openhab.binding.bluetooth.bluegiga.internal.command.attributeclient.BlueGigaReadLongResponse;
38 import org.openhab.binding.bluetooth.bluegiga.internal.command.attributeclient.BlueGigaReadMultipleResponse;
39 import org.openhab.binding.bluetooth.bluegiga.internal.command.attributeclient.BlueGigaReadMultipleResponseEvent;
40 import org.openhab.binding.bluetooth.bluegiga.internal.command.attributeclient.BlueGigaWriteCommandResponse;
41 import org.openhab.binding.bluetooth.bluegiga.internal.command.attributedb.BlueGigaAttributeStatusEvent;
42 import org.openhab.binding.bluetooth.bluegiga.internal.command.attributedb.BlueGigaReadResponse;
43 import org.openhab.binding.bluetooth.bluegiga.internal.command.attributedb.BlueGigaReadTypeResponse;
44 import org.openhab.binding.bluetooth.bluegiga.internal.command.attributedb.BlueGigaSendAttributesResponse;
45 import org.openhab.binding.bluetooth.bluegiga.internal.command.attributedb.BlueGigaUserReadRequestEvent;
46 import org.openhab.binding.bluetooth.bluegiga.internal.command.attributedb.BlueGigaUserReadResponseResponse;
47 import org.openhab.binding.bluetooth.bluegiga.internal.command.attributedb.BlueGigaUserWriteResponseResponse;
48 import org.openhab.binding.bluetooth.bluegiga.internal.command.attributedb.BlueGigaValueEvent;
49 import org.openhab.binding.bluetooth.bluegiga.internal.command.attributedb.BlueGigaWriteResponse;
50 import org.openhab.binding.bluetooth.bluegiga.internal.command.connection.BlueGigaChannelMapGetResponse;
51 import org.openhab.binding.bluetooth.bluegiga.internal.command.connection.BlueGigaConnectionStatusEvent;
52 import org.openhab.binding.bluetooth.bluegiga.internal.command.connection.BlueGigaDisconnectResponse;
53 import org.openhab.binding.bluetooth.bluegiga.internal.command.connection.BlueGigaDisconnectedEvent;
54 import org.openhab.binding.bluetooth.bluegiga.internal.command.connection.BlueGigaFeatureIndEvent;
55 import org.openhab.binding.bluetooth.bluegiga.internal.command.connection.BlueGigaGetRssiResponse;
56 import org.openhab.binding.bluetooth.bluegiga.internal.command.connection.BlueGigaGetStatusResponse;
57 import org.openhab.binding.bluetooth.bluegiga.internal.command.connection.BlueGigaUpdateResponse;
58 import org.openhab.binding.bluetooth.bluegiga.internal.command.connection.BlueGigaVersionIndEvent;
59 import org.openhab.binding.bluetooth.bluegiga.internal.command.gap.BlueGigaConnectDirectResponse;
60 import org.openhab.binding.bluetooth.bluegiga.internal.command.gap.BlueGigaConnectSelectiveResponse;
61 import org.openhab.binding.bluetooth.bluegiga.internal.command.gap.BlueGigaDiscoverResponse;
62 import org.openhab.binding.bluetooth.bluegiga.internal.command.gap.BlueGigaEndProcedureResponse;
63 import org.openhab.binding.bluetooth.bluegiga.internal.command.gap.BlueGigaScanResponseEvent;
64 import org.openhab.binding.bluetooth.bluegiga.internal.command.gap.BlueGigaSetAdvDataResponse;
65 import org.openhab.binding.bluetooth.bluegiga.internal.command.gap.BlueGigaSetAdvParametersResponse;
66 import org.openhab.binding.bluetooth.bluegiga.internal.command.gap.BlueGigaSetModeResponse;
67 import org.openhab.binding.bluetooth.bluegiga.internal.command.gap.BlueGigaSetScanParametersResponse;
68 import org.openhab.binding.bluetooth.bluegiga.internal.command.security.BlueGigaBondStatusEvent;
69 import org.openhab.binding.bluetooth.bluegiga.internal.command.security.BlueGigaBondingFailEvent;
70 import org.openhab.binding.bluetooth.bluegiga.internal.command.security.BlueGigaDeleteBondingResponse;
71 import org.openhab.binding.bluetooth.bluegiga.internal.command.security.BlueGigaEncryptStartResponse;
72 import org.openhab.binding.bluetooth.bluegiga.internal.command.security.BlueGigaGetBondsResponse;
73 import org.openhab.binding.bluetooth.bluegiga.internal.command.security.BlueGigaPassKeyResponse;
74 import org.openhab.binding.bluetooth.bluegiga.internal.command.security.BlueGigaPasskeyDisplayEvent;
75 import org.openhab.binding.bluetooth.bluegiga.internal.command.security.BlueGigaPasskeyRequestEvent;
76 import org.openhab.binding.bluetooth.bluegiga.internal.command.security.BlueGigaSetBondableModeResponse;
77 import org.openhab.binding.bluetooth.bluegiga.internal.command.security.BlueGigaSetParametersResponse;
78 import org.openhab.binding.bluetooth.bluegiga.internal.command.security.BlueGigaWhitelistBondsResponse;
79 import org.openhab.binding.bluetooth.bluegiga.internal.command.system.BlueGigaAddressGetResponse;
80 import org.openhab.binding.bluetooth.bluegiga.internal.command.system.BlueGigaBootEvent;
81 import org.openhab.binding.bluetooth.bluegiga.internal.command.system.BlueGigaEndpointWatermarkRxEvent;
82 import org.openhab.binding.bluetooth.bluegiga.internal.command.system.BlueGigaEndpointWatermarkTxEvent;
83 import org.openhab.binding.bluetooth.bluegiga.internal.command.system.BlueGigaGetConnectionsResponse;
84 import org.openhab.binding.bluetooth.bluegiga.internal.command.system.BlueGigaGetCountersResponse;
85 import org.openhab.binding.bluetooth.bluegiga.internal.command.system.BlueGigaGetInfoResponse;
86 import org.openhab.binding.bluetooth.bluegiga.internal.command.system.BlueGigaHelloResponse;
87 import org.openhab.binding.bluetooth.bluegiga.internal.command.system.BlueGigaNoLicenseKeyEvent;
88 import org.openhab.binding.bluetooth.bluegiga.internal.command.system.BlueGigaProtocolErrorEvent;
89 import org.openhab.binding.bluetooth.bluegiga.internal.command.system.BlueGigaResetResponse;
90 import org.openhab.binding.bluetooth.bluegiga.internal.command.system.BlueGigaWhitelistAppendResponse;
91 import org.openhab.binding.bluetooth.bluegiga.internal.command.system.BlueGigaWhitelistClearResponse;
92 import org.openhab.binding.bluetooth.bluegiga.internal.command.system.BlueGigaWhitelistRemoveResponse;
93 import org.slf4j.Logger;
94 import org.slf4j.LoggerFactory;
97 * Helper class to create BlueGiga BLE Response and Event packets (i.e. packets that we will receive).
99 * @author Chris Jackson - Initial contribution and API
102 class BlueGigaResponsePackets {
104 private static Logger logger = LoggerFactory.getLogger(BlueGigaResponsePackets.class);
106 private static final Map<Integer, Class<?>> PACKETMAP = new HashMap<>();
109 PACKETMAP.put(Objects.hash(0x00, 0x06, true), BlueGigaProtocolErrorEvent.class);
110 PACKETMAP.put(Objects.hash(0x00, 0x02, true), BlueGigaEndpointWatermarkRxEvent.class);
111 PACKETMAP.put(Objects.hash(0x00, 0x03, true), BlueGigaEndpointWatermarkTxEvent.class);
112 PACKETMAP.put(Objects.hash(0x00, 0x05, true), BlueGigaNoLicenseKeyEvent.class);
113 PACKETMAP.put(Objects.hash(0x04, 0x05, false), BlueGigaAttributeWriteResponse.class);
114 PACKETMAP.put(Objects.hash(0x04, 0x0A, false), BlueGigaExecuteWriteResponse.class);
115 PACKETMAP.put(Objects.hash(0x04, 0x00, false), BlueGigaFindByTypeValueResponse.class);
116 PACKETMAP.put(Objects.hash(0x04, 0x03, false), BlueGigaFindInformationResponse.class);
117 PACKETMAP.put(Objects.hash(0x04, 0x07, false), BlueGigaIndicateConfirmResponse.class);
118 PACKETMAP.put(Objects.hash(0x04, 0x09, false), BlueGigaPrepareWriteResponse.class);
119 PACKETMAP.put(Objects.hash(0x04, 0x01, false), BlueGigaReadByGroupTypeResponse.class);
120 PACKETMAP.put(Objects.hash(0x04, 0x04, false), BlueGigaReadByHandleResponse.class);
121 PACKETMAP.put(Objects.hash(0x04, 0x02, false), BlueGigaReadByTypeResponse.class);
122 PACKETMAP.put(Objects.hash(0x04, 0x08, false), BlueGigaReadLongResponse.class);
123 PACKETMAP.put(Objects.hash(0x04, 0x0B, false), BlueGigaReadMultipleResponse.class);
124 PACKETMAP.put(Objects.hash(0x04, 0x06, false), BlueGigaWriteCommandResponse.class);
125 PACKETMAP.put(Objects.hash(0x04, 0x01, true), BlueGigaProcedureCompletedEvent.class);
126 PACKETMAP.put(Objects.hash(0x04, 0x05, true), BlueGigaAttributeValueEvent.class);
127 PACKETMAP.put(Objects.hash(0x04, 0x04, true), BlueGigaFindInformationFoundEvent.class);
128 PACKETMAP.put(Objects.hash(0x04, 0x02, true), BlueGigaGroupFoundEvent.class);
129 PACKETMAP.put(Objects.hash(0x04, 0x00, true), BlueGigaIndicatedEvent.class);
130 PACKETMAP.put(Objects.hash(0x04, 0x00, true), BlueGigaReadMultipleResponseEvent.class);
131 PACKETMAP.put(Objects.hash(0x02, 0x01, false), BlueGigaReadResponse.class);
132 PACKETMAP.put(Objects.hash(0x02, 0x02, false), BlueGigaReadTypeResponse.class);
133 PACKETMAP.put(Objects.hash(0x02, 0x02, false), BlueGigaSendAttributesResponse.class);
134 PACKETMAP.put(Objects.hash(0x02, 0x03, false), BlueGigaUserReadResponseResponse.class);
135 PACKETMAP.put(Objects.hash(0x02, 0x04, false), BlueGigaUserWriteResponseResponse.class);
136 PACKETMAP.put(Objects.hash(0x02, 0x00, false), BlueGigaWriteResponse.class);
137 PACKETMAP.put(Objects.hash(0x02, 0x02, true), BlueGigaAttributeStatusEvent.class);
138 PACKETMAP.put(Objects.hash(0x02, 0x01, true), BlueGigaUserReadRequestEvent.class);
139 PACKETMAP.put(Objects.hash(0x02, 0x00, true), BlueGigaValueEvent.class);
140 PACKETMAP.put(Objects.hash(0x03, 0x04, false), BlueGigaChannelMapGetResponse.class);
141 PACKETMAP.put(Objects.hash(0x03, 0x00, false), BlueGigaDisconnectResponse.class);
142 PACKETMAP.put(Objects.hash(0x03, 0x01, false), BlueGigaGetRssiResponse.class);
143 PACKETMAP.put(Objects.hash(0x03, 0x07, false), BlueGigaGetStatusResponse.class);
144 PACKETMAP.put(Objects.hash(0x03, 0x02, false), BlueGigaUpdateResponse.class);
145 PACKETMAP.put(Objects.hash(0x03, 0x04, true), BlueGigaDisconnectedEvent.class);
146 PACKETMAP.put(Objects.hash(0x03, 0x02, true), BlueGigaFeatureIndEvent.class);
147 PACKETMAP.put(Objects.hash(0x03, 0x00, true), BlueGigaConnectionStatusEvent.class);
148 PACKETMAP.put(Objects.hash(0x03, 0x01, true), BlueGigaVersionIndEvent.class);
149 PACKETMAP.put(Objects.hash(0x06, 0x07, false), BlueGigaSetScanParametersResponse.class);
150 PACKETMAP.put(Objects.hash(0x06, 0x03, false), BlueGigaConnectDirectResponse.class);
151 PACKETMAP.put(Objects.hash(0x06, 0x05, false), BlueGigaConnectSelectiveResponse.class);
152 PACKETMAP.put(Objects.hash(0x06, 0x02, false), BlueGigaDiscoverResponse.class);
153 PACKETMAP.put(Objects.hash(0x06, 0x08, false), BlueGigaSetAdvParametersResponse.class);
154 PACKETMAP.put(Objects.hash(0x06, 0x09, false), BlueGigaSetAdvDataResponse.class);
155 PACKETMAP.put(Objects.hash(0x06, 0x04, false), BlueGigaEndProcedureResponse.class);
156 PACKETMAP.put(Objects.hash(0x06, 0x01, false), BlueGigaSetModeResponse.class);
157 PACKETMAP.put(Objects.hash(0x06, 0x00, true), BlueGigaScanResponseEvent.class);
158 PACKETMAP.put(Objects.hash(0x05, 0x02, false), BlueGigaDeleteBondingResponse.class);
159 PACKETMAP.put(Objects.hash(0x05, 0x00, false), BlueGigaEncryptStartResponse.class);
160 PACKETMAP.put(Objects.hash(0x05, 0x05, false), BlueGigaGetBondsResponse.class);
161 PACKETMAP.put(Objects.hash(0x05, 0x04, false), BlueGigaPassKeyResponse.class);
162 PACKETMAP.put(Objects.hash(0x05, 0x01, false), BlueGigaSetBondableModeResponse.class);
163 PACKETMAP.put(Objects.hash(0x05, 0x03, false), BlueGigaSetParametersResponse.class);
164 PACKETMAP.put(Objects.hash(0x05, 0x07, false), BlueGigaWhitelistBondsResponse.class);
165 PACKETMAP.put(Objects.hash(0x00, 0x0A, false), BlueGigaWhitelistAppendResponse.class);
166 PACKETMAP.put(Objects.hash(0x00, 0x0B, false), BlueGigaWhitelistRemoveResponse.class);
167 PACKETMAP.put(Objects.hash(0x00, 0x0C, false), BlueGigaWhitelistClearResponse.class);
168 PACKETMAP.put(Objects.hash(0x05, 0x01, true), BlueGigaBondingFailEvent.class);
169 PACKETMAP.put(Objects.hash(0x05, 0x04, true), BlueGigaBondStatusEvent.class);
170 PACKETMAP.put(Objects.hash(0x05, 0x02, true), BlueGigaPasskeyDisplayEvent.class);
171 PACKETMAP.put(Objects.hash(0x05, 0x03, true), BlueGigaPasskeyRequestEvent.class);
172 PACKETMAP.put(Objects.hash(0x00, 0x02, false), BlueGigaAddressGetResponse.class);
173 PACKETMAP.put(Objects.hash(0x00, 0x01, false), BlueGigaHelloResponse.class);
174 PACKETMAP.put(Objects.hash(0x00, 0x00, false), BlueGigaResetResponse.class);
175 PACKETMAP.put(Objects.hash(0x00, 0x06, false), BlueGigaGetConnectionsResponse.class);
176 PACKETMAP.put(Objects.hash(0x00, 0x05, false), BlueGigaGetCountersResponse.class);
177 PACKETMAP.put(Objects.hash(0x00, 0x08, false), BlueGigaGetInfoResponse.class);
178 PACKETMAP.put(Objects.hash(0x00, 0x00, true), BlueGigaBootEvent.class);
182 public static BlueGigaResponse getPacket(int[] data) {
183 int cmdClass = data[2];
184 int cmdMethod = data[3];
185 boolean isEvent = (data[0] & 0x80) != 0;
187 Class<?> bleClass = PACKETMAP.get(Objects.hash(cmdClass, cmdMethod, isEvent));
189 if (bleClass == null) {
196 ctor = bleClass.getConstructor(int[].class);
197 return (BlueGigaResponse) ctor.newInstance(data);
198 } catch (NoSuchMethodException | SecurityException | InstantiationException | IllegalAccessException
199 | IllegalArgumentException | InvocationTargetException e) {
200 logger.debug("Error instantiating BLE class", e);