add ble connection

Signed-off-by: XiYuhao <xiyuhao@huawei.com>
This commit is contained in:
XiYuhao 2021-09-22 10:21:31 +08:00
parent 743c9b0ea2
commit 9449fe28ad
14 changed files with 2442 additions and 53 deletions

View File

@ -0,0 +1,63 @@
/*
* Copyright (c) 2021 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.
*/
#ifndef SOFTBUS_ADAPTER_ATOMIC_H
#define SOFTBUS_ADAPTER_ATOMIC_H
#include "stdbool.h"
#include "stdint.h"
#include "stdio.h"
static inline void SoftBusAtomicAdd32(volatile uint32_t* ptr, uint32_t value)
{
#ifdef _WIN32
InterlockedExchangeAdd(ptr, value);
#elif defined __linux__ || defined __LITEOS__ || defined __APPLE__
__sync_fetch_and_add(ptr, value);
#endif
}
static inline uint32_t SoftBusAtomicAddAndFetch32(volatile uint32_t* ptr, uint32_t value)
{
#ifdef _WIN32
return InterlockedExchangeAdd(ptr, value) + value;
#elif defined __linux__ || defined __LITEOS__ || defined __APPLE__
return __sync_add_and_fetch(ptr, value);
#else
return -1;
#endif
}
static inline void SoftBusAtomicAdd64(uint64_t* ptr, uint64_t value)
{
#ifdef _WIN32
InterlockedExchangeAdd64((volatile long long*)ptr, value);
#elif defined __linux__ || defined __LITEOS__ || defined __APPLE__
__sync_fetch_and_add(ptr, value);
#endif
}
static inline bool SoftBusAtomicCmpAndSwap32(volatile uint32_t* ptr, uint32_t oldValue, uint32_t newValue)
{
#ifdef _WIN32
uint32_t initial = InterlockedCompareExchange(ptr, newValue, oldValue);
return initial == oldValue;
#elif defined __linux__ || defined __LITEOS__ || defined __APPLE__
return __sync_bool_compare_and_swap(ptr, oldValue, newValue);
#else
return false;
#endif
}
#endif // SOFTBUS_ADAPTER_ATOMIC_H

View File

@ -0,0 +1,50 @@
/*
* Copyright (c) 2020-2021 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.
*/
#ifndef SOFTBUS_CPU_H
#define SOFTBUS_CPU_H
#ifdef __cplusplus
#if __cplusplus
extern "C" {
#endif
#endif
#ifdef _WIN32
#define BARRIER() MemoryBarrier()
#define MB() BARRIER()
#define WMB() BARRIER()
#define RMB() BARRIER()
#elif defined __linux__ || defined __LITEOS__ || defined __APPLE__
#define DSB() __asm__ volatile("dsb" ::: "memory")
#define DMB() __asm__ volatile("dmb" ::: "memory")
#define ISB() __asm__ volatile("isb" ::: "memory")
#define BARRIER() __asm__ volatile("" ::: "memory")
#define MB() DMB()
#define WMB() DMB()
#define RMB() DMB()
#else
#define MB()
#define WMB()
#define RMB()
#endif
#ifdef __cplusplus
#if __cplusplus
}
#endif /* __cplusplus */
#endif /* __cplusplus */
#endif // SOFTBUS_CPU_H

View File

@ -94,6 +94,16 @@ enum SoftBusErrNo {
SOFTBUS_BRCONNECTION_CONNECTDEVICE_GETSOCKETIDFAIL,
SOFTBUS_BRCONNECTION_DISCONNECT_NOTFIND,
SOFTBUS_TCPCONNECTION_SOCKET_ERR,
SOFTBUS_BLECONNECTION_REG_GATTS_CALLBACK_FAIL,
SOFTBUS_BLECONNECTION_ADD_SERVICE_FAIL,
SOFTBUS_BLECONNECTION_ADD_CHAR_FAIL,
SOFTBUS_BLECONNECTION_ADD_DES_FAIL,
SOFTBUS_BLECONNECTION_NOT_INIT,
SOFTBUS_BLECONNECTION_NOT_START,
SOFTBUS_BLECONNECTION_GETCONNINFO_ERROR,
SOFTBUS_BLECONNECTION_MTU_OVERFLOW_ERROR,
SOFTBUS_BLECONNECTION_MUTEX_LOCK_ERROR,
SOFTBUS_BLECONNECTION_GATT_CLIENT_NOT_SUPPORT,
SOFTBUS_DISCOVER_ERR_BASE = (-3000),

View File

@ -0,0 +1,332 @@
/*
* Copyright (c) 2021 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.
*/
#ifndef SOFTBUS_QUEUE_H
#define SOFTBUS_QUEUE_H
#include <pthread.h>
#include "securec.h"
#include <stdbool.h>
#include <stdint.h>
#include "softbus_adapter_cpu.h"
#include "softbus_adapter_atomic.h"
#ifdef __cplusplus
#if __cplusplus
extern "C" {
#endif
#endif
typedef enum {
QUEUE_INVAL = -10,
QUEUE_FULL,
QUEUE_EMPTY
} QueueError;
/** @brief Lock free ring queue */
typedef struct {
uint32_t magic;
uint32_t unitNum; /* queue node limit */
uint8_t pad[56]; /* cache line pad */
/* producer status */
struct {
uint32_t size; /* queue size */
uint32_t mask; /* mask(size-1). */
volatile uint32_t head; /* producer head */
volatile uint32_t tail; /* producer tail */
uint8_t pad[48]; /* cache line pad */
} producer;
/* consumer status */
struct {
uint32_t size; /* queue size */
uint32_t mask; /* mask(size-1). */
volatile uint32_t head; /* consumer head */
volatile uint32_t tail; /* consumer tail */
uint8_t pad[48]; /* cache line pad */
} consumer;
uintptr_t nodes[0]; /* queue nodes */
} LockFreeQueue;
extern int32_t QueueSizeCalc(uint32_t unitNum, uint32_t* queueSize);
extern int32_t QueueCountGet(const LockFreeQueue* queue, uint32_t* count);
extern int32_t QueueInit(LockFreeQueue* queue, uint32_t unitNum);
extern LockFreeQueue* CreateQueue(uint32_t unitNum);
static inline int32_t QueueIsEmpty(LockFreeQueue* queue)
{
uint32_t producerTail;
uint32_t consumerTail;
uint32_t mask;
if (queue == NULL) {
return QUEUE_INVAL;
}
producerTail = queue->producer.tail;
consumerTail = queue->consumer.tail;
mask = queue->producer.mask;
if (((producerTail - consumerTail) & mask) == 0) {
return 0;
}
return -1;
}
/** @brief Enqueue operation, thread unsafe */
static inline int32_t QueueSingleProducerEnqueue(LockFreeQueue *queue, void *node)
{
uint32_t producerHead;
uint32_t producerNext;
uint32_t consumerTail;
uint32_t availableCount;
uint32_t mask;
if (queue == NULL || node == NULL) {
return QUEUE_INVAL;
}
mask = queue->producer.mask;
producerHead = queue->producer.head;
RMB();
consumerTail = queue->consumer.tail;
/*
* 1. In normal cases, producerHead > consumerTail and producerHead < consumerTail + mask
* 2. If only producerHead is reversed, producerHead > consumerTail - 0xFFFFFFFF and
* producerHead < consumerTail + mask - 0xFFFFFFFF
* The subtraction of two 32-bit integers results in 32-bit modulo.
* Therefore, the availableCount must be between 0 and the queue length.
*/
availableCount = (mask + consumerTail) - producerHead;
if (availableCount < 1) {
return QUEUE_FULL;
}
producerNext = producerHead + 1;
queue->producer.head = producerNext;
queue->nodes[producerHead & mask] = (uintptr_t)node;
/*
* Make sure that the queue is filled with elements before updating the producer tail.
* Prevents problems when the producer tail is updated first:
* 1. The consumer thinks that the elements in this area have been queued and can be consumed,
* but the consumer actually reads dirty elements.
* 2. The process is abnormal. In this case, elements in the memory block in the queue are dirty elements.
*/
WMB();
queue->producer.tail = producerNext;
return 0;
}
/** @brief Enqueue operation, thread safe */
static inline uint32_t QueueMultiProducerEnqueue(LockFreeQueue* queue, void* node)
{
uint32_t producerHead;
uint32_t producerNext;
uint32_t consumerTail;
uint32_t availableCount;
bool success = false;
uint32_t mask;
if (queue == NULL || node == NULL) {
return QUEUE_INVAL;
}
mask = queue->producer.mask;
do {
producerHead = queue->producer.head;
/*
* Make sure the producer's head is read before the consumer's tail.
* If the consumer tail is read first, then the consumer consumes the queue,and then other producers
* produce the queue, the producer header may cross the consumer tail reversely.
*/
RMB();
consumerTail = queue->consumer.tail;
/*
* 1. In normal cases, producerHead > consumerTail and producerHead < consumerTail + mask
* 2. If only producerHead is reversed, producerHead > consumerTail - 0xFFFFFFFF and
* producerHead < consumerTail + mask - 0xFFFFFFFF
* The subtraction of two 32-bit integers results in 32-bit modulo.
* Therefore, the availableCount must be between 0 and the queue length.
*/
availableCount = (mask + consumerTail) - producerHead;
if (availableCount < 1) {
return QUEUE_FULL;
}
producerNext = producerHead + 1;
success = SoftBusAtomicCmpAndSwap32(&queue->producer.head, producerHead, producerNext);
} while (success == false);
queue->nodes[producerHead & mask] = (uintptr_t)node;
/*
* Make sure that the queue is filled with elements before updating the producer tail.
* Prevents problems when the producer tail is updated first:
* 1. The consumer thinks that the elements in this area have been queued and can be consumed,
* but the consumer actually reads dirty elements.
* 2. The process is abnormal. In this case, elements in the memory block in the queue are dirty elements.
*/
WMB();
/* Waiting for other producers to complete enqueuing. */
while (queue->producer.tail != producerHead) {
sched_yield();
}
queue->producer.tail += 1;
return 0;
}
/** @brief Dequeue operation, thread unsafe */
static inline uint32_t QueueSingleConsumerDequeue(LockFreeQueue* queue, void** node)
{
uint32_t consumerHead;
uint32_t producerTail;
uint32_t consumerNext;
uint32_t availableCount;
uint32_t mask;
if (queue == NULL || node == NULL) {
return QUEUE_INVAL;
}
mask = queue->producer.mask;
consumerHead = queue->consumer.head;
/* Prevent producerTail from being read before consumerHead, causing queue head and tail reversal. */
RMB();
producerTail = queue->producer.tail;
/*
* 1. In normal cases, producerTail > consumerHead and producerTail < consumerHead + mask
* 2. If only producerTail is reversed, producerTail > consumerHead - 0xFFFFFFFF and
* producerTail < consumerHead + mask - 0xFFFFFFFF
* The subtraction of two 32-bit integers results in 32-bit modulo.
* Therefore, the availableCount must be between 0 and the queue length.
*/
availableCount = (producerTail - consumerHead);
if (availableCount < 1) {
return QUEUE_EMPTY;
}
consumerNext = consumerHead + 1;
queue->consumer.head = consumerNext;
/* Prevent the read of queue->nodes before the read of ProdTail. */
RMB();
*node = (void *)(queue->nodes[consumerHead & mask]);
/*
* Ensure that the queue element is dequeued before updating the consumer's tail.
* After the consumer tail is updated, the producer considers that the elements in this area have been dequeued
* and can fill in new elements, which actually overwrites the elements that are not dequeued.
*/
RMB();
queue->consumer.tail = consumerNext;
return 0;
}
/** @brief Dequeue operation, thread safe */
static inline uint32_t QueueMultiConsumerDequeue(LockFreeQueue *queue, void **node)
{
bool success = false;
uint32_t consumerHead;
uint32_t producerTail;
uint32_t consumerNext;
uint32_t availableCount;
uint32_t mask;
if (queue == NULL || node == NULL) {
return QUEUE_INVAL;
}
mask = queue->producer.mask;
do {
consumerHead = queue->consumer.head;
/*
* Make sure the consumer's head is read before the producer's tail.
* If the producer tail is read first, then other consumers consume the queue,
* and finally the generator produces the queue, the consumer head may cross the producer tail.
*/
RMB();
producerTail = queue->producer.tail;
/*
* 1. In normal cases, producerTail > consumerHead and producerTail < consumerHead + mask
* 2. If only producerTail is reversed, producerTail > consumerHead - 0xFFFFFFFF and
* producerTail < consumerHead + mask - 0xFFFFFFFF
* The subtraction of two 32-bit integers results in 32-bit modulo.
* Therefore, the availableCount must be between 0 and the queue length.
*/
availableCount = (producerTail - consumerHead);
if (availableCount < 1) {
return QUEUE_EMPTY;
}
consumerNext = consumerHead + 1;
success = SoftBusAtomicCmpAndSwap32(&queue->consumer.head, consumerHead, consumerNext);
} while (success == false);
/* Prevent the read of queue->nodes before the read of ProdTail. */
RMB();
*node = (void *)(queue->nodes[consumerHead & mask]);
/*
* Ensure that the queue element is dequeued before updating the consumer's tail.
* After the consumer tail is updated, the producer considers that the elements in this area have been dequeued
* and can fill in new elements, which actually overwrites the elements that are not dequeued.
*/
RMB();
/* Waiting for other consumers to finish dequeuing. */
while (queue->consumer.tail != consumerHead) {
sched_yield();
}
queue->consumer.tail += 1;
return 0;
}
#ifdef __cplusplus
#if __cplusplus
}
#endif /* __cplusplus */
#endif /* __cplusplus */
#endif // SOFTBUS_QUEUE_H

View File

@ -0,0 +1,70 @@
# Copyright (c) 2021 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.
import("//foundation/communication/dsoftbus/dsoftbus.gni")
if (defined(ohos_lite)) {
import("//build/lite/config/component/lite_component.gni")
common_include = [
"$dsoftbus_root_path/adapter/common/include",
"$dsoftbus_root_path/core/common/include",
"$libsec_include_path",
"$hilog_lite_include_path",
]
if (ohos_kernel_type == "liteos_m") {
static_library("softbus_queue") {
include_dirs = common_include
cflags = [ "-Wall" ]
sources = [ "softbus_queue.c" ]
deps = [
"$dsoftbus_root_path/core/common/log:softbus_log",
"$hilog_lite_deps_path",
"$libsec_deps_path",
]
}
} else {
shared_library("softbus_queue") {
include_dirs = common_include
cflags = [ "-Wall" ]
sources = [ "softbus_queue.c" ]
public_deps = [
"$dsoftbus_root_path/core/common/log:softbus_log",
"$hilog_lite_deps_path",
"$libsec_deps_path",
]
}
}
} else {
import("//build/ohos.gni")
ohos_shared_library("softbus_queue") {
include_dirs = [
"$dsoftbus_root_path/adapter/common/include",
"$dsoftbus_root_path/core/common/include",
"//third_party/cJSON",
]
sources = [ "softbus_queue.c" ]
deps = [ "$dsoftbus_root_path/adapter:softbus_adapter" ]
public_deps = [
"$dsoftbus_root_path/core/common/log:softbus_log",
"//utils/native/base:utilsecurec_shared",
]
if (is_standard_system) {
external_deps = [ "hiviewdfx_hilog_native:libhilog" ]
}
part_name = "dsoftbus_standard"
subsystem_name = "communication"
}
}

View File

@ -0,0 +1,114 @@
/*
* Copyright (c) 2020-2021 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.
*/
#include "softbus_queue.h"
#include "softbus_adapter_mem.h"
#ifdef __cplusplus
#if __cplusplus
extern "C" {
#endif
#endif
#define IS_POWER_OF_2(x) ((((x) - 1) & (x)) == 0)
#define QUEUE_HEADER_MAGIC 0xccddddcc
#define QUEUE_SIZE_MAX 8192
#define CACHE_LINE_SIZE 64
int32_t QueueInit(LockFreeQueue* queue, uint32_t unitNum)
{
if (queue == NULL) {
return QUEUE_INVAL;
}
if (!IS_POWER_OF_2(unitNum)) {
return QUEUE_INVAL;
}
(void)memset_s(queue, sizeof(LockFreeQueue), 0, sizeof(LockFreeQueue));
queue->magic = QUEUE_HEADER_MAGIC;
queue->producer.size = unitNum;
queue->consumer.size = unitNum;
queue->producer.mask = unitNum - 1;
queue->consumer.mask = unitNum - 1;
queue->producer.head = 0;
queue->consumer.head = 0;
queue->producer.tail = 0;
queue->consumer.tail = 0;
queue->unitNum = unitNum;
return 0;
}
int32_t QueueSizeCalc(uint32_t unitNum, uint32_t* queueSize)
{
uint32_t size;
if (queueSize == NULL) {
return QUEUE_INVAL;
}
if (unitNum > QUEUE_SIZE_MAX) {
return QUEUE_INVAL;
}
size = sizeof(uintptr_t) * unitNum + sizeof(LockFreeQueue);
*queueSize = ((size + CACHE_LINE_SIZE - 1) & (~(CACHE_LINE_SIZE - 1)));
return 0;
}
int32_t QueueCountGet(const LockFreeQueue* queue, uint32_t* count)
{
uint32_t producerTail;
uint32_t consumerTail;
uint32_t mask;
if (queue == NULL || count == NULL) {
return QUEUE_INVAL;
}
producerTail = queue->producer.tail;
consumerTail = queue->consumer.tail;
mask = queue->producer.mask;
*count = ((producerTail - consumerTail) & mask);
return 0;
}
LockFreeQueue* CreateQueue(uint32_t unitNum)
{
if (!IS_POWER_OF_2(unitNum)) {
return NULL;
}
uint32_t queueSize;
int ret = QueueSizeCalc(unitNum, &queueSize);
if (ret != 0) {
return NULL;
}
LockFreeQueue *queue = (LockFreeQueue *)SoftBusCalloc(queueSize);
if (queue == NULL) {
return NULL;
}
ret = QueueInit(queue, unitNum);
if (ret != 0) {
SoftBusFree(queue);
return NULL;
}
return queue;
}
#ifdef __cplusplus
#if __cplusplus
}
#endif /* __cplusplus */
#endif /* __cplusplus */

View File

@ -13,12 +13,32 @@
import("//foundation/communication/dsoftbus/dsoftbus.gni")
if (enable_connection_ble == false) {
sources_ble = [ "src/softbus_ble_connection_virtual.c" ]
deps_ble = []
} else {
sources_ble = [
"src/softbus_ble_connection.c",
"src/softbus_ble_trans_manager.c",
]
deps_ble = [
"$dsoftbus_root_path/adapter:softbus_adapter",
"$dsoftbus_root_path/adapter/common/net/bluetooth:softbus_adapter_ble",
"$dsoftbus_root_path/core/bus_center/lnn/net_ledger:dsoftbus_bus_center_ledger",
"$dsoftbus_root_path/core/common/json_utils:json_utils",
"$dsoftbus_root_path/core/common/log:softbus_log",
"$dsoftbus_root_path/core/common/message_handler:message_handler",
"$dsoftbus_root_path/core/common/queue:softbus_queue",
"$dsoftbus_root_path/core/common/softbus_property:softbus_property",
]
}
if (defined(ohos_lite)) {
import("//build/lite/config/component/lite_component.gni")
if (ohos_kernel_type == "liteos_m") {
static_library("ble_connection") {
sources = [ "src/ble_connection_virtual.c" ]
sources = sources_ble
include_dirs = [
"include",
"$dsoftbus_root_path/interfaces/kits/common",
@ -26,11 +46,11 @@ if (defined(ohos_lite)) {
"$dsoftbus_root_path/core/connection/interface",
"$dsoftbus_root_path/core/connection/manager",
]
deps = []
deps = deps_ble
}
} else {
shared_library("ble_connection") {
sources = [ "src/ble_connection_virtual.c" ]
sources = sources_ble
include_dirs = [
"include",
"$dsoftbus_root_path/interfaces/kits/common",
@ -38,21 +58,31 @@ if (defined(ohos_lite)) {
"$dsoftbus_root_path/core/connection/interface",
"$dsoftbus_root_path/core/connection/manager",
]
deps = []
deps = deps_ble
}
}
} else {
import("//build/ohos.gni")
ohos_shared_library("ble_connection") {
sources = [ "src/ble_connection_virtual.c" ]
sources = sources_ble
include_dirs = [
"include",
"src",
"$dsoftbus_root_path/adapter/common/include",
"$dsoftbus_root_path/adapter/common/net/bluetooth/include",
"$dsoftbus_root_path/interfaces/kits/common",
"$dsoftbus_root_path/interfaces/kits/bus_center",
"$dsoftbus_root_path/core/common/include",
"$dsoftbus_root_path/core/bus_center/interface",
"$dsoftbus_root_path/core/connection/interface",
"$dsoftbus_root_path/core/connection/manager",
"$dsoftbus_root_path/core/connection/ble/include",
"$dsoftbus_root_path/core/common/message_handler/include",
"//third_party/cJSON",
]
deps = deps_ble
external_deps = [ "hiviewdfx_hilog_native:libhilog" ]
part_name = "dsoftbus_standard"
subsystem_name = "communication"
}

View File

@ -1,24 +1,24 @@
/*
* Copyright (c) 2021 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.
*/
#ifndef BLE_CONNECTION_H
#define BLE_CONNECTION_H
#include "softbus_conn_interface.h"
#include "softbus_conn_manager.h"
ConnectFuncInterface *ConnInitBle(const ConnectCallback *callback);
/*
* Copyright (c) 2021 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.
*/
#ifndef BLE_CONNECTION_H
#define BLE_CONNECTION_H
#include "softbus_conn_interface.h"
#include "softbus_conn_manager.h"
ConnectFuncInterface *ConnInitBle(const ConnectCallback *callback);
#endif

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,50 @@
/*
* Copyright (c) 2021 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.
*/
#ifndef BLE_CONNECTION_INNER_H
#define BLE_CONNECTION_INNER_H
#include "common_list.h"
#include "softbus_adapter_ble_gatt_server.h"
#include "softbus_conn_manager.h"
#define MAX_CACHE_NUM_PER_CONN 3
typedef struct {
int32_t isUsed;
int32_t timeStamp;
int32_t seq;
int32_t currentSize;
char *cache;
} BleRecvCache;
typedef struct {
ListNode node;
int32_t halConnId;
uint32_t connId;
SoftBusBtAddr btBinaryAddr;
ConnectionInfo info;
int32_t state;
int32_t refCount;
int32_t mtu;
int32_t peerType;
char peerDevId[UDID_BUF_LEN];
BleRecvCache recvCache[MAX_CACHE_NUM_PER_CONN];
} BleConnectionInfo;
BleConnectionInfo* GetBleConnInfoByHalConnId(int32_t halConnectionId);
int32_t GetBleAttrHandle(int32_t module);
#endif

View File

@ -1,25 +1,22 @@
/*
* Copyright (c) 2021 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.
*/
#include "ble_connection.h"
#include "softbus_conn_interface.h"
#include "softbus_conn_manager.h"
ConnectFuncInterface *ConnInitBle(const ConnectCallback *callback)
{
(void)callback;
return NULL;
/*
* Copyright (c) 2021 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.
*/
#include "softbus_conn_interface.h"
#include "softbus_conn_manager.h"
ConnectFuncInterface *ConnInitBle(const ConnectCallback *callback)
{
(void)callback;
return NULL;
}

View File

@ -0,0 +1,182 @@
/*
* Copyright (c) 2021 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.
*/
#include "softbus_ble_trans_manager.h"
#include <arpa/inet.h>
#include "securec.h"
#include "softbus_adapter_mem.h"
#include "softbus_def.h"
#include "softbus_errcode.h"
#include "softbus_log.h"
typedef struct {
int32_t seq;
int32_t size;
int32_t offset;
int32_t total;
} BleTransHeader;
static const int MTU_HEADER_SIZE = 3;
static int32_t GetTransHeader(char *value, int32_t len, BleTransHeader *header)
{
BleTransHeader *tmpHeader = (BleTransHeader *)value;
header->seq = ntohl(tmpHeader->seq);
header->size = ntohl(tmpHeader->size);
header->offset = ntohl(tmpHeader->offset);
header->total = ntohl(tmpHeader->total);
if((header->size != len - (int32_t)sizeof(BleTransHeader)) ||
(header->total < header->size + header->offset) ||
(header->offset < 0) ||
(header->total > MAX_DATA_LEN)) {
return SOFTBUS_ERR;
}
return SOFTBUS_OK;
}
char *BleTransRecv(int32_t halConnId, char *value, uint32_t len, uint32_t *outLen, int32_t *index)
{
if (value == NULL) {
SoftBusLog(SOFTBUS_LOG_CONN, SOFTBUS_LOG_ERROR, "BleTransRecv invalid data");
return NULL;
}
BleConnectionInfo *targetNode = GetBleConnInfoByHalConnId(halConnId);
if (targetNode == NULL) {
SoftBusLog(SOFTBUS_LOG_CONN, SOFTBUS_LOG_ERROR, "BleTransRecv unknown device");
return NULL;
}
BleTransHeader header;
if (GetTransHeader(value, len, &header) != SOFTBUS_OK) {
SoftBusLog(SOFTBUS_LOG_CONN, SOFTBUS_LOG_ERROR, "BleTransRecv GetTransHeader failed");
return NULL;
}
if (header.size == header.total) {
SoftBusLog(SOFTBUS_LOG_CONN, SOFTBUS_LOG_INFO, "BleTransRecv a full pack");
*outLen = (uint32_t)header.total;
*index = -1;
return value + sizeof(BleTransHeader);
}
int availableIndex = -1;
int i;
for (i = 0; i < MAX_CACHE_NUM_PER_CONN; i++) {
if (targetNode->recvCache[i].isUsed == 0) {
availableIndex = availableIndex > -1 ? availableIndex : i;
continue;
}
if (targetNode->recvCache[i].seq == header.seq) {
break;
}
}
if ((i == MAX_CACHE_NUM_PER_CONN) && (availableIndex == -1)) {
SoftBusLog(SOFTBUS_LOG_CONN, SOFTBUS_LOG_ERROR, "BleTransRecv no availed cache");
return NULL;
}
if (i == MAX_CACHE_NUM_PER_CONN) {
targetNode->recvCache[availableIndex].isUsed = 1;
targetNode->recvCache[availableIndex].currentSize = 0;
targetNode->recvCache[availableIndex].seq = header.seq;
if (targetNode->recvCache[availableIndex].cache == NULL) {
targetNode->recvCache[availableIndex].cache = (char *)SoftBusCalloc(MAX_DATA_LEN);
if (targetNode->recvCache[availableIndex].cache == NULL) {
targetNode->recvCache[availableIndex].isUsed = 0;
return NULL;
}
}
i = availableIndex;
}
if (memcpy_s(targetNode->recvCache[i].cache + header.offset, MAX_DATA_LEN - header.offset,
value + sizeof(BleTransHeader), header.size) != 0) {
SoftBusLog(SOFTBUS_LOG_CONN, SOFTBUS_LOG_ERROR, "BleTransRecv memcpy_s failed");
targetNode->recvCache[i].isUsed = 0;
return NULL;
}
targetNode->recvCache[i].currentSize += header.size;
if (targetNode->recvCache[i].currentSize == header.total) {
SoftBusLog(SOFTBUS_LOG_CONN, SOFTBUS_LOG_INFO, "BleTransRecv a part pack, build complete");
*outLen = header.total;
*index = i;
return targetNode->recvCache[i].cache;
}
SoftBusLog(SOFTBUS_LOG_CONN, SOFTBUS_LOG_INFO, "BleTransRecv a part pack, wait next one, total:%d, current:%d", header.total, targetNode->recvCache[i].currentSize);
return NULL;
}
void BleTransCacheFree(int32_t halConnId, int32_t index)
{
BleConnectionInfo *targetNode = GetBleConnInfoByHalConnId(halConnId);
if (targetNode == NULL) {
SoftBusLog(SOFTBUS_LOG_CONN, SOFTBUS_LOG_ERROR, "BleTransCacheFree unknown device");
return;
}
if (targetNode->recvCache[index].cache != NULL) {
SoftBusFree(targetNode->recvCache[index].cache);
targetNode->recvCache[index].cache = NULL;
}
targetNode->recvCache[index].isUsed = 0;
}
static int32_t BleHalSend(BleConnectionInfo *connInfo, const char *data, int32_t len, int32_t module)
{
if (connInfo->info.isServer == 1) {
SoftBusGattsNotify notify = {
.connectId = connInfo->halConnId,
.attrHandle = GetBleAttrHandle(module),
.confirm = 0,
.valueLen = len,
.value = (char *)data
};
return SoftBusGattsSendNotify(&notify);
} else {
SoftBusLog(SOFTBUS_LOG_CONN, SOFTBUS_LOG_ERROR, "SendBleData ble gatt client not support");
return SOFTBUS_ERR;
}
}
int32_t BleTransSend(BleConnectionInfo *connInfo, const char *data, int32_t len, int32_t seq, int32_t module)
{
int32_t templen = len;
char *sendData = (char *)data;
int32_t dataLenMax = connInfo->mtu - MTU_HEADER_SIZE - sizeof(BleTransHeader);
int32_t offset = 0;
while (templen > 0) {
int32_t sendlenth = templen;
if (sendlenth > dataLenMax) {
sendlenth = dataLenMax;
}
char *buff = (char *)SoftBusCalloc(sendlenth + sizeof(BleTransHeader));
int ret = memcpy_s(buff + sizeof(BleTransHeader), sendlenth, sendData, sendlenth);
if (ret != SOFTBUS_OK) {
LOG_INFO("BleTransSend big msg, len:%{public}d\n", templen);
SoftBusFree(buff);
return ret;
}
BleTransHeader *transHeader = (BleTransHeader *)buff;
transHeader->total = htonl(len);
transHeader->size = htonl(sendlenth);
transHeader->offset = htonl(offset);
transHeader->seq = htonl(seq);
ret = BleHalSend(connInfo, buff, sendlenth + sizeof(BleTransHeader), module);
if (ret != SOFTBUS_OK) {
LOG_INFO("BleTransSend BleHalSend failed");
SoftBusFree(buff);
return ret;
}
SoftBusFree(buff);
sendData += sendlenth;
templen -= sendlenth;
offset += sendlenth;
}
return SOFTBUS_OK;
}

View File

@ -0,0 +1,27 @@
/*
* Copyright (c) 2021 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.
*/
#ifndef SOFTBUS_BLE_TRANS_MANAGER_H
#define SOFTBUS_BLE_TRANS_MANAGER_H
#include "softbus_ble_connection_inner.h"
#define MAX_DATA_LEN 4 * 1024
int32_t BleTransSend(BleConnectionInfo *connInfo, const char *data, int32_t len, int32_t seq, int32_t module);
char *BleTransRecv(int32_t halConnId, char *value, uint32_t len, uint32_t *outLen, int32_t *index);
void BleTransCacheFree(int32_t halConnId, int32_t index);
#endif

View File

@ -17,10 +17,10 @@
#include <securec.h>
#include "ble_connection.h"
#include "br_connection.h"
#include "common_list.h"
#include "softbus_adapter_mem.h"
#include "softbus_ble_connection.h"
#include "softbus_conn_interface.h"
#include "softbus_def.h"
#include "softbus_errcode.h"