* Copyright (c) 2024 Huawei Device Co., Ltd.
* 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.
*/
package ohos.ace.plugin.bluetoothplugin;
import ohos.ace.plugin.bluetoothplugin.BluetoothHelper;
import android.bluetooth.BluetoothGattCharacteristic;
import android.bluetooth.BluetoothGattDescriptor;
import android.bluetooth.BluetoothGattServer;
import android.bluetooth.BluetoothGattService;
import java.util.HashMap;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
import ohos.ace.adapter.ALog;
public class CustomGattServer {
private static final String LOG_TAG = "CustomGattServer";
private static final int INVALID_HANDLE = -1;
private static final int INTEGER_SIZE = 2;
private static final int SUB_INDEX = 4;
private static final int SUB_INDEX_END = 8;
private static final String GATT_SERVICE_DIS = "180A";
private static final String GATT_SERVICE_GATTS = "1800";
private static final String GATT_SERVICE_GAP = "1801";
private BluetoothGattServer gattServer_ = null;
private int requestId_;
private HashMap<Integer, Integer> handleInfoMap_ = new HashMap<>();
private HashMap<Integer, BluetoothGattService> bluetoothGattServiceMap_ = new HashMap<>();
private HashMap<Integer, BluetoothGattCharacteristic> BluetoothGattCharacteristicMap_ = new HashMap<>();
private HashMap<Integer, BluetoothGattDescriptor> BluetoothGattDescriptorMap_ = new HashMap<>();
private Lock bluetoothServerMapLock_ = new ReentrantLock();
public CustomGattServer(BluetoothGattServer gattServer) {
gattServer_ = gattServer;
}
public BluetoothGattServer getBluetoothGattServer() {
return gattServer_;
}
public void addBluetoothGattService(int handle, BluetoothGattService bluetoothGattService) {
bluetoothServerMapLock_.lock();
if (bluetoothGattServiceMap_ != null) {
bluetoothGattServiceMap_.put(handle, bluetoothGattService);
}
bluetoothServerMapLock_.unlock();
}
public void removeBluetoothGattService(int handle) {
bluetoothServerMapLock_.lock();
if (bluetoothGattServiceMap_ != null && handleInfoMap_ != null &&
BluetoothGattCharacteristicMap_ != null && BluetoothGattDescriptorMap_ != null) {
bluetoothGattServiceMap_.remove(handle);
if (handleInfoMap_.containsKey(handle)) {
for (int i = handle; i <= handleInfoMap_.get(handle); ++i) {
BluetoothGattCharacteristicMap_.remove(i);
BluetoothGattDescriptorMap_.remove(i);
}
handleInfoMap_.remove(handle);
}
}
bluetoothServerMapLock_.unlock();
}
public BluetoothGattService getBluetoothGattService(int handle) {
return (bluetoothGattServiceMap_ != null) ? bluetoothGattServiceMap_.get(handle) : null;
}
public void addBluetoothGattCharacter(int handle, BluetoothGattCharacteristic BluetoothGattCharacteristic) {
bluetoothServerMapLock_.lock();
if (BluetoothGattCharacteristicMap_ != null) {
BluetoothGattCharacteristicMap_.put(handle, BluetoothGattCharacteristic);
}
bluetoothServerMapLock_.unlock();
}
public BluetoothGattCharacteristic getBluetoothGattCharacter(int handle) {
return (BluetoothGattCharacteristicMap_ != null) ? BluetoothGattCharacteristicMap_.get(handle) : null;
}
public void addBluetoothGattDescriptor(int handle, BluetoothGattDescriptor descriptor) {
bluetoothServerMapLock_.lock();
if (BluetoothGattDescriptorMap_ != null) {
BluetoothGattDescriptorMap_.put(handle, descriptor);
}
bluetoothServerMapLock_.unlock();
}
public BluetoothGattDescriptor getBluetoothGattDescriptor(int handle) {
return (BluetoothGattDescriptorMap_ != null) ? BluetoothGattDescriptorMap_.get(handle) : null;
}
public void addBluetoothHandleInfo(int startHandle, int endHandle) {
bluetoothServerMapLock_.lock();
if (handleInfoMap_ != null) {
handleInfoMap_.put(startHandle, endHandle);
}
bluetoothServerMapLock_.unlock();
}
public boolean serviceIsExist(String uuid) {
if (bluetoothGattServiceMap_ != null) {
for (HashMap.Entry<Integer, BluetoothGattService> entry : bluetoothGattServiceMap_.entrySet()) {
String inputUuid = uuid.substring(SUB_INDEX, SUB_INDEX_END);
String curUuid = entry.getValue().getUuid().toString().substring(SUB_INDEX, SUB_INDEX_END);
if ((inputUuid.equalsIgnoreCase(GATT_SERVICE_DIS) && curUuid.equalsIgnoreCase(GATT_SERVICE_DIS)) ||
(inputUuid.equals(GATT_SERVICE_GATTS) && curUuid.equals(GATT_SERVICE_GATTS)) ||
(inputUuid.equals(GATT_SERVICE_GAP) && curUuid.equals(GATT_SERVICE_GAP))) {
return true;
}
}
}
return false;
}
public Integer[] getServiceHandleScopeByUuid(String uuid) {
Integer[] result = new Integer[INTEGER_SIZE];
if (bluetoothGattServiceMap_ != null) {
for (HashMap.Entry<Integer, BluetoothGattService> entry : bluetoothGattServiceMap_.entrySet()) {
if (entry.getValue().getUuid().toString().equalsIgnoreCase(uuid)) {
result[0] = entry.getKey();
result[1] = handleInfoMap_.get(result[0]);
ALog.i(LOG_TAG, "HandleScope: " + result[0] + " -- " + result[1]);
return result;
}
}
}
return null;
}
public int getCharacteristicHandleByUuid(String serviceUuid, String characteristicUuid) {
int startHandle = getServiceHandleScopeByUuid(serviceUuid)[0];
int endHandle = getServiceHandleScopeByUuid(serviceUuid)[1];
if (BluetoothGattCharacteristicMap_ != null) {
for (int i = startHandle; i <= endHandle; i++) {
if (BluetoothGattCharacteristicMap_.containsKey(i) &&
BluetoothGattCharacteristicMap_.get(i).getUuid().toString().equalsIgnoreCase(characteristicUuid)) {
ALog.i(LOG_TAG, "Characteristic handle is " + i);
return i;
}
}
}
return INVALID_HANDLE;
}
public int getDescriptorHandleByUuid(String serviceUuid, String descriptorUuid) {
int startHandle = getServiceHandleScopeByUuid(serviceUuid)[0];
int endHandle = getServiceHandleScopeByUuid(serviceUuid)[1];
if (BluetoothGattDescriptorMap_ != null) {
for (int i = startHandle; i <= endHandle; i++) {
if (BluetoothGattDescriptorMap_.containsKey(i) &&
BluetoothGattDescriptorMap_.get(i).getUuid().toString().equalsIgnoreCase(descriptorUuid)) {
ALog.i(LOG_TAG, "Descriptor handle is " + i);
return i;
}
}
}
return INVALID_HANDLE;
}
public void setRequestId(int requestId) {
requestId_ = requestId;
}
public int getRequestId() {
return requestId_;
}
}