]> git.basschouten.com Git - openhab-addons.git/blob
23952c36e277dd21261602b926239704bbcd219e
[openhab-addons.git] /
1 /**
2  * Copyright (c) 2010-2023 Contributors to the openHAB project
3  *
4  * See the NOTICE file(s) distributed with this work for additional
5  * information.
6  *
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
10  *
11  * SPDX-License-Identifier: EPL-2.0
12  */
13 package org.openhab.binding.bluetooth.bluegiga.internal;
14
15 import java.lang.reflect.Constructor;
16 import java.lang.reflect.InvocationTargetException;
17 import java.util.HashMap;
18 import java.util.Map;
19 import java.util.Objects;
20
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;
95
96 /**
97  * Helper class to create BlueGiga BLE Response and Event packets (i.e. packets that we will receive).
98  *
99  * @author Chris Jackson - Initial contribution and API
100  */
101 @NonNullByDefault
102 class BlueGigaResponsePackets {
103
104     private static Logger logger = LoggerFactory.getLogger(BlueGigaResponsePackets.class);
105
106     private static final Map<Integer, Class<?>> PACKETMAP = new HashMap<>();
107
108     static {
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);
179     }
180
181     @Nullable
182     public static BlueGigaResponse getPacket(int[] data) {
183         int cmdClass = data[2];
184         int cmdMethod = data[3];
185         boolean isEvent = (data[0] & 0x80) != 0;
186
187         Class<?> bleClass = PACKETMAP.get(Objects.hash(cmdClass, cmdMethod, isEvent));
188
189         if (bleClass == null) {
190             return null;
191         }
192
193         Constructor<?> ctor;
194
195         try {
196             ctor = bleClass.getConstructor(int[].class);
197             BlueGigaResponse bleFrame = (BlueGigaResponse) ctor.newInstance(data);
198             return bleFrame;
199         } catch (NoSuchMethodException | SecurityException | InstantiationException | IllegalAccessException
200                 | IllegalArgumentException | InvocationTargetException e) {
201             logger.debug("Error instantiating BLE class", e);
202         }
203
204         return null;
205     }
206 }