feat: Add rfid feature and .gitignore file
This commit is contained in:
@ -0,0 +1,45 @@
|
||||
/*
|
||||
* Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved.
|
||||
* Licensed under the MIT License (the "License"); you may not use this file except in
|
||||
* compliance with the License. You may obtain a copy of the License at
|
||||
* http://opensource.org/licenses/MIT
|
||||
* 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 QCLOUD_BLE_QIOT_COMMON_H
|
||||
#define QCLOUD_BLE_QIOT_COMMON_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#define BLE_QIOT_PRODUCT_ID_LEN (10) // fixed length of product id
|
||||
#define BLE_QIOT_DEVICE_NAME_LEN (48) // max length of device name
|
||||
#define BLE_QIOT_PSK_LEN (24) // fixed length of secret key
|
||||
#define BLE_QIOT_MAC_LEN (6) // fixed length of mac
|
||||
|
||||
#define SWAP_32(x) \
|
||||
((((x)&0xFF000000) >> 24) | (((x)&0x00FF0000) >> 8) | (((x)&0x0000FF00) << 8) | (((x)&0x000000FF) << 24))
|
||||
#define SWAP_16(x) ((((x)&0xFF00) >> 8) | (((x)&0x00FF) << 8))
|
||||
#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
|
||||
#define HTONL(x) SWAP_32(x)
|
||||
#define HTONS(x) SWAP_16(x)
|
||||
#define NTOHL(x) SWAP_32(x)
|
||||
#define NTOHS(x) SWAP_16(x)
|
||||
#elif __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
|
||||
#define HTONL(x) (x)
|
||||
#define HTONS(x) (x)
|
||||
#define NTOHL(x) (x)
|
||||
#define NTOHS(x) (x)
|
||||
#else
|
||||
#error "undefined byte order"
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // QCLOUD_BLE_QIOT_COMMON_H
|
||||
@ -0,0 +1,120 @@
|
||||
/*
|
||||
* Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved.
|
||||
* Licensed under the MIT License (the "License"); you may not use this file except in
|
||||
* compliance with the License. You may obtain a copy of the License at
|
||||
* http://opensource.org/licenses/MIT
|
||||
* 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 QCLOUD_BLE_QIOT_CONFIG_H
|
||||
#define QCLOUD_BLE_QIOT_CONFIG_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include <printf.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#define BLE_QIOT_SDK_VERSION "1.5.0" // sdk version
|
||||
#define BLE_QIOT_SDK_DEBUG 0 // sdk debug
|
||||
|
||||
// the device broadcast is controlled by the user, but we provide a mechanism to help the device save more power.
|
||||
// if you want broadcast is triggered by something like press a button instead of all the time, and the broadcast
|
||||
// stopped automatically in a few minutes if the device is not bind, define BLE_QIOT_BUTTON_BROADCAST is 1 and
|
||||
// BLE_QIOT_BIND_TIMEOUT is the period that broadcast stopped.
|
||||
// if the device in the bound state, broadcast dose not stop automatically.
|
||||
#define BLE_QIOT_BUTTON_BROADCAST 0
|
||||
#if BLE_QIOT_BUTTON_BROADCAST
|
||||
#define BLE_QIOT_BIND_TIMEOUT (2 * 60 * 1000) // unit: ms
|
||||
#endif //BLE_QIOT_BUTTON_BROADCAST
|
||||
|
||||
// in some BLE stack the default ATT_MTU is 23, set BLE_QIOT_REMOTE_SET_MTU is 1 if you want to reset the mtu by the
|
||||
// Tencent Lianlian. Tencent Lianlian will set the mtu get from function ble_get_user_data_mtu_size()
|
||||
#define BLE_QIOT_REMOTE_SET_MTU (1)
|
||||
|
||||
// the following definition will affect the stack that LLSync used,the minimum value tested is 2048 bytes
|
||||
// the max length of llsync event data, depends on the length of user data reported to Tencent Lianlian at a time
|
||||
#define BLE_QIOT_EVENT_MAX_SIZE (128)
|
||||
// the minimum between BLE_QIOT_EVENT_MAX_SIZE and mtu
|
||||
#define BLE_QIOT_EVENT_BUF_SIZE (23)
|
||||
|
||||
// some data like integer need to be transmitted in a certain byte order, defined it according to your device
|
||||
#define __ORDER_LITTLE_ENDIAN__ 1234
|
||||
#define __ORDER_BIG_ENDIAN__ 4321
|
||||
#define __BYTE_ORDER__ __ORDER_LITTLE_ENDIAN__
|
||||
|
||||
// in some BLE stack ble_qiot_log_hex() maybe not work, user can use there own hexdump function
|
||||
#define BLE_QIOT_USER_DEFINE_HEXDUMP 0
|
||||
#if BLE_QIOT_USER_DEFINE_HEXDUMP
|
||||
// add your code here like this
|
||||
// #define ble_qiot_log_hex(level, hex_name, data, data_len) \
|
||||
// do { \
|
||||
// MY_RAW_LOG("\r\nble qiot dump: %s, length: %d\r\n", hex_name, data_len); \
|
||||
// MY_RAW_HEXDUMP_(data, data_len); \
|
||||
// } while(0)
|
||||
|
||||
// or use your own hexdump function with same definition
|
||||
// void ble_qiot_log_hex(e_ble_qiot_log_level level, const char *hex_name, const char *data, uint32_t data_len);
|
||||
#endif // BLE_QIOT_USER_DEFINE_HEXDUMP
|
||||
|
||||
// Macro for logging a formatted string, the function must printf raw string without any color, prefix, newline or
|
||||
// timestamp
|
||||
#define BLE_QIOT_LOG_PRINT(...) printf(__VA_ARGS__)
|
||||
|
||||
#define BLE_QIOT_LLSYNC_STANDARD 1 // support llsync standard
|
||||
#if BLE_QIOT_LLSYNC_STANDARD
|
||||
// some users hope to confirm on the device before the binding, set BLE_QIOT_SECURE_BIND is 1 to enable the secure
|
||||
// binding and enable secure bind in iot-explorer console. When the server is bound, the device callback ble_secure_bind_user_cb()
|
||||
// will be triggered, the user agree or refuse connect by ble_secure_bind_user_confirm(). If the device does not respond
|
||||
// and the connection timeout, or the user cancel the connection in Tencent Lianlian, a notify will received in function
|
||||
// ble_secure_bind_user_notify().
|
||||
#define BLE_QIOT_SECURE_BIND 0
|
||||
#if BLE_QIOT_SECURE_BIND
|
||||
#define BLE_QIOT_BIND_WAIT_TIME 60
|
||||
#endif //BLE_QIOT_SECURE_BIND
|
||||
|
||||
// some sdk info needs to stored on the device and the address is up to you
|
||||
#define BLE_QIOT_RECORD_FLASH_ADDR 5
|
||||
|
||||
// define user develop version, pick from "a-zA-Z0-9.-_" and length limits 1~32 bytes.
|
||||
// must be consistent with the firmware version that user write in the iot-explorer console
|
||||
// refer https://cloud.tencent.com/document/product/1081/40296
|
||||
#define BLE_QIOT_USER_DEVELOPER_VERSION "0.0.1"
|
||||
|
||||
#define BLE_QIOT_SUPPORT_OTA 1 // 1 is support ota, others not
|
||||
#if BLE_QIOT_SUPPORT_OTA
|
||||
#define BLE_QIOT_SUPPORT_RESUMING 0 // 1 is support resuming, others not
|
||||
#if BLE_QIOT_SUPPORT_RESUMING
|
||||
// storage ota info in the flash if support resuming ota file
|
||||
#define BLE_QIOT_OTA_INFO_FLASH_ADDR 10
|
||||
#endif //BLE_QIOT_SUPPORT_RESUMING
|
||||
|
||||
#define BLE_QIOT_TOTAL_PACKAGES 0x12 // the total package numbers in a loop
|
||||
#define BLE_QIOT_PACKAGE_LENGTH 0xb0 // the user data length in package, ble_get_user_data_mtu_size() - 3 is the max
|
||||
#define BLE_QIOT_RETRY_TIMEOUT 0x20 // the max interval between two packages, unit: second
|
||||
// the time spent for device reboot, the server waiting the device version reported after upgrade. unit: second
|
||||
#define BLE_QIOT_REBOOT_TIME 20
|
||||
#define BLE_QIOT_PACKAGE_INTERVAL 0xa // the interval between two packages send by the server
|
||||
// the package from the server will storage in the buffer, write the buffer to the flash at one time when the buffer
|
||||
// overflow. reduce the flash write can speed up file download, we suggest the BLE_QIOT_OTA_BUF_SIZE is multiples
|
||||
// of BLE_QIOT_PACKAGE_LENGTH and equal flash page size
|
||||
#define BLE_QIOT_OTA_BUF_SIZE (512 * 4)
|
||||
#endif //BLE_QIOT_SUPPORT_OTA
|
||||
#endif //BLE_QIOT_LLSYNC_STANDARD
|
||||
|
||||
#define BLE_QIOT_LLSYNC_CONFIG_NET (!BLE_QIOT_LLSYNC_STANDARD) // support llsync configure network
|
||||
|
||||
#if (1 == BLE_QIOT_LLSYNC_STANDARD) && (1 == BLE_QIOT_LLSYNC_CONFIG_NET)
|
||||
#error "llsync standard and llsync configure network is incompatible"
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // QCLOUD_BLE_QIOT_CONFIG_H
|
||||
@ -0,0 +1,32 @@
|
||||
/*
|
||||
* Tencent is pleased to support the open source community by making IoT Hub available.
|
||||
* Copyright (C) 2018-2020 THL A29 Limited, a Tencent company. All rights reserved.
|
||||
|
||||
* Licensed under the MIT License (the "License"); you may not use this file except in
|
||||
* compliance with the License. You may obtain a copy of the License at
|
||||
* http://opensource.org/licenses/MIT
|
||||
|
||||
* 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 QCLOUD_BLE_QIOT_CRC_H
|
||||
#define QCLOUD_BLE_QIOT_CRC_H
|
||||
|
||||
#if defined(__cplusplus)
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include <printf.h>
|
||||
#include <stdint.h>
|
||||
|
||||
void ble_qiot_crc32_init();
|
||||
uint32_t ble_qiot_crc32(uint32_t crc, const uint8_t *buf, int len);
|
||||
|
||||
#if defined(__cplusplus)
|
||||
}
|
||||
#endif
|
||||
#endif // QCLOUD_BLE_QIOT_HMAC_H
|
||||
@ -0,0 +1,285 @@
|
||||
/*
|
||||
* Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved.
|
||||
* Licensed under the MIT License (the "License"); you may not use this file except in
|
||||
* compliance with the License. You may obtain a copy of the License at
|
||||
* http://opensource.org/licenses/MIT
|
||||
* 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 QCLOUD_BLE_QIOT_EXPORT_H
|
||||
#define QCLOUD_BLE_QIOT_EXPORT_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include "ble_qiot_config.h"
|
||||
|
||||
#define TENCENT_COMPANY_IDENTIFIER 0xFEE7 // Tencent Company ID, another is 0xFEBA
|
||||
|
||||
#define IOT_BLE_UUID_BASE \
|
||||
{ \
|
||||
0xe2, 0xa4, 0x1b, 0x54, 0x93, 0xe4, 0x6a, 0xb5, 0x20, 0x4e, 0xd0, 0x65, 0x00, 0x00, 0x00, 0x00 \
|
||||
}
|
||||
|
||||
// llsync services uuid
|
||||
#if BLE_QIOT_LLSYNC_STANDARD
|
||||
#define IOT_BLE_UUID_SERVICE 0xFFE0
|
||||
#endif //BLE_QIOT_LLSYNC_STANDARD
|
||||
#if BLE_QIOT_LLSYNC_CONFIG_NET
|
||||
#define IOT_BLE_UUID_SERVICE 0xFFF0
|
||||
#endif //BLE_QIOT_LLSYNC_CONFIG_NET
|
||||
|
||||
// characteristics uuid
|
||||
#define IOT_BLE_UUID_DEVICE_INFO 0xFFE1 // used to connection and identity authentication
|
||||
#define IOT_BLE_UUID_EVENT 0xFFE3 // used to send data to the server from device
|
||||
|
||||
#if BLE_QIOT_LLSYNC_STANDARD
|
||||
#define IOT_BLE_UUID_DATA 0xFFE2 // used to send data to the device from server
|
||||
#define IOT_BLE_UUID_OTA 0xFFE4 // used to send ota data to the device from server
|
||||
#endif //BLE_QIOT_LLSYNC_STANDARD
|
||||
|
||||
typedef enum {
|
||||
GATT_CHAR_BROADCAST = (1 << 0), // Broadcasting of the value permitted.
|
||||
GATT_CHAR_READ = (1 << 1), // Reading the value permitted.
|
||||
GATT_CHAR_WRITE_WO_RESP = (1 << 2), // Writing the value with Write Command permitted.
|
||||
GATT_CHAR_WRITE = (1 << 3), // Writing the value with Write Request permitted.
|
||||
GATT_CHAR_NOTIFY = (1 << 4), // Notification of the value permitted.
|
||||
GATT_CHAR_INDICATE = (1 << 5), // Indications of the value permitted.
|
||||
GATT_CHAR_AUTH_SIGNED_WR = (1 << 6), // Writing the value with Signed Write Command permitted.
|
||||
} char_props_s;
|
||||
|
||||
// the callback function prototype definition for the characteristics
|
||||
typedef void (*ble_on_write_cb)(const uint8_t *buf, uint16_t len);
|
||||
|
||||
// the characteristics attributes
|
||||
typedef struct {
|
||||
uint16_t uuid16;
|
||||
uint8_t gatt_char_props;
|
||||
ble_on_write_cb on_write;
|
||||
} qiot_char_s;
|
||||
|
||||
// the service attributes
|
||||
typedef struct {
|
||||
uint16_t service_uuid16;
|
||||
uint8_t service_uuid128[16];
|
||||
uint16_t gatt_max_mtu;
|
||||
|
||||
qiot_char_s device_info;
|
||||
qiot_char_s data;
|
||||
qiot_char_s event;
|
||||
qiot_char_s ota;
|
||||
} qiot_service_init_s;
|
||||
|
||||
typedef enum {
|
||||
BLE_QIOT_RS_OK = 0, // success
|
||||
BLE_QIOT_RS_ERR = -1, // normal error
|
||||
BLE_QIOT_RS_ERR_FLASH = -2, // flash error
|
||||
BLE_QIOT_RS_ERR_PARA = -3, // parameters error
|
||||
BLE_QIOT_RS_VALID_SIGN_ERR = -4,
|
||||
} ble_qiot_ret_status_t;
|
||||
|
||||
/**
|
||||
* @brief get llsync services context
|
||||
*
|
||||
* @return llsync services struct
|
||||
*/
|
||||
const qiot_service_init_s *ble_get_qiot_services(void);
|
||||
|
||||
/**
|
||||
* @brief llsync sdck initialize
|
||||
* @note you should called it before any other sdk api
|
||||
* @return BLE_QIOT_RS_OK is success, other is error
|
||||
*/
|
||||
ble_qiot_ret_status_t ble_qiot_explorer_init(void);
|
||||
|
||||
/**
|
||||
* @brief report mtu of the device to the server
|
||||
* @note report mtu to the server to set the mtu
|
||||
* @return BLE_QIOT_RS_OK is success, other is error
|
||||
*/
|
||||
ble_qiot_ret_status_t ble_event_report_device_info(void);
|
||||
|
||||
/**
|
||||
* @brief sync the device mtu to The Tencent Lianlian.
|
||||
* @note if BLE_QIOT_REMOTE_SET_MTU is 1, The Tencent Lianlian will set the mtu get from function
|
||||
* ble_get_user_data_mtu_size(), but The Tencent Lianlian can not know the effective value even if the setting is
|
||||
* successful, so llsync need sync the mtu again. The user call this function in the BLE mtu callback.
|
||||
* @return BLE_QIOT_RS_OK is success, other is error
|
||||
*/
|
||||
ble_qiot_ret_status_t ble_event_sync_mtu(uint16_t llsync_mtu);
|
||||
|
||||
/**
|
||||
* @brief start llsync advertising
|
||||
* @note broadcast data according to the device bind state, reference to llsync protocol
|
||||
* @return BLE_QIOT_RS_OK is success, other is error
|
||||
*/
|
||||
ble_qiot_ret_status_t ble_qiot_advertising_start(void);
|
||||
|
||||
/**
|
||||
* @brief stop advertising
|
||||
* @return BLE_QIOT_RS_OK is success, other is error
|
||||
*/
|
||||
ble_qiot_ret_status_t ble_qiot_advertising_stop(void);
|
||||
|
||||
/**
|
||||
* @brief device info write callbcak, call the function when characteristic IOT_BLE_UUID_DEVICE_INFO received data
|
||||
* @param buf a pointer point to the data
|
||||
* @param len data length
|
||||
* @return none
|
||||
*/
|
||||
void ble_device_info_write_cb(const uint8_t *buf, uint16_t len);
|
||||
|
||||
/**
|
||||
* @brief gap event connect call-back, when gap get ble connect event, use this function
|
||||
* tell qiot ble sdk
|
||||
* @return none
|
||||
*/
|
||||
void ble_gap_connect_cb(void);
|
||||
|
||||
/**
|
||||
* @brief gap event disconnect call-back, when gap get ble disconnect event, use this function
|
||||
* tell qiot ble sdk
|
||||
* @return none
|
||||
*/
|
||||
void ble_gap_disconnect_cb(void);
|
||||
|
||||
#ifdef BLE_QIOT_LLSYNC_STANDARD
|
||||
/**
|
||||
* @brief get property of the device from the server
|
||||
* @note the property will be received from IOT_BLE_UUID_DATA if success
|
||||
* @return BLE_QIOT_RS_OK is success, other is error. if success, the data from server will come to
|
||||
*/
|
||||
ble_qiot_ret_status_t ble_event_get_status(void);
|
||||
|
||||
/**
|
||||
* @brief report property of the device to the server
|
||||
* @note the reply will be received from IOT_BLE_UUID_DATA if success
|
||||
* @return BLE_QIOT_RS_OK is success, other is error
|
||||
*/
|
||||
ble_qiot_ret_status_t ble_event_report_property(void);
|
||||
|
||||
/**
|
||||
* @brief post event to the server
|
||||
* @param event_id id of the event
|
||||
* @note the reply will be received from IOT_BLE_UUID_DATA if success
|
||||
* @return BLE_QIOT_RS_OK is success, other is error
|
||||
*/
|
||||
ble_qiot_ret_status_t ble_event_post(uint8_t event_id);
|
||||
|
||||
/**
|
||||
* @brief data write callback, call the function when characteristic IOT_BLE_UUID_DATA received data
|
||||
* @param buf a pointer point to the data
|
||||
* @param len data length
|
||||
* @return none
|
||||
*/
|
||||
void ble_lldata_write_cb(const uint8_t *buf, uint16_t len);
|
||||
|
||||
/**
|
||||
* @brief ota data write callback, call the function when characteristic IOT_BLE_UUID_OTA received data
|
||||
* @param buf a pointer point to the data
|
||||
* @param len data length
|
||||
* @return none
|
||||
*/
|
||||
void ble_ota_write_cb(const uint8_t *buf, uint16_t len);
|
||||
|
||||
typedef enum {
|
||||
BLE_QIOT_SECURE_BIND_CONFIRM = 0,
|
||||
BLE_QIOT_SECURE_BIND_REJECT = 1,
|
||||
} ble_qiot_secure_bind_t;
|
||||
|
||||
/**
|
||||
* @brief user choose whether to connect
|
||||
* @note call the function when the user choose connect or not
|
||||
* @return BLE_QIOT_RS_OK is success, other is error
|
||||
*/
|
||||
ble_qiot_ret_status_t ble_secure_bind_user_confirm(ble_qiot_secure_bind_t choose);
|
||||
|
||||
// inform user the ota start
|
||||
typedef void (*ble_ota_start_callback)(void);
|
||||
|
||||
enum {
|
||||
BLE_QIOT_OTA_SUCCESS = 0, // ota success
|
||||
BLE_QIOT_OTA_ERR_CRC = 1, // ota failed because crc error
|
||||
BLE_QIOT_OTA_ERR_TIMEOUT = 2, // ota failed because download timeout
|
||||
BLE_QIOT_OTA_DISCONNECT = 3, // ota failed because ble disconnect
|
||||
BLE_QIOT_OTA_ERR_FILE = 4, // ota failed because the file mismatch the device
|
||||
};
|
||||
// inform user the ota stop and the result
|
||||
typedef void (*ble_ota_stop_callback)(uint8_t result);
|
||||
|
||||
// llsync only valid the file crc, also allow the user valid the file by their way
|
||||
typedef ble_qiot_ret_status_t (*ble_ota_valid_file_callback)(uint32_t file_size, char *file_version);
|
||||
/**
|
||||
* @brief register ota callback
|
||||
* @param start_cb called before ota start, set null if not used
|
||||
* @param stop_cb called after ota stop, set null if not used
|
||||
* @param valid_file_cb called after the crc valid, set null if not used
|
||||
* @return none
|
||||
*/
|
||||
void ble_ota_callback_reg(ble_ota_start_callback start_cb, ble_ota_stop_callback stop_cb,
|
||||
ble_ota_valid_file_callback valid_file_cb);
|
||||
#endif //BLE_QIOT_LLSYNC_STANDARD
|
||||
|
||||
#if BLE_QIOT_LLSYNC_CONFIG_NET
|
||||
|
||||
typedef enum {
|
||||
BLE_WIFI_MODE_NULL = 0, // invalid mode
|
||||
BLE_WIFI_MODE_STA = 1, // station
|
||||
BLE_WIFI_MODE_AP = 2, // ap
|
||||
} BLE_WIFI_MODE;
|
||||
|
||||
typedef enum {
|
||||
BLE_WIFI_STATE_CONNECT = 0, // wifi connect
|
||||
BLE_WIFI_STATE_OTHER = 1, // other state
|
||||
} BLE_WIFI_STATE;
|
||||
|
||||
/**
|
||||
* @brief report wifi-mode setting result
|
||||
* @param result setting result, 0 is success, other failed
|
||||
* @return BLE_QIOT_RS_OK is success, other is error
|
||||
*/
|
||||
ble_qiot_ret_status_t ble_event_report_wifi_mode(uint8_t result);
|
||||
|
||||
/**
|
||||
* @brief report wifi-info setting result
|
||||
* @param result setting result, 0 is success, other failed
|
||||
* @return BLE_QIOT_RS_OK is success, other is error
|
||||
*/
|
||||
ble_qiot_ret_status_t ble_event_report_wifi_info(uint8_t result);
|
||||
|
||||
/**
|
||||
* @brief report wifi connection status
|
||||
* @param mode current wifi mode, reference BLE_WIFI_MODE
|
||||
* @param state current wifi state, reference BLE_WIFI_STATE
|
||||
* @param ssid_len length of ssid
|
||||
* @param ssid the ssid currently connected
|
||||
* @return BLE_QIOT_RS_OK is success, other is error
|
||||
*/
|
||||
ble_qiot_ret_status_t ble_event_report_wifi_connect(BLE_WIFI_MODE mode, BLE_WIFI_STATE state, uint8_t ssid_len,
|
||||
const char *ssid);
|
||||
|
||||
/**
|
||||
* @brief report wifi-token setting result
|
||||
* @param result setting result, 0 is success, other failed
|
||||
* @return BLE_QIOT_RS_OK is success, other is error
|
||||
*/
|
||||
ble_qiot_ret_status_t ble_event_report_wifi_token(uint8_t result);
|
||||
|
||||
/**
|
||||
* @brief report wifi-log
|
||||
* @param log log message
|
||||
* @param log_size length of log
|
||||
* @return BLE_QIOT_RS_OK is success, other is error
|
||||
*/
|
||||
ble_qiot_ret_status_t ble_event_report_wifi_log(const uint8_t *log, uint16_t log_size);
|
||||
|
||||
#endif //BLE_QIOT_LLSYNC_CONFIG_NET
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif // QCLOUD_BLE_QIOT_EXPORT_H
|
||||
@ -0,0 +1,32 @@
|
||||
/*
|
||||
* Tencent is pleased to support the open source community by making IoT Hub available.
|
||||
* Copyright (C) 2018-2020 THL A29 Limited, a Tencent company. All rights reserved.
|
||||
|
||||
* Licensed under the MIT License (the "License"); you may not use this file except in
|
||||
* compliance with the License. You may obtain a copy of the License at
|
||||
* http://opensource.org/licenses/MIT
|
||||
|
||||
* 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 QCLOUD_BLE_QIOT_HMAC_H
|
||||
#define QCLOUD_BLE_QIOT_HMAC_H
|
||||
|
||||
#if defined(__cplusplus)
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#define SHA1_DIGEST_SIZE 20
|
||||
|
||||
void utils_hmac_sha1(const char *msg, int msg_len, char *digest, const char *key, int key_len);
|
||||
|
||||
#if defined(__cplusplus)
|
||||
}
|
||||
#endif
|
||||
#endif // QCLOUD_BLE_QIOT_HMAC_H
|
||||
@ -0,0 +1,254 @@
|
||||
/*
|
||||
* Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved.
|
||||
* Licensed under the MIT License (the "License"); you may not use this file except in
|
||||
* compliance with the License. You may obtain a copy of the License at
|
||||
* http://opensource.org/licenses/MIT
|
||||
* 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 QCLOUD_BLE_QIOT_IMPORT_H
|
||||
#define QCLOUD_BLE_QIOT_IMPORT_H
|
||||
|
||||
#if defined(__cplusplus)
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include "ble_qiot_export.h"
|
||||
|
||||
// 16 bits service UUIDs list, use advertising type 0x02 or 0x03
|
||||
typedef struct {
|
||||
uint8_t uuid_num;
|
||||
uint16_t *uuids;
|
||||
} uuid_list_s;
|
||||
|
||||
// advertise manufacture specific data, use advertising type 0xFF
|
||||
typedef struct {
|
||||
uint16_t company_identifier;
|
||||
uint8_t *adv_data;
|
||||
uint8_t adv_data_len;
|
||||
} manufacturer_data_s;
|
||||
|
||||
typedef struct {
|
||||
uuid_list_s uuid_info;
|
||||
manufacturer_data_s manufacturer_info;
|
||||
} adv_info_s;
|
||||
|
||||
/**
|
||||
* @brief get mac address
|
||||
* @param mac the buf storage mac, 6 bytes permanent
|
||||
* @return 0 is success, other is error
|
||||
*/
|
||||
int ble_get_mac(char *mac);
|
||||
|
||||
/**
|
||||
* @brief add llsync services to ble stack
|
||||
* @param qiot_service_init_s llsync service
|
||||
* @return none
|
||||
*/
|
||||
void ble_services_add(const qiot_service_init_s *p_service);
|
||||
|
||||
/**
|
||||
* @brief start llsync advertising
|
||||
* @param adv a pointer point to advertising data
|
||||
* @return BLE_QIOT_RS_OK is success, other is error
|
||||
*/
|
||||
ble_qiot_ret_status_t ble_advertising_start(adv_info_s *adv);
|
||||
|
||||
/**
|
||||
* @brief stop advertising
|
||||
* @return BLE_QIOT_RS_OK is success, other is error
|
||||
*/
|
||||
ble_qiot_ret_status_t ble_advertising_stop(void);
|
||||
|
||||
/**
|
||||
* @brief get the ATT_MTU user want to used
|
||||
* @return the value
|
||||
*/
|
||||
uint16_t ble_get_user_data_mtu_size(void);
|
||||
|
||||
/**
|
||||
* @brief send a notification to host, use characteristic IOT_BLE_UUID_EVENT
|
||||
* @param buf a pointer point to indication information
|
||||
* @param len indication information length
|
||||
* @return BLE_QIOT_RS_OK is success, other is error
|
||||
*/
|
||||
ble_qiot_ret_status_t ble_send_notify(uint8_t *buf, uint8_t len);
|
||||
|
||||
// timer type
|
||||
enum {
|
||||
BLE_TIMER_ONE_SHOT_TYPE = 0,
|
||||
BLE_TIMER_PERIOD_TYPE,
|
||||
BLE_TIMER_BUTT,
|
||||
};
|
||||
typedef void *ble_timer_t;
|
||||
|
||||
// timer callback prototype
|
||||
typedef void (*ble_timer_cb)(void *param);
|
||||
|
||||
/**
|
||||
* @brief create a timer
|
||||
* @param type timer type
|
||||
* @param timeout_handle timer callback
|
||||
* @return timer identifier is return, NULL is error
|
||||
*/
|
||||
ble_timer_t ble_timer_create(uint8_t type, ble_timer_cb timeout_handle);
|
||||
|
||||
/**
|
||||
* @brief start a timer
|
||||
* @param timer_id Timer identifier
|
||||
* @param period timer period(unit: ms)
|
||||
* @return BLE_QIOT_RS_OK is success, other is error
|
||||
*/
|
||||
ble_qiot_ret_status_t ble_timer_start(ble_timer_t timer_id, uint32_t period);
|
||||
|
||||
/**
|
||||
* @brief stop a timer
|
||||
* @param timer_id Timer identifier
|
||||
* @return BLE_QIOT_RS_OK is success, other is error
|
||||
*/
|
||||
ble_qiot_ret_status_t ble_timer_stop(ble_timer_t timer_id);
|
||||
|
||||
/**
|
||||
* @brief delete a timer
|
||||
* @param timer_id Timer identifier
|
||||
* @return BLE_QIOT_RS_OK is success, other is error
|
||||
*/
|
||||
ble_qiot_ret_status_t ble_timer_delete(ble_timer_t timer_id);
|
||||
|
||||
#ifdef BLE_QIOT_LLSYNC_STANDARD
|
||||
/**
|
||||
* @brief get device product id
|
||||
* @param product_id the buf storage product id, 10 bytes permanent
|
||||
* @return 0 is success, other is error
|
||||
*/
|
||||
int ble_get_product_id(char *product_id);
|
||||
|
||||
/**
|
||||
* @brief get device name
|
||||
* @param device_name the buf storage device name, the max length of the device name is 48 bytes
|
||||
* @return length of device name, 0 is error
|
||||
*/
|
||||
int ble_get_device_name(char *device_name);
|
||||
|
||||
/**
|
||||
* @brief get device secret
|
||||
* @param psk the buf storage secret, 24 bytes permanent
|
||||
* @return 0 is success, other is error
|
||||
*/
|
||||
int ble_get_psk(char *psk);
|
||||
|
||||
/**
|
||||
* @brief write data to flash
|
||||
* @param flash_addr write address in flash
|
||||
* @param write_buf point to write buf
|
||||
* @param write_len length of data to write
|
||||
* @return write_len is success, other is error
|
||||
*/
|
||||
int ble_write_flash(uint32_t flash_addr, const char *write_buf, uint16_t write_len);
|
||||
|
||||
/**
|
||||
* @brief read data from flash
|
||||
* @param flash_addr read address from flash
|
||||
* @param read_buf point to read buf
|
||||
* @param read_len length of data to read
|
||||
* @return read_len is success, other is error
|
||||
*/
|
||||
int ble_read_flash(uint32_t flash_addr, char *read_buf, uint16_t read_len);
|
||||
|
||||
/**
|
||||
* @brief secure binding user callback
|
||||
* @note when the secure binding is activated, the function notify user the connecting is coming, the function is
|
||||
* no-block
|
||||
* @return None
|
||||
*/
|
||||
void ble_secure_bind_user_cb(void);
|
||||
|
||||
enum {
|
||||
BLE_SECURE_BIND_CANCEL = 0, // user cancel in Tencent Lianlian
|
||||
BLE_SECURE_BIND_TIMEOUT = 1, // the binding timeout
|
||||
};
|
||||
/**
|
||||
* @brief secure binding user notify
|
||||
* @note notify user when the secure bind timeout or cancel
|
||||
* @return None
|
||||
*/
|
||||
void ble_secure_bind_user_notify(uint8_t result);
|
||||
|
||||
enum {
|
||||
BLE_OTA_ENABLE = 1, // ota enable
|
||||
BLE_OTA_DISABLE_LOW_POWER = 2, // the device low power can not upgrade
|
||||
BLE_OTA_DISABLE_LOW_VERSION = 3, // disable upgrade low version
|
||||
};
|
||||
/**
|
||||
* @brief get ota is enable
|
||||
* @param version the ota file version
|
||||
* @return BLE_OTA_ENABLE is enable, others disable
|
||||
* @note can not be blocking, the reason defined by users
|
||||
*/
|
||||
uint8_t ble_ota_is_enable(const char *version, u32 file_size, u32 file_crc);
|
||||
|
||||
/**
|
||||
* @brief get the address the ota file will be saved
|
||||
* @return the flash address
|
||||
*/
|
||||
uint32_t ble_ota_get_download_addr(void);
|
||||
|
||||
/**
|
||||
* @brief write data to flash
|
||||
* @param flash_addr write address in flash
|
||||
* @param write_buf point to write buf
|
||||
* @param write_len length of data to write
|
||||
* @return write_len is success, other is error
|
||||
*/
|
||||
int ble_ota_write_flash(uint32_t flash_addr, const char *write_buf, uint16_t write_len);
|
||||
#endif //BLE_QIOT_LLSYNC_STANDARD
|
||||
|
||||
#if BLE_QIOT_LLSYNC_CONFIG_NET
|
||||
/**
|
||||
* @brief set wifi mode
|
||||
* @param mode the target mode
|
||||
* @return BLE_QIOT_RS_OK is success, other is error
|
||||
*/
|
||||
ble_qiot_ret_status_t ble_combo_wifi_mode_set(BLE_WIFI_MODE mode);
|
||||
|
||||
/**
|
||||
* @brief set wifi info
|
||||
* @param ssid wifi ssid
|
||||
* @param ssid_len the length of ssid
|
||||
* @param passwd wifi password
|
||||
* @param passwd_len the length of password
|
||||
* @return BLE_QIOT_RS_OK is success, other is error
|
||||
*/
|
||||
ble_qiot_ret_status_t ble_combo_wifi_info_set(const char *ssid, uint8_t ssid_len, const char *passwd, uint8_t passwd_len);
|
||||
|
||||
/**
|
||||
* @brief connect wifi
|
||||
* @param none
|
||||
* @return BLE_QIOT_RS_OK is success, other is error
|
||||
*/
|
||||
ble_qiot_ret_status_t ble_combo_wifi_connect();
|
||||
|
||||
/**
|
||||
* @brief set wifi token
|
||||
* @param token token message
|
||||
* @param token_len length of token
|
||||
* @return BLE_QIOT_RS_OK is success, other is error
|
||||
*/
|
||||
ble_qiot_ret_status_t ble_combo_wifi_token_set(const char *token, uint16_t token_len);
|
||||
|
||||
/**
|
||||
* @brief get wifi log
|
||||
* @param none
|
||||
* @return BLE_QIOT_RS_OK is success, other is error
|
||||
*/
|
||||
ble_qiot_ret_status_t ble_combo_wifi_log_get(void);
|
||||
#endif //BLE_QIOT_LLSYNC_CONFIG_NET
|
||||
|
||||
#if defined(__cplusplus)
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // QCLOUD_BLE_QIOT_IMPORT_H
|
||||
@ -0,0 +1,44 @@
|
||||
/*
|
||||
* Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved.
|
||||
* Licensed under the MIT License (the "License"); you may not use this file except in
|
||||
* compliance with the License. You may obtain a copy of the License at
|
||||
* http://opensource.org/licenses/MIT
|
||||
* 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 QCLOUD_BLE_QIOT_LLSYNC_DATA_H
|
||||
#define QCLOUD_BLE_QIOT_LLSYNC_DATA_H
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include <stdint.h>
|
||||
#include <ble_qiot_export.h>
|
||||
|
||||
#define BLE_QIOT_CONTROL_DATA_TYPE (0x00)
|
||||
#define BLE_QIOT_GET_STATUS_REPLY_DATA_TYPE (0x22)
|
||||
|
||||
#define BLE_QIOT_GET_STATUS_REPLY_HEADER_LEN (4)
|
||||
#define BLE_QIOT_DATA_FIXED_HEADER_LEN (3)
|
||||
|
||||
// handle property request
|
||||
ble_qiot_ret_status_t ble_lldata_property_request_handle(const char *in_buf, int buf_len);
|
||||
|
||||
// handle property reply
|
||||
ble_qiot_ret_status_t ble_lldata_property_reply_handle(uint8_t type, const char *in_buf, int buf_len);
|
||||
|
||||
// handle event data
|
||||
ble_qiot_ret_status_t ble_lldata_event_handle(uint8_t id, const char *in_buf, int len);
|
||||
|
||||
// handle action data
|
||||
ble_qiot_ret_status_t ble_lldata_action_handle(uint8_t id, const char *in_buf, int len);
|
||||
|
||||
// get report data
|
||||
ble_qiot_ret_status_t ble_user_property_get_report_data(void);
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif // QCLOUD_BLE_QIOT_LLSYNC_DATA_H
|
||||
@ -0,0 +1,173 @@
|
||||
/*
|
||||
* Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved.
|
||||
* Licensed under the MIT License (the "License"); you may not use this file except in
|
||||
* compliance with the License. You may obtain a copy of the License at
|
||||
* http://opensource.org/licenses/MIT
|
||||
* 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 QCLOUD_BLE_QIOT_LLSYNC_DEVICE_H
|
||||
#define QCLOUD_BLE_QIOT_LLSYNC_DEVICE_H
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include <stdint.h>
|
||||
//#include <stdbool.h>
|
||||
#include "ble_qiot_common.h"
|
||||
#include "ble_qiot_export.h"
|
||||
#include "ble_qiot_hmac.h"
|
||||
#include "ble_qiot_llsync_event.h"
|
||||
|
||||
#define LLSYNC_BIND_STATE_MASK 0x03
|
||||
#define LLSYNC_PROTO_VER_BIT 0x04
|
||||
#define LLSYNC_PROTOCOL_VERSION_MASK 0xF0
|
||||
#define LLSYNC_MTU_SET_MASK 0x8000
|
||||
|
||||
#define LLSYNC_MTU_SET_RESULT_ERR 0xFFFF // some error when setting mtu
|
||||
|
||||
#define BLE_QIOT_LLSYNC_PROTOCOL_VERSION (2) // llsync protocol version, equal or less than 15
|
||||
|
||||
#define ATT_DEFAULT_MTU 23 // default att mtu
|
||||
#define ATT_MTU_TO_LLSYNC_MTU(_att_mtu) ((_att_mtu)-3)
|
||||
|
||||
#define BLE_LOCAL_PSK_LEN 4
|
||||
#define BLE_BIND_IDENTIFY_STR_LEN 8
|
||||
#define BLE_EXPIRATION_TIME 60 // timestamp expiration value
|
||||
#define BLE_UNBIND_REQUEST_STR "UnbindRequest"
|
||||
#define BLE_UNBIND_REQUEST_STR_LEN (sizeof("UnbindRequest") - 1)
|
||||
#define BLE_UNBIND_RESPONSE "UnbindResponse"
|
||||
#define BLE_UNBIND_RESPONSE_STR_LEN (sizeof("UnbindResponse") - 1)
|
||||
|
||||
typedef enum {
|
||||
E_DEV_MSG_SYNC_TIME = 0, // sync info before bind
|
||||
E_DEV_MSG_CONN_VALID, // connect request
|
||||
E_DEV_MSG_BIND_SUCC, // inform bind success
|
||||
E_DEV_MSG_BIND_FAIL, // inform bind failed
|
||||
E_DEV_MSG_UNBIND, // unbind request
|
||||
E_DEV_MSG_CONN_SUCC, // inform connect result
|
||||
E_DEV_MSG_CONN_FAIL,
|
||||
E_DEV_MSG_UNBIND_SUCC, // inform unbind result
|
||||
E_DEV_MSG_UNBIND_FAIL,
|
||||
E_DEV_MSG_SET_MTU_RESULT, // inform set mtu result
|
||||
E_DEV_MSG_BIND_TIMEOUT, // inform bind timeout
|
||||
E_DEV_MSG_GET_DEV_INFO = 0xE0, // configure network start
|
||||
E_DEV_MSG_SET_WIFI_MODE,
|
||||
E_DEV_MSG_SET_WIFI_INFO,
|
||||
E_DEV_MSG_SET_WIFI_CONNECT,
|
||||
E_DEV_MSG_SET_WIFI_TOKEN,
|
||||
E_DEV_MSG_GET_DEV_LOG,
|
||||
E_DEV_MSG_MSG_BUTT,
|
||||
} e_dev_info_msg_type;
|
||||
|
||||
typedef enum {
|
||||
E_LLSYNC_BIND_IDLE = 0, // no bind
|
||||
E_LLSYNC_BIND_WAIT, // wait bind, return idle state if no bind in the period
|
||||
E_LLSYNC_BIND_SUCC, // bound
|
||||
} e_llsync_bind_state;
|
||||
|
||||
typedef enum {
|
||||
E_LLSYNC_DISCONNECTED = 0,
|
||||
E_LLSYNC_CONNECTED,
|
||||
} e_llsync_connection_state;
|
||||
|
||||
typedef enum {
|
||||
E_BLE_DISCONNECTED = 0,
|
||||
E_BLE_CONNECTED,
|
||||
} e_ble_connection_state;
|
||||
|
||||
typedef struct ble_device_info_t_ {
|
||||
char product_id[BLE_QIOT_PRODUCT_ID_LEN];
|
||||
char device_name[BLE_QIOT_DEVICE_NAME_LEN + 1];
|
||||
char psk[BLE_QIOT_PSK_LEN];
|
||||
char mac[BLE_QIOT_MAC_LEN];
|
||||
} ble_device_info;
|
||||
|
||||
typedef struct ble_core_data_ {
|
||||
uint8_t bind_state;
|
||||
char local_psk[BLE_LOCAL_PSK_LEN];
|
||||
char identify_str[BLE_BIND_IDENTIFY_STR_LEN];
|
||||
} ble_core_data;
|
||||
|
||||
// write to uuid FEE1 before bind
|
||||
typedef struct ble_bind_data_t_ {
|
||||
int nonce;
|
||||
int timestamp;
|
||||
} ble_bind_data;
|
||||
|
||||
// connect data struct
|
||||
typedef struct ble_conn_data_t_ {
|
||||
int timestamp;
|
||||
char sign_info[SHA1_DIGEST_SIZE];
|
||||
} ble_conn_data;
|
||||
|
||||
// unbind data struct
|
||||
typedef struct ble_unbind_data_t_ {
|
||||
char sign_info[SHA1_DIGEST_SIZE];
|
||||
} ble_unbind_data;
|
||||
|
||||
typedef struct {
|
||||
bool have_data; // start received package
|
||||
uint8_t type; // event type
|
||||
uint16_t buf_len; // the length of data
|
||||
char buf[BLE_QIOT_EVENT_MAX_SIZE];
|
||||
} ble_event_slice_t;
|
||||
|
||||
// read sdk data from flash
|
||||
ble_qiot_ret_status_t ble_init_flash_data(void);
|
||||
|
||||
// set llsync bind state
|
||||
void llsync_bind_state_set(e_llsync_bind_state new_state);
|
||||
|
||||
// get llsync bind state
|
||||
e_llsync_bind_state llsync_bind_state_get(void);
|
||||
|
||||
// set llsync connection state
|
||||
void llsync_connection_state_set(e_llsync_connection_state new_state);
|
||||
|
||||
// set ble connection state
|
||||
void ble_connection_state_set(e_ble_connection_state new_state);
|
||||
|
||||
// get llsync connection state
|
||||
bool llsync_is_connected(void);
|
||||
|
||||
// get ble connection state
|
||||
bool ble_is_connected(void);
|
||||
|
||||
// get broadcast data
|
||||
int ble_get_my_broadcast_data(char *out_buf, int buf_len);
|
||||
|
||||
// get bind authcode, return authcode length;
|
||||
// out_buf length must greater than SHA1_DIGEST_SIZE + BLE_QIOT_DEVICE_NAME_LEN
|
||||
int ble_bind_get_authcode(const char *bind_data, uint16_t data_len, char *out_buf, uint16_t buf_len);
|
||||
|
||||
// write bind result to flash, return 0 is success
|
||||
ble_qiot_ret_status_t ble_bind_write_result(const char *result, uint16_t len);
|
||||
|
||||
// write unbind result to flash, return 0 is success
|
||||
ble_qiot_ret_status_t ble_unbind_write_result(void);
|
||||
|
||||
// get connect authcode, return authcode length;
|
||||
// out_buf length must greater than SHA1_DIGEST_SIZE + BLE_QIOT_DEVICE_NAME_LEN
|
||||
int ble_conn_get_authcode(const char *conn_data, uint16_t data_len, char *out_buf, uint16_t buf_len);
|
||||
|
||||
// get connect authcode, return authcode length;
|
||||
// out_buf length must greater than SHA1_DIGEST_SIZE + BLE_UNBIND_RESPONSE_STR_LEN
|
||||
int ble_unbind_get_authcode(const char *unbind_data, uint16_t data_len, char *out_buf, uint16_t buf_len);
|
||||
|
||||
// inform device the result of mtu setting
|
||||
int ble_inform_mtu_result(const char *result, uint16_t data_len);
|
||||
|
||||
// get llsync mtu
|
||||
uint16_t llsync_mtu_get(void);
|
||||
|
||||
// update llsync mtu
|
||||
void llsync_mtu_update(uint16_t sync_mtu);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif // QCLOUD_BLE_QIOT_LLSYNC_DEVICE_H
|
||||
@ -0,0 +1,56 @@
|
||||
/*
|
||||
* Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved.
|
||||
* Licensed under the MIT License (the "License"); you may not use this file except in
|
||||
* compliance with the License. You may obtain a copy of the License at
|
||||
* http://opensource.org/licenses/MIT
|
||||
* 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 QCLOUD_BLE_QIOT_LLSYNC_EVENT_H
|
||||
#define QCLOUD_BLE_QIOT_LLSYNC_EVENT_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#include "ble_qiot_config.h"
|
||||
#include "ble_qiot_export.h"
|
||||
|
||||
enum {
|
||||
BLE_QIOT_EVENT_NO_SLICE = 0,
|
||||
BLE_QIOT_EVENT_SLICE_HEAD = 1,
|
||||
BLE_QIOT_EVENT_SLICE_BODY = 2,
|
||||
BLE_QIOT_EVENT_SLICE_FOOT = 3,
|
||||
};
|
||||
|
||||
// 1 byte type + 2 bytes payload-length
|
||||
#define BLE_QIOT_EVENT_FIXED_HEADER_LEN (3)
|
||||
|
||||
// the bit 15 - 14 is slice flag, bit 13 - 0 is tlv length
|
||||
#define BLE_QIOT_IS_SLICE_PACKAGE(_C) ((_C)&0XC0)
|
||||
#define BLE_QIOT_IS_SLICE_HEADER(_C) (((_C)&0XC0) == 0X40)
|
||||
#define BLE_QIOT_IS_SLICE_BODY(_C) (((_C)&0XC0) == 0X80)
|
||||
#define BLE_QIOT_IS_SLICE_TAIL(_C) (((_C)&0XC0) == 0XC0)
|
||||
|
||||
#define BLE_QIOT_STRING_TYPE_LEN 2 // string/struct type length
|
||||
#define BLE_QIOT_MIN_STRING_TYPE_LEN (BLE_QIOT_STRING_TYPE_LEN + 1) // at least 2 bytes length and 1 byte payload
|
||||
#define BLE_QIOT_NOT_SUPPORT_WARN " not support, please check the data template"
|
||||
|
||||
ble_qiot_ret_status_t ble_event_notify(uint8_t type, uint8_t *header, uint8_t header_len, const char *buf,
|
||||
uint16_t buf_len);
|
||||
|
||||
ble_qiot_ret_status_t ble_event_notify2(uint8_t type, uint8_t length_flag, uint8_t *header, uint8_t header_len,
|
||||
const char *buf, uint16_t buf_len);
|
||||
|
||||
ble_qiot_ret_status_t ble_event_sync_wait_time(void);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // QCLOUD_BLE_QIOT_LLSYNC_EVENT_H
|
||||
@ -0,0 +1,124 @@
|
||||
/*
|
||||
* Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved.
|
||||
* Licensed under the MIT License (the "License"); you may not use this file except in
|
||||
* compliance with the License. You may obtain a copy of the License at
|
||||
* http://opensource.org/licenses/MIT
|
||||
* 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 QCLOUD_BLE_QIOT_LLSYNC_OTA_H
|
||||
#define QCLOUD_BLE_QIOT_LLSYNC_OTA_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#include "ble_qiot_config.h"
|
||||
#include "ble_qiot_export.h"
|
||||
|
||||
#define BLE_QIOT_GET_OTA_REQUEST_HEADER_LEN 3 // the ota request header len
|
||||
#define BLE_QIOT_OTA_DATA_HEADER_LEN 3 // the ota data header len
|
||||
|
||||
// ota feature
|
||||
#define BLE_QIOT_OTA_ENABLE (1 << 0)
|
||||
#define BLE_QIOT_OTA_RESUME_ENABLE (1 << 1)
|
||||
|
||||
// ota file valid result
|
||||
#define BLE_QIOT_OTA_VALID_SUCCESS (1 << 7)
|
||||
#define BLE_QIOT_OTA_VALID_FAIL (0 << 7)
|
||||
|
||||
#define BLE_QIOT_OTA_MAX_VERSION_STR (32) // max ota version length
|
||||
#define BLE_QIOT_OTA_PAGE_VALID_VAL 0x5A // ota info valid flag
|
||||
|
||||
#define BLE_QIOT_OTA_FIRST_TIMEOUT (1)
|
||||
#define BLE_QIOT_OTA_MAX_RETRY_COUNT 5 // disconnect if retry times more than BLE_QIOT_OTA_MAX_RETRY_COUNT
|
||||
|
||||
// ota control bits
|
||||
#define BLE_QIOT_OTA_REQUEST_BIT (1 << 0)
|
||||
#define BLE_QIOT_OTA_RECV_END_BIT (1 << 1)
|
||||
#define BLE_QIOT_OTA_RECV_DATA_BIT (1 << 2)
|
||||
#define BLE_QIOT_OTA_FIRST_RETRY_BIT (1 << 3)
|
||||
#define BLE_QIOT_OTA_DO_VALID_BIT (1 << 4)
|
||||
#define BLE_QIOT_OTA_HAVE_DATA_BIT (1 << 5)
|
||||
|
||||
// the reason of ota file error
|
||||
enum {
|
||||
BLE_QIOT_OTA_CRC_ERROR = 0,
|
||||
BLE_QIOT_OTA_READ_FLASH_ERROR = 1,
|
||||
BLE_QIOT_OTA_FILE_ERROR = 2,
|
||||
};
|
||||
|
||||
// ota data type
|
||||
enum {
|
||||
BLE_QIOT_OTA_MSG_REQUEST = 0,
|
||||
BLE_QIOT_OTA_MSG_DATA = 1,
|
||||
BLE_QIOT_OTA_MSG_END = 2,
|
||||
BLE_QIOT_OTA_MSG_BUTT,
|
||||
};
|
||||
|
||||
// ota request reply
|
||||
typedef struct ble_ota_reply_info_ {
|
||||
uint8_t package_nums; // package numbers in a loop
|
||||
uint8_t package_size; // each package size
|
||||
uint8_t retry_timeout; // data retry
|
||||
uint8_t reboot_timeout; // max time of device reboot
|
||||
uint32_t last_file_size; // the file already received
|
||||
uint8_t package_interval; // package send interval on the server
|
||||
uint8_t rsv[3];
|
||||
} ble_ota_reply_info;
|
||||
|
||||
typedef struct ble_ota_file_info_ {
|
||||
uint32_t file_size;
|
||||
uint32_t file_crc;
|
||||
uint8_t file_version[BLE_QIOT_OTA_MAX_VERSION_STR];
|
||||
} ble_ota_file_info;
|
||||
|
||||
// ota info saved in flash if support resuming
|
||||
typedef struct ble_ota_info_record_ {
|
||||
uint8_t valid_flag;
|
||||
uint8_t rsv[3];
|
||||
uint32_t last_file_size; // the file size already write in flash
|
||||
uint32_t last_address; // the address file saved
|
||||
ble_ota_file_info download_file_info;
|
||||
} ble_ota_info_record;
|
||||
|
||||
// ota user callback
|
||||
typedef struct ble_ota_user_callback_ {
|
||||
ble_ota_start_callback start_cb;
|
||||
ble_ota_stop_callback stop_cb;
|
||||
ble_ota_valid_file_callback valid_file_cb;
|
||||
} ble_ota_user_callback;
|
||||
|
||||
// ota request package: 1 byte type + 2 bytes length + 4 bytes size + 4 bytes crc + 1 byte version length + 1 ~ 32 bytes
|
||||
// version
|
||||
typedef struct {
|
||||
bool have_data; // start received package
|
||||
uint8_t type; // event type
|
||||
uint16_t buf_len; // the length of data
|
||||
char buf[BLE_QIOT_GET_OTA_REQUEST_HEADER_LEN + 4 + 4 + 1 + BLE_QIOT_OTA_MAX_VERSION_STR];
|
||||
} ble_ota_request_slice_t;
|
||||
|
||||
// ota reply info
|
||||
typedef struct ble_ota_reply_t_ {
|
||||
uint32_t file_size;
|
||||
uint8_t req;
|
||||
} ble_ota_reply_t;
|
||||
|
||||
ble_qiot_ret_status_t ble_ota_request_handle(const char *in_buf, int buf_len);
|
||||
|
||||
ble_qiot_ret_status_t ble_ota_data_handle(const char *in_buf, int buf_len);
|
||||
|
||||
ble_qiot_ret_status_t ble_ota_file_end_handle(void);
|
||||
|
||||
void ble_ota_stop(void);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // QCLOUD_BLE_QIOT_LLSYNC_OTA_H
|
||||
103
apps/common/third_party_profile/Tecent_LL/include/ble_qiot_log.h
Normal file
103
apps/common/third_party_profile/Tecent_LL/include/ble_qiot_log.h
Normal file
@ -0,0 +1,103 @@
|
||||
/*
|
||||
* Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved.
|
||||
* Licensed under the MIT License (the "License"); you may not use this file except in
|
||||
* compliance with the License. You may obtain a copy of the License at
|
||||
* http://opensource.org/licenses/MIT
|
||||
* 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 QCLOUD_BLE_QIOT_LOG_H
|
||||
#define QCLOUD_BLE_QIOT_LOG_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include "ble_qiot_config.h"
|
||||
|
||||
typedef enum {
|
||||
BLE_QIOT_LOG_LEVEL_NONE = 0,
|
||||
BLE_QIOT_LOG_LEVEL_ERR,
|
||||
BLE_QIOT_LOG_LEVEL_WARN,
|
||||
BLE_QIOT_LOG_LEVEL_INFO,
|
||||
BLE_QIOT_LOG_LEVEL_DEBUG,
|
||||
BLE_QIOT_LOG_LEVEL_ALL,
|
||||
} e_ble_qiot_log_level;
|
||||
|
||||
// log new line feed type
|
||||
#define LINE_NONE
|
||||
#define LINE_LF "\n"
|
||||
#define LINE_CR "\r"
|
||||
#define LINE_CRLF "\r\n"
|
||||
|
||||
// log new line feed type config
|
||||
#define LOG_LINE_FEED_TYPE LINE_CRLF
|
||||
|
||||
extern e_ble_qiot_log_level g_log_level;
|
||||
|
||||
#ifndef ble_qiot_log_d
|
||||
#define ble_qiot_log_d(fmt, args...) \
|
||||
do { \
|
||||
if (g_log_level < BLE_QIOT_LOG_LEVEL_DEBUG) \
|
||||
break; \
|
||||
BLE_QIOT_LOG_PRINT("qiot debug: " fmt LOG_LINE_FEED_TYPE, ##args); \
|
||||
} while (0)
|
||||
#endif
|
||||
|
||||
#ifndef ble_qiot_log_i
|
||||
#define ble_qiot_log_i(fmt, args...) \
|
||||
do { \
|
||||
if (g_log_level < BLE_QIOT_LOG_LEVEL_INFO) \
|
||||
break; \
|
||||
BLE_QIOT_LOG_PRINT("qiot info: " fmt LOG_LINE_FEED_TYPE, ##args); \
|
||||
} while (0)
|
||||
#endif
|
||||
|
||||
#ifndef ble_qiot_log_w
|
||||
#define ble_qiot_log_w(fmt, args...) \
|
||||
do { \
|
||||
if (g_log_level < BLE_QIOT_LOG_LEVEL_WARN) \
|
||||
break; \
|
||||
BLE_QIOT_LOG_PRINT("qiot warn(%s|%d): " fmt LOG_LINE_FEED_TYPE, __FILE__, __LINE__, ##args); \
|
||||
} while (0)
|
||||
#endif
|
||||
|
||||
#ifndef ble_qiot_log_e
|
||||
#define ble_qiot_log_e(fmt, args...) \
|
||||
do { \
|
||||
if (g_log_level < BLE_QIOT_LOG_LEVEL_ERR) \
|
||||
break; \
|
||||
BLE_QIOT_LOG_PRINT("qiot err(%s|%d): " fmt LOG_LINE_FEED_TYPE, __FILE__, __LINE__, ##args); \
|
||||
} while (0)
|
||||
#endif
|
||||
|
||||
#ifndef ble_qiot_log
|
||||
#define ble_qiot_log(level, fmt, args...) \
|
||||
do { \
|
||||
if (g_log_level < level) \
|
||||
break; \
|
||||
BLE_QIOT_LOG_PRINT("qiot log(%s|%d): " fmt LOG_LINE_FEED_TYPE, __FILE__, __LINE__, ##args); \
|
||||
} while (0)
|
||||
#endif
|
||||
|
||||
// this function only use for ble_qiot_log_hex
|
||||
#ifndef ble_qiot_log_raw
|
||||
#define ble_qiot_log_raw(fmt, args...) \
|
||||
do { \
|
||||
BLE_QIOT_LOG_PRINT(fmt, ##args); \
|
||||
} while (0)
|
||||
#endif
|
||||
|
||||
void ble_qiot_set_log_level(e_ble_qiot_log_level level);
|
||||
|
||||
#if !BLE_QIOT_USER_DEFINE_HEXDUMP
|
||||
void ble_qiot_log_hex(e_ble_qiot_log_level level, const char *hex_name, const char *data, uint32_t data_len);
|
||||
#endif // BLE_QIOT_USER_DEFINE_HEXDUMP
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif // QCLOUD_BLE_QIOT_LOG_H
|
||||
@ -0,0 +1,94 @@
|
||||
/*
|
||||
* Tencent is pleased to support the open source community by making IoT Hub available.
|
||||
* Copyright (C) 2018-2020 THL A29 Limited, a Tencent company. All rights reserved.
|
||||
|
||||
* Licensed under the MIT License (the "License"); you may not use this file except in
|
||||
* compliance with the License. You may obtain a copy of the License at
|
||||
* http://opensource.org/licenses/MIT
|
||||
|
||||
* 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 QCLOUD_BLE_QIOT_MD5_H
|
||||
#define QCLOUD_BLE_QIOT_MD5_H
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#define MD5_DIGEST_SIZE 16
|
||||
|
||||
typedef struct {
|
||||
unsigned int total[2]; /*!< number of bytes processed */
|
||||
unsigned int state[4]; /*!< intermediate digest state */
|
||||
unsigned char buffer[64]; /*!< data block being processed */
|
||||
} iot_md5_context;
|
||||
|
||||
/**
|
||||
* @brief init MD5 context
|
||||
*
|
||||
* @param ctx MD5 context
|
||||
*/
|
||||
void utils_md5_init(iot_md5_context *ctx);
|
||||
|
||||
/**
|
||||
* @brief free MD5 context
|
||||
*
|
||||
* @param ctx MD5 context
|
||||
*/
|
||||
void utils_md5_free(iot_md5_context *ctx);
|
||||
|
||||
/**
|
||||
* @brief clone MD5 context
|
||||
*
|
||||
* @param dst destination MD5 context
|
||||
* @param src source MD5 context
|
||||
*/
|
||||
void utils_md5_clone(iot_md5_context *dst, const iot_md5_context *src);
|
||||
|
||||
/**
|
||||
* @brief start MD5 calculation
|
||||
*
|
||||
* @param ctx MD5 context
|
||||
*/
|
||||
void utils_md5_starts(iot_md5_context *ctx);
|
||||
|
||||
/**
|
||||
* @brief MD5 update
|
||||
*
|
||||
* @param ctx MD5 context
|
||||
* @param input input data
|
||||
* @param ilen data length
|
||||
*/
|
||||
void utils_md5_update(iot_md5_context *ctx, const unsigned char *input, unsigned int ilen);
|
||||
|
||||
/**
|
||||
* @brief finish MD5 calculation
|
||||
*
|
||||
* @param ctx MD5 context
|
||||
* @param output MD5 result
|
||||
*/
|
||||
void utils_md5_finish(iot_md5_context *ctx, unsigned char output[16]);
|
||||
|
||||
/* MD5 internal process */
|
||||
void utils_md5_process(iot_md5_context *ctx, const unsigned char data[64]);
|
||||
|
||||
/**
|
||||
* @brief Output = MD5( input buffer )
|
||||
*
|
||||
* @param input data input
|
||||
* @param ilen data lenght
|
||||
* @param output MD5 result
|
||||
*/
|
||||
void utils_md5(const unsigned char *input, unsigned int ilen, unsigned char output[16]);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
@ -0,0 +1,93 @@
|
||||
/*
|
||||
* Tencent is pleased to support the open source community by making IoT Hub available.
|
||||
* Copyright (C) 2018-2020 THL A29 Limited, a Tencent company. All rights reserved.
|
||||
|
||||
* Licensed under the MIT License (the "License"); you may not use this file except in
|
||||
* compliance with the License. You may obtain a copy of the License at
|
||||
* http://opensource.org/licenses/MIT
|
||||
|
||||
* 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 QCLOUD_BLE_IOT_PARAM_CHECK_H_
|
||||
#define QCLOUD_BLE_IOT_PARAM_CHECK_H_
|
||||
|
||||
#if defined(__cplusplus)
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include "ble_qiot_log.h"
|
||||
|
||||
#define NUMBERIC_SANITY_CHECK(num, err) \
|
||||
do { \
|
||||
if (0 == (num)) { \
|
||||
ble_qiot_log_e("Invalid argument, numeric 0"); \
|
||||
return (err); \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#define NUMBERIC_SANITY_CHECK_RTN(num) \
|
||||
do { \
|
||||
if (0 == (num)) { \
|
||||
ble_qiot_log_e("Invalid argument, numeric 0"); \
|
||||
return; \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#define BUFF_LEN_SANITY_CHECK(num, min, err) \
|
||||
do { \
|
||||
if ((min) > (num)) { \
|
||||
ble_qiot_log_e("Invalid argument, %d <= %d", min, num); \
|
||||
return (err); \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#define POINTER_SANITY_CHECK(ptr, err) \
|
||||
do { \
|
||||
if (NULL == (ptr)) { \
|
||||
ble_qiot_log_e("Invalid argument, %s = %p", #ptr, ptr); \
|
||||
return (err); \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#define POINTER_SANITY_CHECK_RTN(ptr) \
|
||||
do { \
|
||||
if (NULL == (ptr)) { \
|
||||
ble_qiot_log_e("Invalid argument, %s = %p", #ptr, ptr); \
|
||||
return; \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#define STRING_PTR_SANITY_CHECK(ptr, err) \
|
||||
do { \
|
||||
if (NULL == (ptr)) { \
|
||||
ble_qiot_log_e("Invalid argument, %s = %p", #ptr, (ptr)); \
|
||||
return (err); \
|
||||
} \
|
||||
if (0 == strlen((ptr))) { \
|
||||
ble_qiot_log_e("Invalid argument, %s = '%s'", #ptr, (ptr)); \
|
||||
return (err); \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#define STRING_PTR_SANITY_CHECK_RTN(ptr) \
|
||||
do { \
|
||||
if (NULL == (ptr)) { \
|
||||
ble_qiot_log_e("Invalid argument, %s = %p", #ptr, (ptr)); \
|
||||
return; \
|
||||
} \
|
||||
if (0 == strlen((ptr))) { \
|
||||
ble_qiot_log_e("Invalid argument, %s = '%s'", #ptr, (ptr)); \
|
||||
return; \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#if defined(__cplusplus)
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* QCLOUD_BLE_IOT_PARAM_CHECK_H_ */
|
||||
@ -0,0 +1,97 @@
|
||||
/*
|
||||
* Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved.
|
||||
* Licensed under the MIT License (the "License"); you may not use this file except in
|
||||
* compliance with the License. You may obtain a copy of the License at
|
||||
* http://opensource.org/licenses/MIT
|
||||
* 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 QCLOUD_BLE_IOT_SERVICE_H_
|
||||
#define QCLOUD_BLE_IOT_SERVICE_H_
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#include "ble_qiot_export.h"
|
||||
#include "ble_qiot_llsync_data.h"
|
||||
#include "ble_qiot_template.h"
|
||||
|
||||
// message type, reference data template
|
||||
enum {
|
||||
BLE_QIOT_MSG_TYPE_PROPERTY = 0,
|
||||
BLE_QIOT_MSG_TYPE_EVENT,
|
||||
BLE_QIOT_MSG_TYPE_ACTION,
|
||||
BLE_QIOT_MSG_TYPE_BUTT,
|
||||
};
|
||||
|
||||
// define reply result
|
||||
enum {
|
||||
BLE_QIOT_REPLY_SUCCESS = 0,
|
||||
BLE_QIOT_REPLY_FAIL,
|
||||
BLE_QIOT_REPLY_DATA_ERR,
|
||||
BLE_QIOT_REPLY_BUTT,
|
||||
};
|
||||
|
||||
// define message type that from server to device
|
||||
enum {
|
||||
BLE_QIOT_DATA_DOWN_REPORT_REPLY = 0,
|
||||
BLE_QIOT_DATA_DOWN_CONTROL,
|
||||
BLE_QIOT_DATA_DOWN_GET_STATUS_REPLY,
|
||||
BLE_QIOT_DATA_DOWN_ACTION,
|
||||
BLE_QIOT_DATA_DOWN_EVENT_REPLY,
|
||||
};
|
||||
|
||||
// define message type that from device to server
|
||||
enum {
|
||||
BLE_QIOT_EVENT_UP_PROPERTY_REPORT = 0,
|
||||
BLE_QIOT_EVENT_UP_CONTROL_REPLY,
|
||||
BLE_QIOT_EVENT_UP_GET_STATUS,
|
||||
BLE_QIOT_EVENT_UP_EVENT_POST,
|
||||
BLE_QIOT_EVENT_UP_ACTION_REPLY,
|
||||
BLE_QIOT_EVENT_UP_BIND_SIGN_RET,
|
||||
BLE_QIOT_EVENT_UP_CONN_SIGN_RET,
|
||||
BLE_QIOT_EVENT_UP_UNBIND_SIGN_RET,
|
||||
BLE_QIOT_EVENT_UP_REPORT_MTU,
|
||||
BLE_QIOT_EVENT_UP_REPLY_OTA_REPORT,
|
||||
BLE_QIOT_EVENT_UP_REPLY_OTA_DATA,
|
||||
BLE_QIOT_EVENT_UP_REPORT_CHECK_RESULT,
|
||||
BLE_QIOT_EVENT_UP_SYNC_MTU,
|
||||
BLE_QIOT_EVENT_UP_SYNC_WAIT_TIME,
|
||||
BLE_QIOT_EVENT_UP_WIFI_MODE = 0xE0,
|
||||
BLE_QIOT_EVENT_UP_WIFI_INFO,
|
||||
BLE_QIOT_EVENT_UP_WIFI_CONNECT,
|
||||
BLE_QIOT_EVENT_UP_WIFI_TOKEN,
|
||||
BLE_QIOT_EVENT_UP_WIFI_LOG,
|
||||
BLE_QIOT_EVENT_UP_BUTT,
|
||||
};
|
||||
|
||||
// msg header define, bit 7-6 is msg type, bit 5 means request or reply, bit 4 - 0 is id
|
||||
#define BLE_QIOT_PARSE_MSG_HEAD_TYPE(_C) (((_C) & 0XFF) >> 6)
|
||||
#define BLE_QIOT_PARSE_MSG_HEAD_EFFECT(_C) ((((_C) & 0XFF) & 0X20) ? BLE_QIOT_EFFECT_REPLY : BLE_QIOT_EFFECT_REQUEST)
|
||||
#define BLE_QIOT_PARSE_MSG_HEAD_ID(_C) ((_C) & 0X1F)
|
||||
|
||||
// tlv header define, bit 7 - 5 is type, bit 4 - 0 depends on type of data template
|
||||
#define BLE_QIOT_PARSE_TLV_HEAD_TYPE(_C) (((_C) & 0XFF) >> 5)
|
||||
#define BLE_QIOT_PARSE_TLV_HEAD_ID(_C) ((_C) & 0X1F)
|
||||
|
||||
// handle llsync device info
|
||||
// return 0 is success, other is error
|
||||
int ble_device_info_msg_handle(const char *in_buf, int in_len);
|
||||
|
||||
// lldata message from remote
|
||||
// return 0 is success, other is error
|
||||
int ble_lldata_msg_handle(const char *in_buf, int in_len);
|
||||
|
||||
// ota message from remote
|
||||
// return 0 is success, other is error
|
||||
int ble_ota_msg_handle(const char *buf, uint16_t len);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif // QCLOUD_BLE_IOT_SERVICE_H_
|
||||
@ -0,0 +1,93 @@
|
||||
/*
|
||||
* Tencent is pleased to support the open source community by making IoT Hub available.
|
||||
* Copyright (C) 2018-2020 THL A29 Limited, a Tencent company. All rights reserved.
|
||||
|
||||
* Licensed under the MIT License (the "License"); you may not use this file except in
|
||||
* compliance with the License. You may obtain a copy of the License at
|
||||
* http://opensource.org/licenses/MIT
|
||||
|
||||
* 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 QCLOUD_BLE_LLSYNC_BLE_QIOT_SHA1_H
|
||||
#define QCLOUD_BLE_LLSYNC_BLE_QIOT_SHA1_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stddef.h>
|
||||
|
||||
/**
|
||||
* \brief SHA-1 context structure
|
||||
*/
|
||||
typedef struct {
|
||||
uint32_t total[2]; /*!< number of bytes processed */
|
||||
uint32_t state[5]; /*!< intermediate digest state */
|
||||
unsigned char buffer[64]; /*!< data block being processed */
|
||||
} iot_sha1_context;
|
||||
|
||||
/**
|
||||
* \brief Initialize SHA-1 context
|
||||
*
|
||||
* \param ctx SHA-1 context to be initialized
|
||||
*/
|
||||
void utils_sha1_init(iot_sha1_context *ctx);
|
||||
|
||||
/**
|
||||
* \brief Clear SHA-1 context
|
||||
*
|
||||
* \param ctx SHA-1 context to be cleared
|
||||
*/
|
||||
void utils_sha1_free(iot_sha1_context *ctx);
|
||||
|
||||
/**
|
||||
* \brief Clone (the state of) a SHA-1 context
|
||||
*
|
||||
* \param dst The destination context
|
||||
* \param src The context to be cloned
|
||||
*/
|
||||
void utils_sha1_clone(iot_sha1_context *dst, const iot_sha1_context *src);
|
||||
|
||||
/**
|
||||
* \brief SHA-1 context setup
|
||||
*
|
||||
* \param ctx context to be initialized
|
||||
*/
|
||||
void utils_sha1_starts(iot_sha1_context *ctx);
|
||||
|
||||
/**
|
||||
* \brief SHA-1 process buffer
|
||||
*
|
||||
* \param ctx SHA-1 context
|
||||
* \param input buffer holding the data
|
||||
* \param ilen length of the input data
|
||||
*/
|
||||
void utils_sha1_update(iot_sha1_context *ctx, const unsigned char *input, size_t ilen);
|
||||
|
||||
/**
|
||||
* \brief SHA-1 final digest
|
||||
*
|
||||
* \param ctx SHA-1 context
|
||||
* \param output SHA-1 checksum result
|
||||
*/
|
||||
void utils_sha1_finish(iot_sha1_context *ctx, unsigned char output[20]);
|
||||
|
||||
/* Internal use */
|
||||
void utils_sha1_process(iot_sha1_context *ctx, const unsigned char data[64]);
|
||||
|
||||
/**
|
||||
* \brief Output = SHA-1( input buffer )
|
||||
*
|
||||
* \param input buffer holding the data
|
||||
* \param ilen length of the input data
|
||||
* \param output SHA-1 checksum result
|
||||
*/
|
||||
void utils_sha1(const unsigned char *input, size_t ilen, unsigned char output[20]);
|
||||
|
||||
#endif // QCLOUD_BLE_LLSYNC_BLE_QIOT_SHA1_H
|
||||
@ -0,0 +1,119 @@
|
||||
/*
|
||||
* Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved.
|
||||
* Licensed under the MIT License (the "License"); you may not use this file except in
|
||||
* compliance with the License. You may obtain a copy of the License at
|
||||
* http://opensource.org/licenses/MIT
|
||||
* 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_QIOT_TEMPLATE_H_
|
||||
#define BLE_QIOT_TEMPLATE_H_
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include <stdint.h>
|
||||
//#include <stdbool.h>
|
||||
|
||||
|
||||
// data type in template, corresponding to type in json file
|
||||
enum {
|
||||
BLE_QIOT_DATA_TYPE_BOOL = 0,
|
||||
BLE_QIOT_DATA_TYPE_INT,
|
||||
BLE_QIOT_DATA_TYPE_STRING,
|
||||
BLE_QIOT_DATA_TYPE_FLOAT,
|
||||
BLE_QIOT_DATA_TYPE_ENUM,
|
||||
BLE_QIOT_DATA_TYPE_TIME,
|
||||
BLE_QIOT_DATA_TYPE_STRUCT,
|
||||
BLE_QIOT_DATA_TYPE_BUTT,
|
||||
};
|
||||
|
||||
// message type, reference data template
|
||||
enum {
|
||||
BLE_QIOT_PROPERTY_AUTH_RW = 0,
|
||||
BLE_QIOT_PROPERTY_AUTH_READ,
|
||||
BLE_QIOT_PROPERTY_AUTH_BUTT,
|
||||
};
|
||||
|
||||
// define message flow direction
|
||||
enum {
|
||||
BLE_QIOT_EFFECT_REQUEST = 0,
|
||||
BLE_QIOT_EFFECT_REPLY,
|
||||
BLE_QIOT_EFFECT_BUTT,
|
||||
};
|
||||
#define BLE_QIOT_PACKAGE_MSG_HEAD(_TYPE, _REPLY, _ID) (((_TYPE) << 6) | (((_REPLY) == BLE_QIOT_EFFECT_REPLY) << 5) | ((_ID) & 0X1F))
|
||||
#define BLE_QIOT_PACKAGE_TLV_HEAD(_TYPE, _ID) (((_TYPE) << 5) | ((_ID) & 0X1F))
|
||||
|
||||
|
||||
// define tlv struct
|
||||
typedef struct {
|
||||
uint8_t type;
|
||||
uint8_t id;
|
||||
uint16_t len;
|
||||
char *val;
|
||||
} e_ble_tlv;
|
||||
#define BLE_QIOT_INCLUDE_PROPERTY
|
||||
|
||||
// define property id
|
||||
enum {
|
||||
BLE_QIOT_PROPERTY_ID_POWER_SWITCH = 0,
|
||||
BLE_QIOT_PROPERTY_ID_BUTT,
|
||||
};
|
||||
|
||||
// define property set handle return 0 if success, other is error
|
||||
// sdk call the function that inform the server data to the device
|
||||
typedef int (*property_set_cb)(const char *data, uint16_t len);
|
||||
|
||||
// define property get handle. return the data length obtained, -1 is error, 0 is no data
|
||||
// sdk call the function fetch user data and send to the server, the data should wrapped by user adn skd just transmit
|
||||
typedef int (*property_get_cb)(char *buf, uint16_t buf_len);
|
||||
|
||||
// each property have a struct ble_property_t, make up a array named sg_ble_property_array
|
||||
typedef struct {
|
||||
property_set_cb set_cb; //set callback
|
||||
property_get_cb get_cb; //get callback
|
||||
uint8_t authority; //property authority
|
||||
uint8_t type; //data type
|
||||
} ble_property_t;
|
||||
// property module
|
||||
#ifdef BLE_QIOT_INCLUDE_PROPERTY
|
||||
uint8_t ble_get_property_type_by_id(uint8_t id);
|
||||
|
||||
int ble_user_property_set_data(const e_ble_tlv *tlv);
|
||||
int ble_user_property_get_data_by_id(uint8_t id, char *buf, uint16_t buf_len);
|
||||
int ble_user_property_report_reply_handle(uint8_t result);
|
||||
int ble_lldata_parse_tlv(const char *buf, int buf_len, e_ble_tlv *tlv);
|
||||
int ble_user_property_struct_handle(const char *in_buf, uint16_t buf_len, ble_property_t *struct_arr, uint8_t arr_size);
|
||||
int ble_user_property_struct_get_data(char *in_buf, uint16_t buf_len, ble_property_t *struct_arr, uint8_t arr_size);
|
||||
void ll_sync_led_switch(void);
|
||||
void ll_sync_unbind(void);
|
||||
void llsync_device_state_sync(void);
|
||||
#endif
|
||||
|
||||
// event module
|
||||
#ifdef BLE_QIOT_INCLUDE_EVENT
|
||||
int ble_event_get_id_array_size(uint8_t event_id);
|
||||
uint8_t ble_event_get_param_id_type(uint8_t event_id, uint8_t param_id);
|
||||
int ble_event_get_data_by_id(uint8_t event_id, uint8_t param_id, char *out_buf, uint16_t buf_len);
|
||||
int ble_user_event_reply_handle(uint8_t event_id, uint8_t result);
|
||||
#endif
|
||||
|
||||
// action module
|
||||
#ifdef BLE_QIOT_INCLUDE_ACTION
|
||||
uint8_t ble_action_get_intput_type_by_id(uint8_t action_id, uint8_t input_id);
|
||||
uint8_t ble_action_get_output_type_by_id(uint8_t action_id, uint8_t output_id);
|
||||
int ble_action_get_input_id_size(uint8_t action_id);
|
||||
int ble_action_get_output_id_size(uint8_t action_id);
|
||||
int ble_action_user_handle_input_param(uint8_t action_id, e_ble_tlv *input_param_array, uint8_t input_array_size,
|
||||
uint8_t *output_id_array);
|
||||
int ble_action_user_handle_output_param(uint8_t action_id, uint8_t output_id, char *buf, uint16_t buf_len);
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif //BLE_QIOT_TEMPLATE_H_
|
||||
@ -0,0 +1,36 @@
|
||||
/*
|
||||
* Tencent is pleased to support the open source community by making IoT Hub available.
|
||||
* Copyright (C) 2018-2020 THL A29 Limited, a Tencent company. All rights reserved.
|
||||
|
||||
* Licensed under the MIT License (the "License"); you may not use this file except in
|
||||
* compliance with the License. You may obtain a copy of the License at
|
||||
* http://opensource.org/licenses/MIT
|
||||
|
||||
* 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 QCLOUD_BLE_IOT_UTILS_BASE64_H_
|
||||
#define QCLOUD_BLE_IOT_UTILS_BASE64_H_
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdint.h>
|
||||
#include "ble_qiot_export.h"
|
||||
|
||||
ble_qiot_ret_status_t qcloud_iot_utils_base64encode(unsigned char *dst, size_t dlen, size_t *olen,
|
||||
const unsigned char *src, size_t slen);
|
||||
|
||||
ble_qiot_ret_status_t qcloud_iot_utils_base64decode(unsigned char *dst, size_t dlen, size_t *olen,
|
||||
const unsigned char *src, size_t slen);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif /* QCLOUD_BLE_IOT_UTILS_BASE64_H_ */
|
||||
1341
apps/common/third_party_profile/Tecent_LL/tecent_ll_demo/ll_demo.c
Normal file
1341
apps/common/third_party_profile/Tecent_LL/tecent_ll_demo/ll_demo.c
Normal file
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,76 @@
|
||||
// binary representation
|
||||
// attribute size in bytes (16), flags(16), handle (16), uuid (16/128), value(...)
|
||||
|
||||
#ifndef _LL_DEMO_H
|
||||
#define _LL_DEMO_H
|
||||
|
||||
#include <stdint.h>
|
||||
#include "app_config.h"
|
||||
|
||||
#if (TCFG_BLE_DEMO_SELECT == DEF_BLE_DEMO_LL_SYNC)
|
||||
//
|
||||
// gatt profile include file, generated by jieli gatt_inc_generator.exe
|
||||
//
|
||||
|
||||
const uint8_t profile_data[] = {
|
||||
//////////////////////////////////////////////////////
|
||||
//
|
||||
// 0x0001 PRIMARY_SERVICE 1800
|
||||
//
|
||||
//////////////////////////////////////////////////////
|
||||
0x0a, 0x00, 0x02, 0x00, 0x01, 0x00, 0x00, 0x28, 0x00, 0x18,
|
||||
|
||||
/* CHARACTERISTIC, 2a00, READ | DYNAMIC, */
|
||||
// 0x0002 CHARACTERISTIC 2a00 READ | DYNAMIC
|
||||
0x0d, 0x00, 0x02, 0x00, 0x02, 0x00, 0x03, 0x28, 0x02, 0x03, 0x00, 0x00, 0x2a,
|
||||
// 0x0003 VALUE 2a00 READ | DYNAMIC
|
||||
0x08, 0x00, 0x02, 0x01, 0x03, 0x00, 0x00, 0x2a,
|
||||
|
||||
//////////////////////////////////////////////////////
|
||||
//
|
||||
// 0x0004 PRIMARY_SERVICE 0000FFE0-65D0-4E20-B56A-E493541BA4E2
|
||||
//
|
||||
//////////////////////////////////////////////////////
|
||||
0x18, 0x00, 0x02, 0x00, 0x04, 0x00, 0x00, 0x28, 0xe2, 0xa4, 0x1b, 0x54, 0x93, 0xe4, 0x6a, 0xb5, 0x20, 0x4e, 0xd0, 0x65, 0xe0, 0xff, 0x00, 0x00,
|
||||
|
||||
/* CHARACTERISTIC, 0000FFE1-65D0-4E20-B56A-E493541BA4E2, WRITE | DYNAMIC, */
|
||||
// 0x0005 CHARACTERISTIC 0000FFE1-65D0-4E20-B56A-E493541BA4E2 WRITE | DYNAMIC
|
||||
0x1b, 0x00, 0x02, 0x00, 0x05, 0x00, 0x03, 0x28, 0x08, 0x06, 0x00, 0xe2, 0xa4, 0x1b, 0x54, 0x93, 0xe4, 0x6a, 0xb5, 0x20, 0x4e, 0xd0, 0x65, 0xe1, 0xff, 0x00, 0x00,
|
||||
// 0x0006 VALUE 0000FFE1-65D0-4E20-B56A-E493541BA4E2 WRITE | DYNAMIC
|
||||
0x16, 0x00, 0x08, 0x03, 0x06, 0x00, 0xe2, 0xa4, 0x1b, 0x54, 0x93, 0xe4, 0x6a, 0xb5, 0x20, 0x4e, 0xd0, 0x65, 0xe1, 0xff, 0x00, 0x00,
|
||||
|
||||
/* CHARACTERISTIC, 0000FFE2-65D0-4E20-B56A-E493541BA4E2, WRITE | DYNAMIC, */
|
||||
// 0x0007 CHARACTERISTIC 0000FFE2-65D0-4E20-B56A-E493541BA4E2 WRITE | DYNAMIC
|
||||
0x1b, 0x00, 0x02, 0x00, 0x07, 0x00, 0x03, 0x28, 0x08, 0x08, 0x00, 0xe2, 0xa4, 0x1b, 0x54, 0x93, 0xe4, 0x6a, 0xb5, 0x20, 0x4e, 0xd0, 0x65, 0xe2, 0xff, 0x00, 0x00,
|
||||
// 0x0008 VALUE 0000FFE2-65D0-4E20-B56A-E493541BA4E2 WRITE | DYNAMIC
|
||||
0x16, 0x00, 0x08, 0x03, 0x08, 0x00, 0xe2, 0xa4, 0x1b, 0x54, 0x93, 0xe4, 0x6a, 0xb5, 0x20, 0x4e, 0xd0, 0x65, 0xe2, 0xff, 0x00, 0x00,
|
||||
|
||||
/* CHARACTERISTIC, 0000FFE3-65D0-4E20-B56A-E493541BA4E2, NOTIFY, */
|
||||
// 0x0009 CHARACTERISTIC 0000FFE3-65D0-4E20-B56A-E493541BA4E2 NOTIFY
|
||||
0x1b, 0x00, 0x02, 0x00, 0x09, 0x00, 0x03, 0x28, 0x10, 0x0a, 0x00, 0xe2, 0xa4, 0x1b, 0x54, 0x93, 0xe4, 0x6a, 0xb5, 0x20, 0x4e, 0xd0, 0x65, 0xe3, 0xff, 0x00, 0x00,
|
||||
// 0x000a VALUE 0000FFE3-65D0-4E20-B56A-E493541BA4E2 NOTIFY
|
||||
0x16, 0x00, 0x10, 0x02, 0x0a, 0x00, 0xe2, 0xa4, 0x1b, 0x54, 0x93, 0xe4, 0x6a, 0xb5, 0x20, 0x4e, 0xd0, 0x65, 0xe3, 0xff, 0x00, 0x00,
|
||||
// 0x000b CLIENT_CHARACTERISTIC_CONFIGURATION
|
||||
0x0a, 0x00, 0x0a, 0x01, 0x0b, 0x00, 0x02, 0x29, 0x00, 0x00,
|
||||
|
||||
/* CHARACTERISTIC, 0000FFE4-65D0-4E20-B56A-E493541BA4E2, WRITE_WITHOUT_RESPONSE | DYNAMIC, */
|
||||
// 0x000c CHARACTERISTIC 0000FFE4-65D0-4E20-B56A-E493541BA4E2 WRITE_WITHOUT_RESPONSE | DYNAMIC
|
||||
0x1b, 0x00, 0x02, 0x00, 0x0c, 0x00, 0x03, 0x28, 0x04, 0x0d, 0x00, 0xe2, 0xa4, 0x1b, 0x54, 0x93, 0xe4, 0x6a, 0xb5, 0x20, 0x4e, 0xd0, 0x65, 0xe4, 0xff, 0x00, 0x00,
|
||||
// 0x000d VALUE 0000FFE4-65D0-4E20-B56A-E493541BA4E2 WRITE_WITHOUT_RESPONSE | DYNAMIC
|
||||
0x16, 0x00, 0x04, 0x03, 0x0d, 0x00, 0xe2, 0xa4, 0x1b, 0x54, 0x93, 0xe4, 0x6a, 0xb5, 0x20, 0x4e, 0xd0, 0x65, 0xe4, 0xff, 0x00, 0x00,
|
||||
|
||||
// END
|
||||
0x00, 0x00,
|
||||
};
|
||||
//
|
||||
// characteristics <--> handles
|
||||
//
|
||||
#define ATT_CHARACTERISTIC_2a00_01_VALUE_HANDLE 0x0003
|
||||
#define ATT_CHARACTERISTIC_0000FFE1_65D0_4E20_B56A_E493541BA4E2_01_VALUE_HANDLE 0x0006
|
||||
#define ATT_CHARACTERISTIC_0000FFE2_65D0_4E20_B56A_E493541BA4E2_01_VALUE_HANDLE 0x0008
|
||||
#define ATT_CHARACTERISTIC_0000FFE3_65D0_4E20_B56A_E493541BA4E2_01_VALUE_HANDLE 0x000a
|
||||
#define ATT_CHARACTERISTIC_0000FFE3_65D0_4E20_B56A_E493541BA4E2_01_CLIENT_CONFIGURATION_HANDLE 0x000b
|
||||
#define ATT_CHARACTERISTIC_0000FFE4_65D0_4E20_B56A_E493541BA4E2_01_VALUE_HANDLE 0x000d
|
||||
|
||||
#endif
|
||||
#endif
|
||||
@ -0,0 +1,61 @@
|
||||
#include "ll_task.h"
|
||||
#include "os/os_api.h"
|
||||
#include "ble_qiot_config.h"
|
||||
#include "ble_qiot_service.h"
|
||||
#include "ble_qiot_import.h"
|
||||
|
||||
LL_PACKET_CONTROL LL_packet_c;
|
||||
|
||||
#define __this (&LL_packet_c)
|
||||
|
||||
static void tecent_ll_task(void *arg)
|
||||
{
|
||||
LL_PACKET_HEAD_T ll_packet_head;
|
||||
u8 *buffer = NULL;
|
||||
u8 result = 0;
|
||||
while (1) {
|
||||
os_sem_pend(&(__this->ll_sem), 0);
|
||||
if (cbuf_get_data_len(&(__this->cbuf)) > LL_PACKET_HEAD_LEN) {
|
||||
cbuf_read(&(__this->cbuf), &ll_packet_head, LL_PACKET_HEAD_LEN);
|
||||
buffer = malloc(ll_packet_head.len);
|
||||
if (buffer == NULL) {
|
||||
printf("buf malloc err\n");
|
||||
break;
|
||||
}
|
||||
cbuf_read(&(__this->cbuf), buffer, ll_packet_head.len);
|
||||
switch (ll_packet_head.packet_channel) {
|
||||
case LL_DEVICE_INFO_MSG_CH:
|
||||
result = ble_device_info_msg_handle(buffer, ll_packet_head.len);
|
||||
break;
|
||||
case LL_DATA_MSG_CH:
|
||||
result = ble_lldata_msg_handle(buffer, ll_packet_head.len);
|
||||
break;
|
||||
case LL_OTA_MSG_CH:
|
||||
result = ble_ota_msg_handle(buffer, ll_packet_head.len);
|
||||
break;
|
||||
}
|
||||
free(buffer);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int tecent_ll_task_init(void)
|
||||
{
|
||||
os_sem_create(&(__this->ll_sem), 0);
|
||||
u32 malloc_size = (ble_get_user_data_mtu_size() + LL_PACKET_HEAD_LEN) * BLE_QIOT_TOTAL_PACKAGES;
|
||||
__this->tecent_ll_buf = malloc(malloc_size);
|
||||
memset(__this->tecent_ll_buf, 0x0, malloc_size);
|
||||
cbuf_init(&(__this->cbuf), __this->tecent_ll_buf, malloc_size);
|
||||
os_task_create(tecent_ll_task, NULL, 31, 512, 0, "tecent_ll_task");
|
||||
return 0;
|
||||
}
|
||||
|
||||
void tecent_ll_packet_recieve(void *buf, u16 len)
|
||||
{
|
||||
if (cbuf_is_write_able(&(__this->cbuf), len) >= len) {
|
||||
cbuf_write(&(__this->cbuf), buf, len);
|
||||
} else {
|
||||
printf("[L]\n");
|
||||
}
|
||||
os_sem_post(&(__this->ll_sem));
|
||||
}
|
||||
@ -0,0 +1,31 @@
|
||||
#ifndef __LL_TASK_H__
|
||||
#define __LL_TASK_H__
|
||||
|
||||
#include "typedef.h"
|
||||
#include "os/os_api.h"
|
||||
#include "circular_buf.h"
|
||||
|
||||
typedef struct __LL_PACKET_HEAD {
|
||||
u8 packet_channel;
|
||||
u16 len;
|
||||
} LL_PACKET_HEAD_T;
|
||||
|
||||
typedef struct __LL_PACKET_CONTROL {
|
||||
OS_SEM ll_sem;
|
||||
cbuffer_t cbuf;
|
||||
volatile u8 wait;
|
||||
u8 *tecent_ll_buf;
|
||||
} LL_PACKET_CONTROL;
|
||||
|
||||
#define LL_PACKET_HEAD_LEN (sizeof(LL_PACKET_HEAD_T))
|
||||
|
||||
enum {
|
||||
LL_DEVICE_INFO_MSG_CH = 0,
|
||||
LL_DATA_MSG_CH,
|
||||
LL_OTA_MSG_CH,
|
||||
};
|
||||
|
||||
int tecent_ll_task_init(void);
|
||||
void tecent_ll_packet_recieve(void *buf, u16 len);
|
||||
|
||||
#endif //__LL_TASK_H__
|
||||
@ -0,0 +1,224 @@
|
||||
#include "ble_qiot_import.h"
|
||||
/* #include "le/ble_api.h" */
|
||||
#include "vm.h"
|
||||
#include "le_common.h"
|
||||
#include "dual_bank_updata_api.h"
|
||||
|
||||
#define PRODUCT_ID "YSUM4IEDOH"
|
||||
#define DEVICE_NAME "dev001"
|
||||
#define SECRET_KEY "6WNLgmVK4fThhVIgdOBmKQ=="
|
||||
|
||||
#define LOG_TAG "[ble_qiot_import]"
|
||||
#define LOG_ERROR_ENABLE
|
||||
#define LOG_DEBUG_ENABLE
|
||||
#define LOG_INFO_ENABLE
|
||||
/* #define LOG_DUMP_ENABLE */
|
||||
#define LOG_CLI_ENABLE
|
||||
#include "debug.h"
|
||||
|
||||
#define ADV_INTERVAL_MIN (160)
|
||||
|
||||
static u8 scan_rsp_data[ADV_RSP_PACKET_MAX];//max is 31
|
||||
static char d_name[7] = "LLMAIN";
|
||||
static u8 d_name_len = 6; //名字长度,不包含结束符
|
||||
static u8 ble_work_state = 0; //ble 状态变化
|
||||
static u8 adv_ctrl_en; //广播控制
|
||||
static u16 protocol_MTU; //广播控制
|
||||
|
||||
static u8 adv_data_len;
|
||||
static u8 adv_data[ADV_RSP_PACKET_MAX];//max is 31
|
||||
static u8 scan_rsp_data_len;
|
||||
static u8 scan_rsp_data[ADV_RSP_PACKET_MAX];//max is 31
|
||||
|
||||
int ble_get_product_id(char *product_id)
|
||||
{
|
||||
log_info("ble_get_product_id");
|
||||
memcpy(product_id, PRODUCT_ID, strlen(PRODUCT_ID));
|
||||
put_buf(product_id, strlen(product_id));
|
||||
return 0;
|
||||
}
|
||||
|
||||
int ble_get_device_name(char *device_name)
|
||||
{
|
||||
log_info("ble_get_device_name");
|
||||
memcpy(device_name, DEVICE_NAME, strlen(DEVICE_NAME));
|
||||
put_buf(device_name, strlen(device_name));
|
||||
return strlen(device_name);
|
||||
}
|
||||
|
||||
int ble_get_psk(char *psk)
|
||||
{
|
||||
log_info("ble_get_psk");
|
||||
memcpy(psk, SECRET_KEY, strlen(SECRET_KEY));
|
||||
put_buf(psk, strlen(psk));
|
||||
return 0;
|
||||
}
|
||||
|
||||
extern const u8 *ble_get_mac_addr(void);
|
||||
int ble_get_mac(char *mac)
|
||||
{
|
||||
log_info("ble_get_mac");
|
||||
le_controller_get_mac(mac);
|
||||
put_buf(mac, 6);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void (*app_set_adv_data)(u8 *adv_data, u8 adv_len) = NULL;
|
||||
static void (*app_set_rsp_data)(u8 *rsp_data, u8 rsp_len) = NULL;
|
||||
void app_set_adv_data_register(void (*handler)(u8 *adv_data, u8 adv_len))
|
||||
{
|
||||
app_set_adv_data = handler;
|
||||
}
|
||||
void app_set_rsp_data_register(void (*handler)(u8 *rsp_data, u8 rsp_len))
|
||||
{
|
||||
app_set_rsp_data = handler;
|
||||
}
|
||||
|
||||
static int llsync_set_rsp_data(void)
|
||||
{
|
||||
u8 offset = 0;
|
||||
u8 *buf = scan_rsp_data;
|
||||
|
||||
u8 name_len = sizeof(d_name);
|
||||
u8 vaild_len = ADV_RSP_PACKET_MAX - (offset + 2);
|
||||
if (name_len > vaild_len) {
|
||||
name_len = vaild_len;
|
||||
}
|
||||
offset += make_eir_packet_data(&buf[offset], offset, HCI_EIR_DATATYPE_COMPLETE_LOCAL_NAME, (void *)d_name, d_name_len);
|
||||
|
||||
if (offset > ADV_RSP_PACKET_MAX) {
|
||||
printf("***rsp_data overflow!!!!!!\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
//printf("rsp_data(%d):", offset);
|
||||
//printf_buf(buf, offset);
|
||||
scan_rsp_data_len = offset;
|
||||
if (app_set_rsp_data) {
|
||||
app_set_rsp_data(scan_rsp_data, scan_rsp_data_len);
|
||||
}
|
||||
ble_op_set_rsp_data(offset, buf);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int llsync_set_adv_data(adv_info_s *adv)
|
||||
{
|
||||
u8 offset = 0;
|
||||
u8 *buf = adv_data;
|
||||
u8 manufacturer_buf[20];
|
||||
|
||||
memcpy(&manufacturer_buf[0], &adv->manufacturer_info.company_identifier, 2);
|
||||
memcpy(&manufacturer_buf[2], adv->manufacturer_info.adv_data, adv->manufacturer_info.adv_data_len);
|
||||
printf("manufacturer_buf\n");
|
||||
put_buf(manufacturer_buf, adv->manufacturer_info.adv_data_len + 2);
|
||||
|
||||
offset += make_eir_packet_val(&buf[offset], offset, HCI_EIR_DATATYPE_FLAGS, 0x06, 1);
|
||||
offset += make_eir_packet_val(&buf[offset], offset, HCI_EIR_DATATYPE_COMPLETE_16BIT_SERVICE_UUIDS, IOT_BLE_UUID_SERVICE, 2);
|
||||
offset += make_eir_packet_data(&buf[offset], offset, HCI_EIR_DATATYPE_MANUFACTURER_SPECIFIC_DATA, manufacturer_buf, adv->manufacturer_info.adv_data_len + 2);
|
||||
|
||||
if (offset > ADV_RSP_PACKET_MAX) {
|
||||
puts("***adv_data overflow!!!!!!\n");
|
||||
printf("offset = %d, limite is %d\n", offset, ADV_RSP_PACKET_MAX);
|
||||
return -1;
|
||||
}
|
||||
|
||||
//log_info("adv_data(%d):", offset);
|
||||
//log_info_hexdump(buf, offset);
|
||||
adv_data_len = offset;
|
||||
if (app_set_adv_data) {
|
||||
app_set_adv_data(adv_data, adv_data_len);
|
||||
}
|
||||
ble_op_set_adv_data(offset, buf);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void (*llsync_ble_module_enable)(u8 en) = NULL;
|
||||
ble_qiot_ret_status_t ble_advertising_start(adv_info_s *adv)
|
||||
{
|
||||
log_info("ble_advertising_start\n");
|
||||
//log_info_hexdump(adv->manufacturer_info.adv_data, adv->manufacturer_info.adv_data_len);
|
||||
|
||||
llsync_set_adv_data(adv);
|
||||
llsync_set_rsp_data();
|
||||
|
||||
if (llsync_ble_module_enable) {
|
||||
llsync_ble_module_enable(1);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void llsync_ble_module_enable_register(void (*handler)(u8 en))
|
||||
{
|
||||
llsync_ble_module_enable = handler;
|
||||
}
|
||||
|
||||
ble_qiot_ret_status_t ble_advertising_stop(void)
|
||||
{
|
||||
log_info("ble_advertising_stop\n");
|
||||
if (llsync_ble_module_enable) {
|
||||
llsync_ble_module_enable(0);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int (*llsync_send_data)(void *priv, u8 *data, u16 len) = NULL;
|
||||
void llsync_send_data_register(int (*handler)(void *priv, void *buf, u16 len))
|
||||
{
|
||||
llsync_send_data = handler;
|
||||
}
|
||||
|
||||
ble_qiot_ret_status_t ble_send_notify(uint8_t *buf, uint8_t len)
|
||||
{
|
||||
if (llsync_send_data) {
|
||||
llsync_send_data(NULL, buf, len);
|
||||
} else {
|
||||
log_info("llsync_send_data no register");
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint16_t ble_get_user_data_mtu_size(void)
|
||||
{
|
||||
return BLE_QIOT_PACKAGE_LENGTH + 6;
|
||||
}
|
||||
|
||||
uint8_t ble_ota_is_enable(const char *version, u32 file_size, u32 file_crc)
|
||||
{
|
||||
log_info("ota version: %s, enable ota", version);
|
||||
if (dual_bank_passive_update_init(file_crc, file_size, BLE_QIOT_OTA_BUF_SIZE, NULL) == 0) {
|
||||
if (dual_bank_update_allow_check(file_size) == 0) {
|
||||
return BLE_OTA_ENABLE;
|
||||
}
|
||||
}
|
||||
dual_bank_passive_update_exit(NULL);
|
||||
return 0;
|
||||
}
|
||||
|
||||
extern s32 vm_open(u16 index);
|
||||
extern s32 vm_read(vm_hdl hdl, u8 *data_buf, u16 len);
|
||||
extern s32 vm_write(vm_hdl hdl, u8 *data_buf, u16 len);
|
||||
|
||||
int ble_read_flash(uint32_t flash_addr, char *read_buf, uint16_t read_len)
|
||||
{
|
||||
int ret;
|
||||
s32 hdl = vm_open(flash_addr);
|
||||
|
||||
ret = vm_read(hdl, read_buf, read_len);
|
||||
if (ret < 0) {
|
||||
log_info("\n\nread flash error:%d", ret);
|
||||
}
|
||||
return read_len;
|
||||
}
|
||||
|
||||
int ble_write_flash(uint32_t flash_addr, const char *write_buf, uint16_t write_len)
|
||||
{
|
||||
int ret;
|
||||
s32 hdl = vm_open(flash_addr);
|
||||
|
||||
ret = vm_write(hdl, write_buf, write_len);
|
||||
if (ret < 0) {
|
||||
log_info("\n\nwrite flash error:%d", ret);
|
||||
}
|
||||
return write_len;
|
||||
}
|
||||
|
||||
@ -0,0 +1,346 @@
|
||||
/*
|
||||
* Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved.
|
||||
* Licensed under the MIT License (the "License"); you may not use this file except in
|
||||
* compliance with the License. You may obtain a copy of the License at
|
||||
* http://opensource.org/licenses/MIT
|
||||
* 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.
|
||||
*
|
||||
*/
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
//#include <stdbool.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "ble_qiot_config.h"
|
||||
|
||||
#if BLE_QIOT_LLSYNC_STANDARD
|
||||
|
||||
#include "ble_qiot_export.h"
|
||||
#include "ble_qiot_import.h"
|
||||
#include "ble_qiot_common.h"
|
||||
#include "ble_qiot_llsync_event.h"
|
||||
#include "ble_qiot_utils_base64.h"
|
||||
#include "ble_qiot_log.h"
|
||||
#include "ble_qiot_param_check.h"
|
||||
#include "ble_qiot_service.h"
|
||||
#include "ble_qiot_template.h"
|
||||
#include "ble_qiot_llsync_data.h"
|
||||
|
||||
// parse tlv data and return the length parsed
|
||||
int ble_lldata_parse_tlv(const char *buf, int buf_len, e_ble_tlv *tlv)
|
||||
{
|
||||
int ret_len = 0;
|
||||
uint16_t type_len = 0;
|
||||
|
||||
tlv->type = BLE_QIOT_PARSE_TLV_HEAD_TYPE(buf[0]);
|
||||
if (tlv->type >= BLE_QIOT_DATA_TYPE_BUTT) {
|
||||
ble_qiot_log_e("lldata parse invalid type: %d", tlv->type);
|
||||
return -1;
|
||||
}
|
||||
tlv->id = BLE_QIOT_PARSE_TLV_HEAD_ID(buf[0]);
|
||||
ret_len++;
|
||||
|
||||
switch (tlv->type) {
|
||||
case BLE_QIOT_DATA_TYPE_BOOL:
|
||||
tlv->len = sizeof(uint8_t);
|
||||
tlv->val = (char *)buf + ret_len;
|
||||
ret_len += sizeof(uint8_t);
|
||||
break;
|
||||
case BLE_QIOT_DATA_TYPE_ENUM:
|
||||
tlv->len = sizeof(uint16_t);
|
||||
tlv->val = (char *)buf + ret_len;
|
||||
ret_len += sizeof(uint16_t);
|
||||
break;
|
||||
case BLE_QIOT_DATA_TYPE_INT:
|
||||
case BLE_QIOT_DATA_TYPE_FLOAT:
|
||||
case BLE_QIOT_DATA_TYPE_TIME:
|
||||
tlv->len = sizeof(uint32_t);
|
||||
tlv->val = (char *)buf + ret_len;
|
||||
ret_len += sizeof(uint32_t);
|
||||
break;
|
||||
case BLE_QIOT_DATA_TYPE_STRUCT:
|
||||
case BLE_QIOT_DATA_TYPE_STRING:
|
||||
if (buf_len < BLE_QIOT_MIN_STRING_TYPE_LEN) {
|
||||
ble_qiot_log_e("lldata len invalid, type: %d, len: %d", tlv->type, buf_len);
|
||||
return -1;
|
||||
}
|
||||
memcpy(&type_len, &buf[ret_len], sizeof(uint16_t));
|
||||
tlv->len = NTOHS(type_len);
|
||||
ret_len += sizeof(uint16_t);
|
||||
tlv->val = (char *)buf + ret_len;
|
||||
ret_len += tlv->len;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
ble_qiot_log_d("tlv parsed, type: %d, id: %d, len: %d", tlv->type, tlv->id, tlv->len);
|
||||
|
||||
return ret_len;
|
||||
}
|
||||
|
||||
// handle property data, method is control or get status
|
||||
static ble_qiot_ret_status_t ble_lldata_property_data_handle(bool is_request, const char *in_buf, int buf_len)
|
||||
{
|
||||
#ifdef BLE_QIOT_INCLUDE_PROPERTY
|
||||
uint16_t parse_len = 0;
|
||||
int ret_len = 0;
|
||||
e_ble_tlv tlv;
|
||||
int8_t ret = BLE_QIOT_REPLY_SUCCESS;
|
||||
|
||||
ble_qiot_ret_status_t inform_ret = BLE_QIOT_RS_OK;
|
||||
|
||||
ble_qiot_log_d("handle property data");
|
||||
while (parse_len < buf_len) {
|
||||
memset(&tlv, 0, sizeof(e_ble_tlv));
|
||||
ret_len = ble_lldata_parse_tlv(in_buf + parse_len, buf_len - parse_len, &tlv);
|
||||
if (ret_len < 0) {
|
||||
return BLE_QIOT_RS_ERR;
|
||||
}
|
||||
|
||||
parse_len += ret_len;
|
||||
if (parse_len > buf_len) {
|
||||
ble_qiot_log_e("invalid peroperty data, %d(property len) > %d(buf len)", parse_len, buf_len);
|
||||
ret = BLE_QIOT_REPLY_DATA_ERR;
|
||||
break;
|
||||
}
|
||||
|
||||
if (BLE_QIOT_RS_OK != ble_user_property_set_data(&tlv)) {
|
||||
ret = BLE_QIOT_REPLY_FAIL;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (is_request) {
|
||||
return ble_event_notify(BLE_QIOT_EVENT_UP_CONTROL_REPLY, NULL, 0, (const char *)&ret, sizeof(int8_t));
|
||||
} else {
|
||||
return (BLE_QIOT_REPLY_SUCCESS == ret) ? BLE_QIOT_RS_OK : BLE_QIOT_RS_ERR;
|
||||
}
|
||||
#else
|
||||
ble_qiot_log_e("property" BLE_QIOT_NOT_SUPPORT_WARN);
|
||||
return BLE_QIOT_RS_OK;
|
||||
#endif //BLE_QIOT_INCLUDE_PROPERTY
|
||||
}
|
||||
|
||||
#ifdef BLE_QIOT_INCLUDE_PROPERTY
|
||||
// post property
|
||||
ble_qiot_ret_status_t ble_user_property_get_report_data(void)
|
||||
{
|
||||
uint8_t property_id = 0;
|
||||
uint8_t property_type = 0;
|
||||
int property_len = 0;
|
||||
uint16_t type_len = 0;
|
||||
uint16_t data_len = 0;
|
||||
uint16_t data_buf_off = 0;
|
||||
|
||||
uint8_t data_buf[BLE_QIOT_EVENT_MAX_SIZE] = {0};
|
||||
|
||||
ble_qiot_log_d("report property");
|
||||
for (property_id = 0; property_id < BLE_QIOT_PROPERTY_ID_BUTT; property_id++) {
|
||||
property_type = ble_get_property_type_by_id(property_id);
|
||||
if (property_type >= BLE_QIOT_DATA_TYPE_BUTT) {
|
||||
ble_qiot_log_e("property(%d) type(%d) invalid", property_id, property_type);
|
||||
return BLE_QIOT_RS_ERR;
|
||||
}
|
||||
|
||||
data_buf[data_len++] = BLE_QIOT_PACKAGE_TLV_HEAD(property_type, property_id);
|
||||
data_buf_off = data_len;
|
||||
if ((BLE_QIOT_DATA_TYPE_STRING == property_type) || (BLE_QIOT_DATA_TYPE_STRUCT == property_type)) {
|
||||
// reserved 2 bytes for string/struct length
|
||||
data_buf_off += BLE_QIOT_STRING_TYPE_LEN;
|
||||
}
|
||||
property_len = ble_user_property_get_data_by_id(property_id, (char *)&data_buf[data_buf_off],
|
||||
sizeof(data_buf) - data_buf_off);
|
||||
if (property_len < 0) {
|
||||
return BLE_QIOT_RS_ERR;
|
||||
} else if (property_len == 0) {
|
||||
// clean the property head cause no data to post
|
||||
data_len--;
|
||||
data_buf[data_len] = '0';
|
||||
ble_qiot_log_d("property: %d no data to post", property_id);
|
||||
} else {
|
||||
if ((BLE_QIOT_DATA_TYPE_STRING == property_type) || (BLE_QIOT_DATA_TYPE_STRUCT == property_type)) {
|
||||
// filling the payload length
|
||||
type_len = HTONS(property_len);
|
||||
memcpy(data_buf + data_len, &type_len, sizeof(uint16_t));
|
||||
data_len += sizeof(uint16_t);
|
||||
}
|
||||
data_len += property_len;
|
||||
}
|
||||
}
|
||||
// ble_qiot_log_hex(BLE_QIOT_LOG_LEVEL_INFO, "user data", data_buf, data_len);
|
||||
|
||||
return ble_event_notify(BLE_QIOT_EVENT_UP_PROPERTY_REPORT, NULL, 0, (const char *)data_buf, data_len);
|
||||
}
|
||||
#endif //BLE_QIOT_INCLUDE_PROPERTY
|
||||
|
||||
// handle control
|
||||
ble_qiot_ret_status_t ble_lldata_property_request_handle(const char *in_buf, int buf_len)
|
||||
{
|
||||
return ble_lldata_property_data_handle(true, in_buf, buf_len);
|
||||
}
|
||||
|
||||
// handle report_reply
|
||||
static ble_qiot_ret_status_t ble_lldata_property_report_reply(const char *in_buf, int buf_len)
|
||||
{
|
||||
#ifdef BLE_QIOT_INCLUDE_PROPERTY
|
||||
(void)ble_user_property_report_reply_handle(in_buf[0]);
|
||||
#else
|
||||
ble_qiot_log_e("property" BLE_QIOT_NOT_SUPPORT_WARN);
|
||||
#endif //BLE_QIOT_INCLUDE_PROPERTY
|
||||
return BLE_QIOT_RS_OK;
|
||||
}
|
||||
|
||||
// handle get_status_reply
|
||||
static ble_qiot_ret_status_t ble_lldata_property_get_status_reply(const char *in_buf, int buf_len)
|
||||
{
|
||||
#ifdef BLE_QIOT_INCLUDE_PROPERTY
|
||||
uint8_t result = 0;
|
||||
uint16_t reply_len = 0;
|
||||
|
||||
result = in_buf[0];
|
||||
ble_qiot_log_d("get status reply result: %d", result);
|
||||
if (BLE_QIOT_REPLY_SUCCESS == result) {
|
||||
memcpy(&reply_len, &in_buf[1], sizeof(uint16_t));
|
||||
return ble_lldata_property_data_handle(false, in_buf + sizeof(uint8_t) + sizeof(uint16_t), NTOHS(reply_len));
|
||||
} else {
|
||||
return BLE_QIOT_RS_ERR;
|
||||
}
|
||||
#else
|
||||
ble_qiot_log_e("property" BLE_QIOT_NOT_SUPPORT_WARN);
|
||||
return BLE_QIOT_RS_OK;
|
||||
#endif //BLE_QIOT_INCLUDE_PROPERTY
|
||||
}
|
||||
|
||||
// handle reply from remote
|
||||
ble_qiot_ret_status_t ble_lldata_property_reply_handle(uint8_t type, const char *in_buf, int buf_len)
|
||||
{
|
||||
switch (type) {
|
||||
case BLE_QIOT_DATA_DOWN_REPORT_REPLY:
|
||||
return ble_lldata_property_report_reply(in_buf, buf_len);
|
||||
case BLE_QIOT_DATA_DOWN_GET_STATUS_REPLY:
|
||||
return ble_lldata_property_get_status_reply(in_buf, buf_len);
|
||||
default:
|
||||
ble_qiot_log_e("invalid property reply type");
|
||||
return BLE_QIOT_RS_ERR;
|
||||
}
|
||||
}
|
||||
|
||||
// handle event_post_reply
|
||||
ble_qiot_ret_status_t ble_lldata_event_handle(uint8_t id, const char *in_buf, int len)
|
||||
{
|
||||
#ifdef BLE_QIOT_INCLUDE_EVENT
|
||||
(void)ble_user_event_reply_handle(id, in_buf[0]);
|
||||
#else
|
||||
ble_qiot_log_e("event" BLE_QIOT_NOT_SUPPORT_WARN);
|
||||
#endif //BLE_QIOT_INCLUDE_PROPERTY
|
||||
return BLE_QIOT_RS_OK;
|
||||
}
|
||||
|
||||
// handle action
|
||||
ble_qiot_ret_status_t ble_lldata_action_handle(uint8_t action_id, const char *in_buf, int len)
|
||||
{
|
||||
#ifdef BLE_QIOT_INCLUDE_ACTION
|
||||
POINTER_SANITY_CHECK(in_buf, BLE_QIOT_RS_ERR_PARA);
|
||||
|
||||
uint16_t parse_len = 0;
|
||||
uint8_t tlv_index = 0;
|
||||
int ret_len = 0;
|
||||
int handle_ret = BLE_QIOT_REPLY_SUCCESS;
|
||||
uint8_t output_id = 0;
|
||||
uint8_t output_type = 0;
|
||||
uint16_t data_len = 0;
|
||||
uint16_t data_buf_off = 0;
|
||||
int output_param_len = 0;
|
||||
uint16_t string_len = 0;
|
||||
uint8_t header_buf[2] = {0};
|
||||
|
||||
e_ble_tlv tlv[BLE_QIOT_ACTION_INPUT_ID_BUTT] = {0};
|
||||
uint8_t output_flag_array[BLE_QIOT_ACTION_OUTPUT_ID_BUTT] = {0}; // set true if the id have output
|
||||
uint8_t data_buf[BLE_QIOT_EVENT_MAX_SIZE] = {0};
|
||||
|
||||
header_buf[0] = BLE_QIOT_REPLY_SUCCESS;
|
||||
header_buf[1] = action_id;
|
||||
|
||||
ble_qiot_log_d("input action: %d", action_id);
|
||||
while (parse_len < len) {
|
||||
if (tlv_index >= BLE_QIOT_ACTION_INPUT_ID_BUTT) {
|
||||
ble_qiot_log_e("invalid action(id: %d) data", action_id);
|
||||
handle_ret = BLE_QIOT_REPLY_DATA_ERR;
|
||||
goto end;
|
||||
}
|
||||
ret_len = ble_lldata_parse_tlv(in_buf + parse_len, len - parse_len, &tlv[tlv_index]);
|
||||
if (ret_len < 0) {
|
||||
handle_ret = BLE_QIOT_REPLY_DATA_ERR;
|
||||
goto end;
|
||||
}
|
||||
parse_len += ret_len;
|
||||
tlv_index++;
|
||||
if (parse_len > len) {
|
||||
ble_qiot_log_e("action data parse failed, parse len: %d > data len: %d", parse_len, len);
|
||||
handle_ret = BLE_QIOT_REPLY_DATA_ERR;
|
||||
goto end;
|
||||
}
|
||||
}
|
||||
if (0 != ble_action_user_handle_input_param(action_id, tlv, tlv_index, output_flag_array)) {
|
||||
handle_ret = BLE_QIOT_REPLY_FAIL;
|
||||
goto end;
|
||||
}
|
||||
|
||||
for (output_id = 0; output_id < BLE_QIOT_ACTION_OUTPUT_ID_BUTT; output_id++) {
|
||||
if (output_flag_array[output_id]) {
|
||||
output_type = ble_action_get_output_type_by_id(action_id, output_id);
|
||||
if (output_type >= BLE_QIOT_DATA_TYPE_BUTT) {
|
||||
ble_qiot_log_e("action id(%d:%d) type invalid", action_id, output_id);
|
||||
handle_ret = BLE_QIOT_REPLY_FAIL;
|
||||
goto end;
|
||||
}
|
||||
data_buf[data_len++] = BLE_QIOT_PACKAGE_TLV_HEAD(output_type, output_id);
|
||||
data_buf_off = data_len;
|
||||
if (BLE_QIOT_DATA_TYPE_STRING == output_type) {
|
||||
data_buf_off += BLE_QIOT_STRING_TYPE_LEN;
|
||||
}
|
||||
output_param_len = ble_action_user_handle_output_param(
|
||||
action_id, output_id, (char *)data_buf + data_buf_off, sizeof(data_buf) - data_buf_off);
|
||||
if (output_param_len < 0) {
|
||||
handle_ret = BLE_QIOT_REPLY_FAIL;
|
||||
goto end;
|
||||
} else if (output_param_len == 0) {
|
||||
// clean the head cause no data to post
|
||||
data_len--;
|
||||
data_buf[data_len] = '0';
|
||||
ble_qiot_log_d("action id(%d: %d) no data to post", action_id, output_id);
|
||||
} else {
|
||||
if (BLE_QIOT_DATA_TYPE_STRING == output_type) {
|
||||
string_len = HTONS(output_param_len);
|
||||
memcpy(data_buf + data_len, &string_len, sizeof(uint16_t));
|
||||
data_len += sizeof(uint16_t);
|
||||
}
|
||||
data_len += output_param_len;
|
||||
}
|
||||
}
|
||||
}
|
||||
// ble_qiot_log_hex(BLE_QIOT_LOG_LEVEL_INFO, "user data", data_buf, data_len);
|
||||
return ble_event_notify(BLE_QIOT_EVENT_UP_ACTION_REPLY, header_buf, sizeof(header_buf), (const char *)data_buf,
|
||||
data_len);
|
||||
|
||||
end:
|
||||
header_buf[0] = BLE_QIOT_REPLY_FAIL;
|
||||
ble_event_notify(BLE_QIOT_EVENT_UP_ACTION_REPLY, header_buf, sizeof(header_buf), (const char *)&handle_ret,
|
||||
sizeof(uint8_t));
|
||||
return BLE_QIOT_RS_ERR;
|
||||
#else
|
||||
ble_qiot_log_e("action" BLE_QIOT_NOT_SUPPORT_WARN);
|
||||
return BLE_QIOT_RS_OK;
|
||||
#endif //BLE_QIOT_INCLUDE_PROPERTY
|
||||
}
|
||||
|
||||
#endif //BLE_QIOT_LLSYNC_STANDARD
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
@ -0,0 +1,428 @@
|
||||
/*
|
||||
* Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved.
|
||||
* Licensed under the MIT License (the "License"); you may not use this file except in
|
||||
* compliance with the License. You may obtain a copy of the License at
|
||||
* http://opensource.org/licenses/MIT
|
||||
* 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.
|
||||
*
|
||||
*/
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include "ble_qiot_config.h"
|
||||
|
||||
#include <stdint.h>
|
||||
#include <printf.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "ble_qiot_common.h"
|
||||
#include "ble_qiot_config.h"
|
||||
#include "ble_qiot_export.h"
|
||||
#include "ble_qiot_hmac.h"
|
||||
#include "ble_qiot_import.h"
|
||||
#include "ble_qiot_log.h"
|
||||
#include "ble_qiot_param_check.h"
|
||||
#include "ble_qiot_utils_base64.h"
|
||||
#include "ble_qiot_md5.h"
|
||||
#include "ble_qiot_llsync_device.h"
|
||||
|
||||
#define BLE_GET_EXPIRATION_TIME(_cur_time) ((_cur_time) + BLE_EXPIRATION_TIME)
|
||||
|
||||
static ble_core_data sg_core_data; // ble data storage in flash
|
||||
static ble_device_info sg_device_info; // device info storage in flash
|
||||
static e_llsync_bind_state sg_llsync_bind_state; // llsync bind state in used
|
||||
static e_llsync_connection_state sg_llsync_connection_state; // llsync connection state in used
|
||||
static e_ble_connection_state sg_ble_connection_state; // ble connection state in used
|
||||
static uint16_t sg_llsync_mtu; // the mtu for llsync slice data
|
||||
|
||||
uint16_t llsync_mtu_get(void)
|
||||
{
|
||||
// return default mtu if llsync mtu not set
|
||||
if (0 == sg_llsync_mtu) {
|
||||
sg_llsync_mtu = ATT_MTU_TO_LLSYNC_MTU(ATT_DEFAULT_MTU);
|
||||
}
|
||||
return sg_llsync_mtu;
|
||||
}
|
||||
|
||||
void llsync_mtu_update(uint16_t llsync_mtu)
|
||||
{
|
||||
sg_llsync_mtu = llsync_mtu;
|
||||
}
|
||||
|
||||
void llsync_bind_state_set(e_llsync_bind_state new_state)
|
||||
{
|
||||
ble_qiot_log_d("bind state: %d ---> %d", sg_llsync_bind_state, new_state);
|
||||
sg_llsync_bind_state = new_state;
|
||||
}
|
||||
|
||||
e_llsync_bind_state llsync_bind_state_get(void)
|
||||
{
|
||||
return sg_llsync_bind_state;
|
||||
}
|
||||
|
||||
void llsync_connection_state_set(e_llsync_connection_state new_state)
|
||||
{
|
||||
ble_qiot_log_d("llsync state: %d ---> %d", sg_llsync_connection_state, new_state);
|
||||
sg_llsync_connection_state = new_state;
|
||||
}
|
||||
|
||||
bool llsync_is_connected(void)
|
||||
{
|
||||
return sg_llsync_connection_state == E_LLSYNC_CONNECTED;
|
||||
}
|
||||
|
||||
void ble_connection_state_set(e_ble_connection_state new_state)
|
||||
{
|
||||
ble_qiot_log_d("ble state: %d ---> %d", sg_llsync_connection_state, new_state);
|
||||
sg_ble_connection_state = new_state;
|
||||
}
|
||||
|
||||
bool ble_is_connected(void)
|
||||
{
|
||||
return sg_ble_connection_state == E_BLE_CONNECTED;
|
||||
}
|
||||
|
||||
// [1byte bind state] + [6 bytes mac] + [8bytes identify string]/[10 bytes product id]
|
||||
int ble_get_my_broadcast_data(char *out_buf, int buf_len)
|
||||
{
|
||||
POINTER_SANITY_CHECK(out_buf, BLE_QIOT_RS_ERR_PARA);
|
||||
BUFF_LEN_SANITY_CHECK(buf_len, BLE_BIND_IDENTIFY_STR_LEN + BLE_QIOT_MAC_LEN + 1, BLE_QIOT_RS_ERR_PARA);
|
||||
int ret_len = 0;
|
||||
#if BLE_QIOT_LLSYNC_STANDARD
|
||||
int i = 0;
|
||||
uint8_t md5_in_buf[128] = {0};
|
||||
uint8_t md5_in_len = 0;
|
||||
uint8_t md5_out_buf[MD5_DIGEST_SIZE] = {0};
|
||||
|
||||
out_buf[ret_len++] = llsync_bind_state_get() | (BLE_QIOT_LLSYNC_PROTOCOL_VERSION << LLSYNC_PROTO_VER_BIT);
|
||||
if (E_LLSYNC_BIND_SUCC == llsync_bind_state_get()) {
|
||||
// 1 bytes state + 8 bytes device identify_str + 8 bytes identify_str
|
||||
memcpy((char *)md5_in_buf, sg_device_info.product_id, sizeof(sg_device_info.product_id));
|
||||
md5_in_len += sizeof(sg_device_info.product_id);
|
||||
memcpy((char *)md5_in_buf + md5_in_len, sg_device_info.device_name, strlen(sg_device_info.device_name));
|
||||
md5_in_len += strlen(sg_device_info.device_name);
|
||||
utils_md5(md5_in_buf, md5_in_len, md5_out_buf);
|
||||
for (i = 0; i < MD5_DIGEST_SIZE / 2; i++) {
|
||||
out_buf[i + ret_len] = md5_out_buf[i] ^ md5_out_buf[i + MD5_DIGEST_SIZE / 2];
|
||||
}
|
||||
ret_len += MD5_DIGEST_SIZE / 2;
|
||||
memcpy(out_buf + ret_len, sg_core_data.identify_str, sizeof(sg_core_data.identify_str));
|
||||
ret_len += sizeof(sg_core_data.identify_str);
|
||||
} else
|
||||
#endif //BLE_QIOT_LLSYNC_STANDARD
|
||||
{
|
||||
#if BLE_QIOT_LLSYNC_CONFIG_NET
|
||||
out_buf[ret_len++] = BLE_QIOT_LLSYNC_PROTOCOL_VERSION;
|
||||
#endif // BLE_QIOT_LLSYNC_CONFIG_NET
|
||||
// 1 bytes state + 6 bytes mac + 10 bytes product id
|
||||
memcpy(out_buf + ret_len, sg_device_info.mac, BLE_QIOT_MAC_LEN);
|
||||
ret_len += BLE_QIOT_MAC_LEN;
|
||||
memcpy(out_buf + ret_len, sg_device_info.product_id, sizeof(sg_device_info.product_id));
|
||||
ret_len += sizeof(sg_device_info.product_id);
|
||||
}
|
||||
ble_qiot_log_hex(BLE_QIOT_LOG_LEVEL_INFO, "broadcast", out_buf, ret_len);
|
||||
|
||||
return ret_len;
|
||||
}
|
||||
|
||||
int ble_inform_mtu_result(const char *result, uint16_t data_len)
|
||||
{
|
||||
uint16_t ret = 0;
|
||||
|
||||
memcpy(&ret, result, sizeof(uint16_t));
|
||||
ret = NTOHS(ret);
|
||||
ble_qiot_log_i("mtu setting result: %02x", ret);
|
||||
|
||||
if (LLSYNC_MTU_SET_RESULT_ERR == ret) {
|
||||
return ble_event_sync_mtu(ATT_DEFAULT_MTU);
|
||||
} else if (0 == ret) {
|
||||
return BLE_QIOT_RS_OK;
|
||||
} else {
|
||||
llsync_mtu_update(ATT_MTU_TO_LLSYNC_MTU(ret));
|
||||
return BLE_QIOT_RS_OK;
|
||||
}
|
||||
}
|
||||
|
||||
#if BLE_QIOT_LLSYNC_STANDARD
|
||||
static int memchk(const uint8_t *buf, int len)
|
||||
{
|
||||
int i = 0;
|
||||
|
||||
for (i = 0; i < len; i++) {
|
||||
if (buf[i] != 0xFF) {
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
extern void bt_tws_sync_ll_sync_state();
|
||||
static ble_qiot_ret_status_t ble_write_core_data(ble_core_data *core_data)
|
||||
{
|
||||
memcpy(&sg_core_data, core_data, sizeof(ble_core_data));
|
||||
if (sizeof(ble_core_data) !=
|
||||
ble_write_flash(BLE_QIOT_RECORD_FLASH_ADDR, (char *)&sg_core_data, sizeof(ble_core_data))) {
|
||||
ble_qiot_log_e("llsync write core failed");
|
||||
return BLE_QIOT_RS_ERR_FLASH;
|
||||
}
|
||||
|
||||
#if TCFG_USER_TWS_ENABLE
|
||||
bt_tws_sync_ll_sync_state();
|
||||
#endif
|
||||
|
||||
return BLE_QIOT_RS_OK;
|
||||
}
|
||||
|
||||
int ble_bind_get_authcode(const char *bind_data, uint16_t data_len, char *out_buf, uint16_t buf_len)
|
||||
{
|
||||
POINTER_SANITY_CHECK(bind_data, BLE_QIOT_RS_ERR_PARA);
|
||||
BUFF_LEN_SANITY_CHECK(data_len, (int32_t)sizeof(ble_bind_data), BLE_QIOT_RS_ERR_PARA);
|
||||
POINTER_SANITY_CHECK(out_buf, BLE_QIOT_RS_ERR_PARA);
|
||||
BUFF_LEN_SANITY_CHECK(buf_len, SHA1_DIGEST_SIZE + BLE_QIOT_DEVICE_NAME_LEN, BLE_QIOT_RS_ERR_PARA);
|
||||
|
||||
char out_sign[SHA1_DIGEST_SIZE] = {0};
|
||||
char sign_info[80] = {0};
|
||||
int sign_info_len = 0;
|
||||
int time_expiration = 0;
|
||||
int nonce = 0;
|
||||
int ret_len = 0;
|
||||
uint8_t secret[BLE_QIOT_PSK_LEN / 4 * 3] = {0};
|
||||
int secret_len = 0;
|
||||
|
||||
// if the pointer "char *bind_data" is not aligned with 4 byte, in some cpu convert it to
|
||||
// pointer "ble_bind_data *" work correctly, but some cpu will get wrong value, or cause
|
||||
// other "Unexpected Error". Here copy it to a local variable make sure aligned with 4 byte.
|
||||
ble_bind_data bind_data_aligned;
|
||||
memcpy(&bind_data_aligned, bind_data, sizeof(ble_bind_data));
|
||||
|
||||
nonce = NTOHL(bind_data_aligned.nonce);
|
||||
time_expiration = BLE_GET_EXPIRATION_TIME(NTOHL(bind_data_aligned.timestamp));
|
||||
|
||||
// [10 bytes product_id] + [x bytes device name] + ';' + [4 bytes nonce] + ';' + [4 bytes timestamp]
|
||||
memcpy(sign_info, sg_device_info.product_id, sizeof(sg_device_info.product_id));
|
||||
sign_info_len += sizeof(sg_device_info.product_id);
|
||||
memcpy(sign_info + sign_info_len, sg_device_info.device_name, strlen(sg_device_info.device_name));
|
||||
sign_info_len += strlen(sg_device_info.device_name);
|
||||
snprintf(sign_info + sign_info_len, sizeof(sign_info) - sign_info_len, ";%u", nonce);
|
||||
sign_info_len += strlen(sign_info + sign_info_len);
|
||||
snprintf(sign_info + sign_info_len, sizeof(sign_info) - sign_info_len, ";%u", time_expiration);
|
||||
sign_info_len += strlen(sign_info + sign_info_len);
|
||||
|
||||
qcloud_iot_utils_base64decode(secret, sizeof(secret), (size_t *)&secret_len,
|
||||
(const unsigned char *)sg_device_info.psk, sizeof(sg_device_info.psk));
|
||||
ble_qiot_log_hex(BLE_QIOT_LOG_LEVEL_INFO, "bind sign in", sign_info, sign_info_len);
|
||||
utils_hmac_sha1((const char *)sign_info, sign_info_len, out_sign, (const char *)secret, secret_len);
|
||||
ble_qiot_log_hex(BLE_QIOT_LOG_LEVEL_INFO, "bind sign out", out_sign, sizeof(out_sign));
|
||||
|
||||
// return [20 bytes sign] + [x bytes device_name]
|
||||
memset(out_buf, 0, buf_len);
|
||||
memcpy(out_buf, out_sign, SHA1_DIGEST_SIZE);
|
||||
ret_len = SHA1_DIGEST_SIZE;
|
||||
|
||||
memcpy(out_buf + ret_len, sg_device_info.device_name, strlen(sg_device_info.device_name));
|
||||
ret_len += strlen(sg_device_info.device_name);
|
||||
ble_qiot_log_hex(BLE_QIOT_LOG_LEVEL_INFO, "bind auth code", out_buf, ret_len);
|
||||
|
||||
return ret_len;
|
||||
}
|
||||
|
||||
ble_qiot_ret_status_t ble_bind_write_result(const char *result, uint16_t len)
|
||||
{
|
||||
POINTER_SANITY_CHECK(result, BLE_QIOT_RS_ERR_PARA);
|
||||
BUFF_LEN_SANITY_CHECK(len, (int32_t)sizeof(ble_core_data), BLE_QIOT_RS_ERR_PARA);
|
||||
|
||||
ble_core_data *bind_result = (ble_core_data *)result;
|
||||
|
||||
llsync_bind_state_set((e_llsync_bind_state)bind_result->bind_state);
|
||||
return ble_write_core_data(bind_result);
|
||||
}
|
||||
|
||||
ble_qiot_ret_status_t ble_unbind_write_result(void)
|
||||
{
|
||||
ble_core_data bind_result;
|
||||
|
||||
llsync_connection_state_set(E_LLSYNC_DISCONNECTED);
|
||||
llsync_bind_state_set(E_LLSYNC_BIND_IDLE);
|
||||
memset(&bind_result, 0, sizeof(bind_result));
|
||||
return ble_write_core_data(&bind_result);
|
||||
}
|
||||
|
||||
int ble_conn_get_authcode(const char *conn_data, uint16_t data_len, char *out_buf, uint16_t buf_len)
|
||||
{
|
||||
POINTER_SANITY_CHECK(conn_data, BLE_QIOT_RS_ERR_PARA);
|
||||
BUFF_LEN_SANITY_CHECK(data_len, (int32_t)sizeof(ble_conn_data), BLE_QIOT_RS_ERR_PARA);
|
||||
POINTER_SANITY_CHECK(out_buf, BLE_QIOT_RS_ERR_PARA);
|
||||
BUFF_LEN_SANITY_CHECK(buf_len, SHA1_DIGEST_SIZE + BLE_QIOT_DEVICE_NAME_LEN, BLE_QIOT_RS_ERR_PARA);
|
||||
|
||||
char sign_info[64] = {0};
|
||||
char out_sign[SHA1_DIGEST_SIZE] = {0};
|
||||
int sign_info_len = 0;
|
||||
int timestamp = 0;
|
||||
int ret_len = 0;
|
||||
|
||||
// if the pointer "char *bind_data" is not aligned with 4 byte, in some cpu convert it to
|
||||
// pointer "ble_bind_data *" work correctly, but some cpu will get wrong value, or cause
|
||||
// other "Unexpected Error". Here copy it to a local variable make sure aligned with 4 byte.
|
||||
ble_conn_data conn_data_aligned;
|
||||
memcpy(&conn_data_aligned, conn_data, sizeof(ble_conn_data));
|
||||
|
||||
// valid sign
|
||||
timestamp = NTOHL(conn_data_aligned.timestamp);
|
||||
snprintf(sign_info + sign_info_len, sizeof(sign_info) - sign_info_len, "%d", timestamp);
|
||||
sign_info_len = strlen(sign_info + sign_info_len);
|
||||
ble_qiot_log_hex(BLE_QIOT_LOG_LEVEL_INFO, "valid sign in", sign_info, sign_info_len);
|
||||
utils_hmac_sha1(sign_info, sign_info_len, out_sign, sg_core_data.local_psk, sizeof(sg_core_data.local_psk));
|
||||
ble_qiot_log_hex(BLE_QIOT_LOG_LEVEL_INFO, "valid sign out", out_sign, SHA1_DIGEST_SIZE);
|
||||
if (0 != memcmp(&conn_data_aligned.sign_info, out_sign, SHA1_DIGEST_SIZE)) {
|
||||
ble_qiot_log_e("llsync invalid connect sign");
|
||||
return BLE_QIOT_RS_VALID_SIGN_ERR;
|
||||
}
|
||||
|
||||
// calc sign
|
||||
memset(sign_info, 0, sizeof(sign_info));
|
||||
sign_info_len = 0;
|
||||
|
||||
// expiration time + product id + device name
|
||||
timestamp = BLE_GET_EXPIRATION_TIME(NTOHL(conn_data_aligned.timestamp));
|
||||
snprintf(sign_info + sign_info_len, sizeof(sign_info) - sign_info_len, "%d", timestamp);
|
||||
sign_info_len += strlen(sign_info + sign_info_len);
|
||||
memcpy(sign_info + sign_info_len, sg_device_info.product_id, sizeof(sg_device_info.product_id));
|
||||
sign_info_len += sizeof(sg_device_info.product_id);
|
||||
memcpy(sign_info + sign_info_len, sg_device_info.device_name, strlen(sg_device_info.device_name));
|
||||
sign_info_len += strlen(sg_device_info.device_name);
|
||||
|
||||
ble_qiot_log_hex(BLE_QIOT_LOG_LEVEL_INFO, "conn sign in", sign_info, sign_info_len);
|
||||
utils_hmac_sha1(sign_info, sign_info_len, out_sign, sg_core_data.local_psk, sizeof(sg_core_data.local_psk));
|
||||
ble_qiot_log_hex(BLE_QIOT_LOG_LEVEL_INFO, "conn sign out", out_sign, sizeof(out_sign));
|
||||
|
||||
// return authcode
|
||||
memset(out_buf, 0, buf_len);
|
||||
memcpy(out_buf, out_sign, SHA1_DIGEST_SIZE);
|
||||
ret_len += SHA1_DIGEST_SIZE;
|
||||
memcpy(out_buf + ret_len, sg_device_info.device_name, strlen(sg_device_info.device_name));
|
||||
ret_len += strlen(sg_device_info.device_name);
|
||||
ble_qiot_log_hex(BLE_QIOT_LOG_LEVEL_INFO, "conn auth code", out_buf, ret_len);
|
||||
|
||||
return ret_len;
|
||||
}
|
||||
|
||||
int ble_unbind_get_authcode(const char *unbind_data, uint16_t data_len, char *out_buf, uint16_t buf_len)
|
||||
{
|
||||
POINTER_SANITY_CHECK(unbind_data, BLE_QIOT_RS_ERR_PARA);
|
||||
BUFF_LEN_SANITY_CHECK(data_len, (int32_t)sizeof(ble_unbind_data), BLE_QIOT_RS_ERR_PARA);
|
||||
POINTER_SANITY_CHECK(out_buf, BLE_QIOT_RS_ERR_PARA);
|
||||
BUFF_LEN_SANITY_CHECK(buf_len, SHA1_DIGEST_SIZE, BLE_QIOT_RS_ERR_PARA);
|
||||
|
||||
char sign_info[32] = {0};
|
||||
char out_sign[SHA1_DIGEST_SIZE] = {0};
|
||||
int sign_info_len = 0;
|
||||
int ret_len = 0;
|
||||
|
||||
// valid sign
|
||||
memcpy(sign_info, BLE_UNBIND_REQUEST_STR, BLE_UNBIND_REQUEST_STR_LEN);
|
||||
sign_info_len = BLE_UNBIND_REQUEST_STR_LEN;
|
||||
utils_hmac_sha1(sign_info, sign_info_len, out_sign, sg_core_data.local_psk, sizeof(sg_core_data.local_psk));
|
||||
ble_qiot_log_hex(BLE_QIOT_LOG_LEVEL_INFO, "valid sign out", out_sign, SHA1_DIGEST_SIZE);
|
||||
|
||||
if (0 != memcmp(((ble_unbind_data *)unbind_data)->sign_info, out_sign, SHA1_DIGEST_SIZE)) {
|
||||
ble_qiot_log_e("llsync invalid unbind sign");
|
||||
return BLE_QIOT_RS_VALID_SIGN_ERR;
|
||||
}
|
||||
|
||||
// calc sign
|
||||
memset(sign_info, 0, sizeof(sign_info));
|
||||
sign_info_len = 0;
|
||||
|
||||
memcpy(sign_info, BLE_UNBIND_RESPONSE, strlen(BLE_UNBIND_RESPONSE));
|
||||
sign_info_len += BLE_UNBIND_RESPONSE_STR_LEN;
|
||||
utils_hmac_sha1(sign_info, sign_info_len, out_sign, sg_core_data.local_psk, sizeof(sg_core_data.local_psk));
|
||||
ble_qiot_log_hex(BLE_QIOT_LOG_LEVEL_INFO, "unbind auth code", out_sign, SHA1_DIGEST_SIZE);
|
||||
|
||||
memset(out_buf, 0, buf_len);
|
||||
memcpy(out_buf, out_sign, sizeof(out_sign));
|
||||
ret_len += sizeof(out_sign);
|
||||
|
||||
return ret_len;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
ble_qiot_ret_status_t ble_init_flash_data(void)
|
||||
{
|
||||
#if BLE_QIOT_LLSYNC_STANDARD
|
||||
if (sizeof(sg_core_data) !=
|
||||
ble_read_flash(BLE_QIOT_RECORD_FLASH_ADDR, (char *)&sg_core_data, sizeof(sg_core_data))) {
|
||||
ble_qiot_log_e("llsync read flash failed");
|
||||
return BLE_QIOT_RS_ERR_FLASH;
|
||||
}
|
||||
if (0 == memchk((const uint8_t *)&sg_core_data, sizeof(sg_core_data))) {
|
||||
memset(&sg_core_data, 0, sizeof(sg_core_data));
|
||||
}
|
||||
|
||||
if (0 != ble_get_psk(sg_device_info.psk)) {
|
||||
ble_qiot_log_e("llsync get secret key failed");
|
||||
return BLE_QIOT_RS_ERR_FLASH;
|
||||
}
|
||||
#endif //BLE_QIOT_LLSYNC_STANDARD
|
||||
|
||||
if (0 != ble_get_mac(sg_device_info.mac)) {
|
||||
ble_qiot_log_e("llsync get mac failed");
|
||||
return BLE_QIOT_RS_ERR_FLASH;
|
||||
}
|
||||
if (0 != ble_get_product_id(sg_device_info.product_id)) {
|
||||
ble_qiot_log_e("llsync get product id failed");
|
||||
return BLE_QIOT_RS_ERR_FLASH;
|
||||
}
|
||||
if (0 == ble_get_device_name(sg_device_info.device_name)) {
|
||||
ble_qiot_log_e("llsync get device name failed");
|
||||
return BLE_QIOT_RS_ERR_FLASH;
|
||||
}
|
||||
|
||||
#if BLE_QIOT_LLSYNC_STANDARD
|
||||
llsync_bind_state_set((e_llsync_bind_state)sg_core_data.bind_state);
|
||||
// ble_qiot_log_hex(BLE_QIOT_LOG_LEVEL_INFO, "core_data", (char *)&sg_core_data, sizeof(sg_core_data));
|
||||
// ble_qiot_log_hex(BLE_QIOT_LOG_LEVEL_INFO, "device_info", (char *)&sg_device_info, sizeof(sg_device_info));
|
||||
#endif //BLE_QIOT_LLSYNC_STANDARD
|
||||
|
||||
return BLE_QIOT_RS_OK;
|
||||
}
|
||||
|
||||
|
||||
|
||||
void ll_sync_state_deal(void *_data, u16 len)
|
||||
{
|
||||
ble_core_data data;
|
||||
|
||||
memcpy(&data, _data, len);
|
||||
|
||||
if (data.bind_state == E_LLSYNC_BIND_SUCC) {
|
||||
//g_printf("bind ok\n");
|
||||
ble_bind_write_result((u8 *)&data, len);
|
||||
} else if (data.bind_state == E_LLSYNC_BIND_WAIT) {
|
||||
//g_printf("bind wait\n");
|
||||
llsync_bind_state_set(E_LLSYNC_BIND_IDLE);
|
||||
} else {
|
||||
//g_printf("no bind \n");
|
||||
ble_unbind_write_result();
|
||||
}
|
||||
}
|
||||
|
||||
u16 ll_sync_get_core_data(u8 *data)
|
||||
{
|
||||
if (sizeof(ble_core_data) > 20) {
|
||||
ASSERT(0, "DATA ERROR\n");
|
||||
}
|
||||
memcpy(data, &sg_core_data, sizeof(ble_core_data));
|
||||
return sizeof(ble_core_data);
|
||||
}
|
||||
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
@ -0,0 +1,269 @@
|
||||
/*
|
||||
* Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved.
|
||||
* Licensed under the MIT License (the "License"); you may not use this file except in
|
||||
* compliance with the License. You may obtain a copy of the License at
|
||||
* http://opensource.org/licenses/MIT
|
||||
* 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.
|
||||
*
|
||||
*/
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include "ble_qiot_config.h"
|
||||
|
||||
//#include <stdbool.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "ble_qiot_import.h"
|
||||
#include "ble_qiot_common.h"
|
||||
#include "ble_qiot_param_check.h"
|
||||
#include "ble_qiot_service.h"
|
||||
#include "ble_qiot_template.h"
|
||||
#include "ble_qiot_llsync_device.h"
|
||||
#include "ble_qiot_llsync_event.h"
|
||||
|
||||
// report device info
|
||||
ble_qiot_ret_status_t ble_event_report_device_info(void)
|
||||
{
|
||||
char device_info[56] = {0}; // 1 byte llsync proto version + 2 bytes mtu size + 1 byte length of develop version
|
||||
uint16_t mtu_size = 0;
|
||||
|
||||
#if BLE_QIOT_REMOTE_SET_MTU
|
||||
mtu_size = LLSYNC_MTU_SET_MASK;
|
||||
#endif //BLE_QIOT_REMOTE_SET_MTU
|
||||
mtu_size |= ble_get_user_data_mtu_size();
|
||||
mtu_size = HTONS(mtu_size);
|
||||
device_info[0] = BLE_QIOT_LLSYNC_PROTOCOL_VERSION;
|
||||
memcpy(&device_info[1], &mtu_size, sizeof(mtu_size));
|
||||
#if BLE_QIOT_LLSYNC_CONFIG_NET
|
||||
device_info[3] = (char)ble_get_device_name(&device_info[4]);
|
||||
#else
|
||||
device_info[3] = (char)strlen(BLE_QIOT_USER_DEVELOPER_VERSION);
|
||||
memcpy(&device_info[4], BLE_QIOT_USER_DEVELOPER_VERSION, device_info[3]);
|
||||
#endif //BLE_QIOT_LLSYNC_CONFIG_NET
|
||||
return ble_event_notify(BLE_QIOT_EVENT_UP_REPORT_MTU, NULL, 0, device_info, 4 + device_info[3]);
|
||||
}
|
||||
|
||||
// sync mtu
|
||||
ble_qiot_ret_status_t ble_event_sync_mtu(uint16_t att_mtu)
|
||||
{
|
||||
uint16_t mtu_size = 0;
|
||||
|
||||
mtu_size = ATT_MTU_TO_LLSYNC_MTU(att_mtu);
|
||||
llsync_mtu_update(mtu_size);
|
||||
mtu_size = HTONS(mtu_size);
|
||||
return ble_event_notify(BLE_QIOT_EVENT_UP_SYNC_MTU, NULL, 0, (const char *)&mtu_size, sizeof(uint16_t));
|
||||
}
|
||||
|
||||
ble_qiot_ret_status_t ble_event_notify2(uint8_t type, uint8_t length_flag, uint8_t *header, uint8_t header_len,
|
||||
const char *buf, uint16_t buf_len)
|
||||
{
|
||||
char *p = (char *)buf;
|
||||
uint16_t left_len = buf_len;
|
||||
uint16_t send_len = 0;
|
||||
uint16_t mtu_size = 0;
|
||||
uint8_t slice_state = BLE_QIOT_EVENT_NO_SLICE;
|
||||
uint16_t send_buf_index = 0;
|
||||
uint16_t tmp_len = 0;
|
||||
|
||||
uint8_t send_buf[BLE_QIOT_EVENT_BUF_SIZE] = {0};
|
||||
|
||||
if (!llsync_is_connected() && type != BLE_QIOT_EVENT_UP_BIND_SIGN_RET && type != BLE_QIOT_EVENT_UP_CONN_SIGN_RET &&
|
||||
type != BLE_QIOT_EVENT_UP_UNBIND_SIGN_RET && type != BLE_QIOT_EVENT_UP_SYNC_WAIT_TIME) {
|
||||
ble_qiot_log_e("upload msg negate, device not connected");
|
||||
return BLE_QIOT_RS_ERR;
|
||||
}
|
||||
|
||||
// reserve event header length, 3 bytes fixed length + n bytes header
|
||||
mtu_size = llsync_mtu_get();
|
||||
mtu_size = mtu_size > sizeof(send_buf) ? sizeof(send_buf) : mtu_size;
|
||||
mtu_size -= (BLE_QIOT_EVENT_FIXED_HEADER_LEN + header_len);
|
||||
// ble_qiot_log_d("mtu size %d", mtu_size);
|
||||
|
||||
do {
|
||||
memset(send_buf, 0, sizeof(send_buf));
|
||||
send_buf_index = 0;
|
||||
send_len = left_len > mtu_size ? mtu_size : left_len;
|
||||
|
||||
send_buf[send_buf_index++] = type;
|
||||
if (NULL != buf) {
|
||||
tmp_len = HTONS(send_len + header_len);
|
||||
memcpy(send_buf + send_buf_index, &tmp_len, sizeof(uint16_t));
|
||||
send_buf_index += sizeof(uint16_t);
|
||||
if (NULL != header) {
|
||||
memcpy(send_buf + send_buf_index, header, header_len);
|
||||
send_buf_index += header_len;
|
||||
}
|
||||
memcpy(send_buf + send_buf_index, p, send_len);
|
||||
send_buf_index += send_len;
|
||||
|
||||
p += send_len;
|
||||
left_len -= send_len;
|
||||
send_len += (BLE_QIOT_EVENT_FIXED_HEADER_LEN + header_len);
|
||||
|
||||
if (0 == left_len) {
|
||||
slice_state =
|
||||
(BLE_QIOT_EVENT_NO_SLICE == slice_state) ? BLE_QIOT_EVENT_NO_SLICE : BLE_QIOT_EVENT_SLICE_FOOT;
|
||||
} else {
|
||||
slice_state =
|
||||
(BLE_QIOT_EVENT_NO_SLICE == slice_state) ? BLE_QIOT_EVENT_SLICE_HEAD : BLE_QIOT_EVENT_SLICE_BODY;
|
||||
}
|
||||
// the high 2 bits means slice state, and the left 14 bits is data length
|
||||
send_buf[1] |= slice_state << 6;
|
||||
send_buf[1] |= length_flag;
|
||||
} else {
|
||||
send_len = send_buf_index;
|
||||
}
|
||||
|
||||
ble_qiot_log_hex(BLE_QIOT_LOG_LEVEL_INFO, "post data", (char *)send_buf, send_len);
|
||||
if (0 != ble_send_notify(send_buf, send_len)) {
|
||||
ble_qiot_log_e("event(type: %d) post failed, len: %d", type, send_len);
|
||||
return BLE_QIOT_RS_ERR;
|
||||
}
|
||||
} while (left_len != 0);
|
||||
|
||||
return BLE_QIOT_RS_OK;
|
||||
}
|
||||
|
||||
ble_qiot_ret_status_t ble_event_notify(uint8_t type, uint8_t *header, uint8_t header_len, const char *buf,
|
||||
uint16_t buf_len)
|
||||
{
|
||||
return ble_event_notify2(type, 0, header, header_len, buf, buf_len);
|
||||
}
|
||||
|
||||
#if BLE_QIOT_LLSYNC_CONFIG_NET
|
||||
ble_qiot_ret_status_t ble_event_report_wifi_mode(uint8_t result)
|
||||
{
|
||||
return ble_event_notify(BLE_QIOT_EVENT_UP_WIFI_MODE, NULL, 0, (const char *)&result, sizeof(uint8_t));
|
||||
}
|
||||
|
||||
ble_qiot_ret_status_t ble_event_report_wifi_info(uint8_t result)
|
||||
{
|
||||
return ble_event_notify(BLE_QIOT_EVENT_UP_WIFI_INFO, NULL, 0, (const char *)&result, sizeof(uint8_t));
|
||||
}
|
||||
|
||||
ble_qiot_ret_status_t ble_event_report_wifi_connect(BLE_WIFI_MODE mode, BLE_WIFI_STATE state, uint8_t ssid_len,
|
||||
const char *ssid)
|
||||
{
|
||||
char buf[40] = {0};
|
||||
uint8_t pos = 0;
|
||||
|
||||
buf[pos++] = mode;
|
||||
buf[pos++] = state;
|
||||
buf[pos++] = 0;
|
||||
buf[pos++] = ssid_len;
|
||||
memcpy(buf + pos, ssid, ssid_len);
|
||||
|
||||
return ble_event_notify(BLE_QIOT_EVENT_UP_WIFI_CONNECT, NULL, 0, (const char *)buf, pos + ssid_len);
|
||||
}
|
||||
|
||||
ble_qiot_ret_status_t ble_event_report_wifi_token(uint8_t result)
|
||||
{
|
||||
return ble_event_notify(BLE_QIOT_EVENT_UP_WIFI_TOKEN, NULL, 0, (const char *)&result, sizeof(uint8_t));
|
||||
}
|
||||
|
||||
ble_qiot_ret_status_t ble_event_report_wifi_log(const uint8_t *log, uint16_t log_size)
|
||||
{
|
||||
return ble_event_notify(BLE_QIOT_EVENT_UP_WIFI_LOG, NULL, 0, (const char *)log, log_size);
|
||||
}
|
||||
#endif //BLE_QIOT_LLSYNC_CONFIG_NET
|
||||
|
||||
#if BLE_QIOT_LLSYNC_STANDARD
|
||||
// get_status
|
||||
ble_qiot_ret_status_t ble_event_get_status(void)
|
||||
{
|
||||
#ifdef BLE_QIOT_INCLUDE_PROPERTY
|
||||
return ble_event_notify(BLE_QIOT_EVENT_UP_GET_STATUS, NULL, 0, NULL, 0);
|
||||
#else
|
||||
ble_qiot_log_e("property" BLE_QIOT_NOT_SUPPORT_WARN);
|
||||
return BLE_QIOT_RS_OK;
|
||||
#endif
|
||||
}
|
||||
|
||||
// report
|
||||
ble_qiot_ret_status_t ble_event_report_property(void)
|
||||
{
|
||||
#ifdef BLE_QIOT_INCLUDE_PROPERTY
|
||||
return ble_user_property_get_report_data();
|
||||
#else
|
||||
ble_qiot_log_e("property" BLE_QIOT_NOT_SUPPORT_WARN);
|
||||
return BLE_QIOT_RS_OK;
|
||||
#endif
|
||||
}
|
||||
|
||||
#if BLE_QIOT_SECURE_BIND
|
||||
ble_qiot_ret_status_t ble_event_sync_wait_time(void)
|
||||
{
|
||||
uint16_t time = BLE_QIOT_BIND_WAIT_TIME;
|
||||
|
||||
time = HTONS(time);
|
||||
return ble_event_notify(BLE_QIOT_EVENT_UP_SYNC_WAIT_TIME, NULL, 0, (const char *)&time, sizeof(uint16_t));
|
||||
}
|
||||
#endif //BLE_QIOT_SECURE_BIND
|
||||
|
||||
ble_qiot_ret_status_t ble_event_post(uint8_t event_id)
|
||||
{
|
||||
#ifdef BLE_QIOT_INCLUDE_EVENT
|
||||
uint8_t param_id = 0;
|
||||
uint8_t param_id_size = 0;
|
||||
uint8_t param_type = 0;
|
||||
int param_len = 0;
|
||||
uint16_t data_len = 0;
|
||||
uint16_t data_buf_off = 0;
|
||||
uint16_t string_len = 0;
|
||||
uint8_t header_buf = {0};
|
||||
|
||||
uint8_t data_buf[BLE_QIOT_EVENT_MAX_SIZE] = {0};
|
||||
|
||||
ble_qiot_log_d("post event: %d", event_id);
|
||||
param_id_size = ble_event_get_id_array_size(event_id);
|
||||
// get all data
|
||||
for (param_id = 0; param_id < param_id_size; param_id++) {
|
||||
param_type = ble_event_get_param_id_type(event_id, param_id);
|
||||
if (param_type >= BLE_QIOT_DATA_TYPE_BUTT) {
|
||||
ble_qiot_log_e("invalid event(%d:%d) type", event_id, param_id);
|
||||
return BLE_QIOT_RS_ERR;
|
||||
}
|
||||
|
||||
data_buf[data_len++] = BLE_QIOT_PACKAGE_TLV_HEAD(param_type, param_id);
|
||||
data_buf_off = data_len;
|
||||
if (BLE_QIOT_DATA_TYPE_STRING == param_type) {
|
||||
// reserved 2 bytes for string type, other type have fixed length
|
||||
data_buf_off += BLE_QIOT_STRING_TYPE_LEN;
|
||||
}
|
||||
param_len = ble_event_get_data_by_id(event_id, param_id, (char *)data_buf + data_buf_off,
|
||||
sizeof(data_buf) - data_buf_off);
|
||||
if (param_len < 0) {
|
||||
return BLE_QIOT_RS_ERR;
|
||||
} else if (param_len == 0) {
|
||||
// clean the header cause no data to post
|
||||
data_len--;
|
||||
data_buf[data_len] = '0';
|
||||
ble_qiot_log_d("event(%d: %d) no data to post", event_id, param_id);
|
||||
} else {
|
||||
if (BLE_QIOT_DATA_TYPE_STRING == param_type) {
|
||||
string_len = HTONS(param_len);
|
||||
memcpy(data_buf + data_len, &string_len, sizeof(uint16_t));
|
||||
data_len += sizeof(uint16_t);
|
||||
}
|
||||
data_len += param_len;
|
||||
}
|
||||
}
|
||||
header_buf = event_id;
|
||||
|
||||
return ble_event_notify(BLE_QIOT_EVENT_UP_EVENT_POST, &header_buf, sizeof(header_buf), (const char *)data_buf,
|
||||
data_len);
|
||||
#else
|
||||
ble_qiot_log_e("event" BLE_QIOT_NOT_SUPPORT_WARN);
|
||||
return BLE_QIOT_RS_OK;
|
||||
#endif //BLE_QIOT_INCLUDE_EVENT
|
||||
}
|
||||
#endif //BLE_QIOT_LLSYNC_STANDARD
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
@ -0,0 +1,621 @@
|
||||
/*
|
||||
* Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved.
|
||||
* Licensed under the MIT License (the "License"); you may not use this file except in
|
||||
* compliance with the License. You may obtain a copy of the License at
|
||||
* http://opensource.org/licenses/MIT
|
||||
* 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.
|
||||
*
|
||||
*/
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include "ble_qiot_config.h"
|
||||
|
||||
#if BLE_QIOT_LLSYNC_STANDARD
|
||||
//#include <stdbool.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "ble_qiot_export.h"
|
||||
#include "ble_qiot_import.h"
|
||||
#include "ble_qiot_common.h"
|
||||
#include "ble_qiot_llsync_data.h"
|
||||
#include "ble_qiot_llsync_event.h"
|
||||
#include "ble_qiot_utils_base64.h"
|
||||
#include "ble_qiot_crc.h"
|
||||
#include "ble_qiot_log.h"
|
||||
#include "ble_qiot_param_check.h"
|
||||
#include "ble_qiot_service.h"
|
||||
#include "ble_qiot_template.h"
|
||||
#include "ble_qiot_llsync_ota.h"
|
||||
#include "dual_bank_updata_api.h"
|
||||
#include "timer.h"
|
||||
#include "os/os_api.h"
|
||||
#include "update_loader_download.h"
|
||||
#include "app_config.h"
|
||||
|
||||
#if BLE_QIOT_SUPPORT_OTA
|
||||
static ble_ota_user_callback sg_ota_user_cb; // user callback
|
||||
// 1. monitor the data and request from the server if data lost; 2. call the user function if no data for a long time
|
||||
static int sg_ota_timer = 0;
|
||||
static uint8_t sg_ota_timeout_cnt = 0; // count the number of no data times
|
||||
static uint8_t sg_ota_data_buf[BLE_QIOT_OTA_BUF_SIZE] = {0}; // storage ota data and write to the flash at once
|
||||
static uint16_t sg_ota_data_buf_size = 0; // the data size in the buffer
|
||||
static uint32_t sg_ota_download_file_size = 0; // the data size download from the server
|
||||
static uint8_t sg_ota_next_seq = 0; // the next expect seq
|
||||
static uint32_t sg_ota_download_address = 0; // the address saved ota file
|
||||
static uint8_t sg_ota_download_percent = 0; // the percent of file had download
|
||||
static uint8_t sg_ota_flag = 0; // ota control info
|
||||
static ble_ota_info_record sg_ota_info; // the ota info storage in flash if support resuming
|
||||
static ble_ota_reply_t sg_ota_reply_info; // record the last reply info
|
||||
|
||||
static OS_SEM sg_ota_sem;
|
||||
|
||||
static update_op_tws_api_t *sg_ota_tws_same_api = NULL;
|
||||
static u8 pkt_flag = PKT_FLAG_FIRST;
|
||||
|
||||
#define BLE_QIOT_OTA_FLAG_SET(_BIT) (sg_ota_flag |= (_BIT));
|
||||
#define BLE_QIOT_OTA_FLAG_CLR(_BIT) (sg_ota_flag &= ~(_BIT));
|
||||
#define BLE_QIOT_OTA_FLAG_IS_SET(_BIT) ((sg_ota_flag & (_BIT)) == (_BIT))
|
||||
|
||||
uint32_t ble_ota_get_download_addr(void)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline bool ble_qiot_ota_info_valid(void)
|
||||
{
|
||||
return sg_ota_info.valid_flag == BLE_QIOT_OTA_PAGE_VALID_VAL;
|
||||
}
|
||||
static inline uint8_t ble_ota_next_seq_get(void)
|
||||
{
|
||||
return sg_ota_next_seq;
|
||||
}
|
||||
static inline void ble_ota_next_seq_inc(void)
|
||||
{
|
||||
sg_ota_next_seq++;
|
||||
}
|
||||
static inline uint32_t ble_ota_download_address_get(void)
|
||||
{
|
||||
return sg_ota_download_address;
|
||||
}
|
||||
static inline void ble_ota_download_address_set(void)
|
||||
{
|
||||
sg_ota_download_address = ble_ota_get_download_addr();
|
||||
return;
|
||||
}
|
||||
static inline uint32_t ble_ota_download_size_get(void)
|
||||
{
|
||||
return sg_ota_download_file_size;
|
||||
}
|
||||
static inline void ble_ota_download_size_inc(uint32_t size)
|
||||
{
|
||||
sg_ota_download_file_size += size;
|
||||
}
|
||||
static inline uint8_t ble_ota_file_percent_get(void)
|
||||
{
|
||||
return sg_ota_download_percent;
|
||||
}
|
||||
static inline void ble_ota_file_percent_set(uint8_t percent)
|
||||
{
|
||||
sg_ota_download_percent = percent;
|
||||
}
|
||||
|
||||
int ble_ota_write_flash(uint32_t flash_addr, const char *write_buf, uint16_t write_len)
|
||||
{
|
||||
return sg_ota_data_buf_size;
|
||||
}
|
||||
|
||||
void ble_ota_callback_reg(ble_ota_start_callback start_cb, ble_ota_stop_callback stop_cb,
|
||||
ble_ota_valid_file_callback valid_file_cb)
|
||||
{
|
||||
sg_ota_user_cb.start_cb = start_cb;
|
||||
sg_ota_user_cb.stop_cb = stop_cb;
|
||||
sg_ota_user_cb.valid_file_cb = valid_file_cb;
|
||||
}
|
||||
static inline void ble_ota_user_start_cb(void)
|
||||
{
|
||||
if (NULL != sg_ota_user_cb.start_cb) {
|
||||
ble_qiot_log_i("start callback begin");
|
||||
sg_ota_user_cb.start_cb();
|
||||
ble_qiot_log_i("start callback end");
|
||||
}
|
||||
}
|
||||
static inline void ble_ota_user_stop_cb(uint8_t result)
|
||||
{
|
||||
if (NULL != sg_ota_user_cb.stop_cb) {
|
||||
ble_qiot_log_i("stop callback begin");
|
||||
sg_ota_user_cb.stop_cb(result);
|
||||
ble_qiot_log_i("stop callback end");
|
||||
}
|
||||
}
|
||||
static inline ble_qiot_ret_status_t ble_ota_user_valid_cb(void)
|
||||
{
|
||||
if (NULL != sg_ota_user_cb.valid_file_cb) {
|
||||
ble_qiot_log_i("valid callback begin");
|
||||
return sg_ota_user_cb.valid_file_cb(sg_ota_info.download_file_info.file_size,
|
||||
(char *)sg_ota_info.download_file_info.file_version);
|
||||
}
|
||||
return BLE_QIOT_RS_OK;
|
||||
}
|
||||
static inline ble_qiot_ret_status_t ble_ota_write_info(void)
|
||||
{
|
||||
#if BLE_QIOT_SUPPORT_RESUMING
|
||||
sg_ota_info.valid_flag = BLE_QIOT_OTA_PAGE_VALID_VAL;
|
||||
sg_ota_info.last_file_size = ble_ota_download_size_get();
|
||||
sg_ota_info.last_address = ble_ota_download_address_get();
|
||||
if (sizeof(ble_ota_info_record) !=
|
||||
ble_write_flash(BLE_QIOT_OTA_INFO_FLASH_ADDR, (const char *)&sg_ota_info, sizeof(ble_ota_info_record))) {
|
||||
ble_qiot_log_e("write ota info failed");
|
||||
return BLE_QIOT_RS_ERR;
|
||||
}
|
||||
#endif //BLE_QIOT_SUPPORT_RESUMING
|
||||
return BLE_QIOT_RS_OK;
|
||||
}
|
||||
static inline void ble_ota_clear_info(void)
|
||||
{
|
||||
#if BLE_QIOT_SUPPORT_RESUMING
|
||||
sg_ota_info.valid_flag = ~BLE_QIOT_OTA_PAGE_VALID_VAL;
|
||||
if (sizeof(ble_ota_info_record) !=
|
||||
ble_write_flash(BLE_QIOT_OTA_INFO_FLASH_ADDR, (const char *)&sg_ota_info, sizeof(ble_ota_info_record))) {
|
||||
ble_qiot_log_e("clear ota info failed");
|
||||
}
|
||||
#endif //BLE_QIOT_SUPPORT_RESUMING
|
||||
return;
|
||||
}
|
||||
static inline ble_qiot_ret_status_t ble_ota_reply_ota_data(void)
|
||||
{
|
||||
uint8_t req = ble_ota_next_seq_get();
|
||||
uint32_t file_size = ble_ota_download_size_get();
|
||||
|
||||
printf("used old file size %x, req %d", file_size, req);
|
||||
if (sg_ota_reply_info.file_size != file_size) {
|
||||
sg_ota_reply_info.file_size = file_size;
|
||||
sg_ota_reply_info.req = req;
|
||||
} else {
|
||||
// in the case that the device reply info missed, the timer reply info again but the seq increased, so we need
|
||||
// saved the last reply info and used in the time
|
||||
req = sg_ota_reply_info.req;
|
||||
}
|
||||
|
||||
file_size = HTONL(file_size);
|
||||
return ble_event_notify(BLE_QIOT_EVENT_UP_REPLY_OTA_DATA, &req, sizeof(uint8_t), (const char *)&file_size,
|
||||
sizeof(uint32_t));
|
||||
}
|
||||
static inline ble_qiot_ret_status_t ble_ota_report_check_result(uint8_t firmware_valid, uint8_t error_code)
|
||||
{
|
||||
uint8_t result = firmware_valid | error_code;
|
||||
return ble_event_notify(BLE_QIOT_EVENT_UP_REPORT_CHECK_RESULT, NULL, 0, (const char *)&result, sizeof(uint8_t));
|
||||
}
|
||||
static inline void ble_ota_timer_delete(void)
|
||||
{
|
||||
if (NULL == sg_ota_timer) {
|
||||
ble_qiot_log_e("ble ota timer invalid, delete failed");
|
||||
return;
|
||||
}
|
||||
|
||||
sys_timer_del(sg_ota_timer);
|
||||
/* if (BLE_QIOT_RS_OK != ble_timer_delete(sg_ota_timer)) { */
|
||||
/* ble_qiot_log_e("ble ota timer delete failed"); */
|
||||
/* } */
|
||||
sg_ota_timer = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
static int ble_ota_write_end_callback(void *priv)
|
||||
{
|
||||
os_sem_post(&sg_ota_sem);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static ble_qiot_ret_status_t ble_ota_write_data_to_flash(void)
|
||||
{
|
||||
int ret = 0;
|
||||
int write_addr = 0;
|
||||
|
||||
// the download size include the data size, so the write address exclude the data size
|
||||
//os_time_dly(10);
|
||||
/* g_printf("%s\n", __func__); */
|
||||
dual_bank_update_write((const char *)sg_ota_data_buf, sg_ota_data_buf_size, ble_ota_write_end_callback);
|
||||
os_sem_pend(&sg_ota_sem, 0);
|
||||
|
||||
#if OTA_TWS_SAME_TIME_ENABLE
|
||||
if (pkt_flag != PKT_FLAG_FIRST) {
|
||||
if (sg_ota_tws_same_api && sg_ota_tws_same_api->tws_ota_data_send_pend) {
|
||||
if (sg_ota_tws_same_api->tws_ota_data_send_pend()) {
|
||||
printf("pend timeout\n");
|
||||
return BLE_QIOT_RS_ERR;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (sg_ota_tws_same_api && sg_ota_tws_same_api->tws_ota_data_send) {
|
||||
sg_ota_tws_same_api->tws_ota_data_send(sg_ota_data_buf, sg_ota_data_buf_size);
|
||||
}
|
||||
|
||||
pkt_flag = PKT_FLAG_MIDDLE;
|
||||
#endif
|
||||
|
||||
#if 0
|
||||
write_addr = ble_ota_download_address_get() + ble_ota_download_size_get() - sg_ota_data_buf_size;
|
||||
ret = ble_ota_write_flash(write_addr, (const char *)sg_ota_data_buf, sg_ota_data_buf_size);
|
||||
if (ret != sg_ota_data_buf_size) {
|
||||
ble_qiot_log_e("ota data write flash failed");
|
||||
return BLE_QIOT_RS_ERR;
|
||||
}
|
||||
#endif
|
||||
return BLE_QIOT_RS_OK;
|
||||
}
|
||||
static void ble_ota_timer_callback(void *param)
|
||||
{
|
||||
if (BLE_QIOT_OTA_FLAG_IS_SET(BLE_QIOT_OTA_RECV_DATA_BIT)) {
|
||||
BLE_QIOT_OTA_FLAG_CLR(BLE_QIOT_OTA_RECV_DATA_BIT);
|
||||
return;
|
||||
}
|
||||
sg_ota_timeout_cnt++;
|
||||
|
||||
ble_qiot_log_w("reply in the timer, count: %d", sg_ota_timeout_cnt);
|
||||
ble_ota_reply_ota_data();
|
||||
|
||||
if (sg_ota_timeout_cnt >= BLE_QIOT_OTA_MAX_RETRY_COUNT) {
|
||||
sg_ota_flag = 0;
|
||||
ble_ota_timer_delete();
|
||||
// inform the user ota failed because timeout
|
||||
#if BLE_QIOT_SUPPORT_OTA
|
||||
ble_ota_stop();
|
||||
#endif //BLE_QIOT_SUPPORT_OTA
|
||||
ble_ota_user_stop_cb(BLE_QIOT_OTA_ERR_TIMEOUT);
|
||||
}
|
||||
}
|
||||
static inline void ble_ota_timer_start(void)
|
||||
{
|
||||
if (NULL == sg_ota_timer) {
|
||||
sg_ota_timer = sys_timer_add(NULL, ble_ota_timer_callback, BLE_QIOT_RETRY_TIMEOUT * 1000);
|
||||
/* sg_ota_timer = ble_timer_create(BLE_TIMER_PERIOD_TYPE, ble_ota_timer_callback); */
|
||||
/* if (NULL == sg_ota_timer) { */
|
||||
/* ble_qiot_log_e("ble ota timer create failed"); */
|
||||
/* return; */
|
||||
/* } */
|
||||
}
|
||||
/* if (BLE_QIOT_RS_OK != ble_timer_start(sg_ota_timer, BLE_QIOT_RETRY_TIMEOUT * 1000)) { */
|
||||
/* ble_qiot_log_e("ble ota timer start failed"); */
|
||||
/* } */
|
||||
return;
|
||||
}
|
||||
static ble_qiot_ret_status_t ble_ota_init(void)
|
||||
{
|
||||
uint32_t size_align = 0;
|
||||
uint8_t file_percent = 0;
|
||||
|
||||
// init the ota env
|
||||
memset(sg_ota_data_buf, 0, sizeof(sg_ota_data_buf));
|
||||
sg_ota_data_buf_size = 0;
|
||||
sg_ota_timeout_cnt = 0;
|
||||
memset(&sg_ota_info, 0, sizeof(ble_ota_info_record));
|
||||
sg_ota_download_file_size = 0;
|
||||
sg_ota_next_seq = 0;
|
||||
sg_ota_download_percent = 0;
|
||||
sg_ota_flag = 0;
|
||||
ble_ota_download_address_set();
|
||||
memset(&sg_ota_reply_info, 0, sizeof(sg_ota_reply_info));
|
||||
|
||||
#if BLE_QIOT_SUPPORT_RESUMING
|
||||
// start from 0 if read flash fail, but ota will continue so ignored the return code
|
||||
ble_read_flash(BLE_QIOT_OTA_INFO_FLASH_ADDR, (char *)&sg_ota_info, sizeof(sg_ota_info));
|
||||
ble_qiot_log_hex(BLE_QIOT_LOG_LEVEL_INFO, "ota info", &sg_ota_info, sizeof(sg_ota_info));
|
||||
// check if the valid flag legalled
|
||||
if (ble_qiot_ota_info_valid()) {
|
||||
// the ota info write to flash may be mismatch the file write to flash, we should download file from the byte
|
||||
// align the flash page
|
||||
if (ble_ota_download_address_get() == sg_ota_info.last_address) {
|
||||
size_align = sg_ota_info.last_file_size / BLE_QIOT_RECORD_FLASH_PAGESIZE * BLE_QIOT_RECORD_FLASH_PAGESIZE;
|
||||
ble_ota_download_size_inc(size_align);
|
||||
file_percent = size_align * 100 / sg_ota_info.download_file_info.file_size;
|
||||
ble_ota_file_percent_set(file_percent);
|
||||
ble_qiot_log_i("align file size: %x, the percent: %d", size_align, file_percent);
|
||||
} else {
|
||||
memset(&sg_ota_info, 0, sizeof(ble_ota_info_record));
|
||||
}
|
||||
} else {
|
||||
memset(&sg_ota_info, 0, sizeof(ble_ota_info_record));
|
||||
}
|
||||
#endif //BLE_QIOT_SUPPORT_RESUMING
|
||||
return BLE_QIOT_RS_OK;
|
||||
}
|
||||
// stop ota if ble disconnect
|
||||
void ble_ota_stop(void)
|
||||
{
|
||||
if (!BLE_QIOT_OTA_FLAG_IS_SET(BLE_QIOT_OTA_REQUEST_BIT)) {
|
||||
ble_qiot_log_w("ota not start");
|
||||
return;
|
||||
}
|
||||
sg_ota_flag = 0;
|
||||
set_ota_status(0);
|
||||
ble_ota_timer_delete();
|
||||
// write data to flash if the ota stop
|
||||
ble_ota_write_data_to_flash();
|
||||
ble_ota_write_info();
|
||||
dual_bank_passive_update_exit(NULL);
|
||||
#if OTA_TWS_SAME_TIME_ENABLE
|
||||
if (sg_ota_tws_same_api && sg_ota_tws_same_api->tws_ota_err) {
|
||||
sg_ota_tws_same_api->tws_ota_err(0);
|
||||
}
|
||||
#endif
|
||||
// inform user ota failed because ble disconnect
|
||||
ble_ota_user_stop_cb(BLE_QIOT_OTA_DISCONNECT);
|
||||
}
|
||||
|
||||
ble_qiot_ret_status_t ble_ota_request_handle(const char *in_buf, int buf_len)
|
||||
{
|
||||
BUFF_LEN_SANITY_CHECK(buf_len, sizeof(ble_ota_file_info) - BLE_QIOT_OTA_MAX_VERSION_STR, BLE_QIOT_RS_ERR_PARA);
|
||||
|
||||
uint8_t ret = 0;
|
||||
uint8_t reply_flag = 0;
|
||||
uint32_t file_size = 0;
|
||||
uint32_t file_crc = 0;
|
||||
uint8_t version_len = 0;
|
||||
char *p = (char *)in_buf;
|
||||
char *notify_data = NULL;
|
||||
uint16_t notify_len = 0;
|
||||
ble_ota_reply_info ota_reply_info;
|
||||
|
||||
ble_ota_init();
|
||||
|
||||
memcpy(&file_size, p, sizeof(file_size));
|
||||
p += sizeof(file_size);
|
||||
memcpy(&file_crc, p, sizeof(file_crc));
|
||||
p += sizeof(file_crc);
|
||||
version_len = *p++;
|
||||
file_size = NTOHL(file_size);
|
||||
file_crc = NTOHL(file_crc);
|
||||
ble_qiot_log_i("request ota, size: %x, crc: %x, version: %s", file_size, file_crc, p);
|
||||
|
||||
// check if the ota is allowed
|
||||
ret = ble_ota_is_enable((const char *)p, file_size, file_crc);
|
||||
if (ret == BLE_OTA_ENABLE) {
|
||||
#if OTA_TWS_SAME_TIME_ENABLE
|
||||
sg_ota_tws_same_api = get_tws_update_api();
|
||||
if (sg_ota_tws_same_api == NULL) {
|
||||
ret = 0;
|
||||
} else {
|
||||
if (sg_ota_tws_same_api && sg_ota_tws_same_api->tws_ota_start) {
|
||||
struct __tws_ota_para tws_update_para;
|
||||
tws_update_para.fm_size = file_size;
|
||||
tws_update_para.fm_crc = file_crc;
|
||||
tws_update_para.max_pkt_len = BLE_QIOT_OTA_BUF_SIZE;
|
||||
if (sg_ota_tws_same_api->tws_ota_start(&tws_update_para) != 0) { //tws same time err
|
||||
ret = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
if (BLE_OTA_ENABLE == ret) {
|
||||
reply_flag = BLE_QIOT_OTA_ENABLE;
|
||||
ota_reply_info.package_nums = BLE_QIOT_TOTAL_PACKAGES;
|
||||
ota_reply_info.package_size = BLE_QIOT_PACKAGE_LENGTH + BLE_QIOT_OTA_DATA_HEADER_LEN;
|
||||
ota_reply_info.retry_timeout = BLE_QIOT_RETRY_TIMEOUT;
|
||||
ota_reply_info.reboot_timeout = BLE_QIOT_REBOOT_TIME;
|
||||
ota_reply_info.last_file_size = 0;
|
||||
ota_reply_info.package_interval = BLE_QIOT_PACKAGE_INTERVAL;
|
||||
#if BLE_QIOT_SUPPORT_RESUMING
|
||||
reply_flag |= BLE_QIOT_OTA_RESUME_ENABLE;
|
||||
// check file crc to determine its the same file, download the new file if its different
|
||||
if (ble_qiot_ota_info_valid() && (file_crc == sg_ota_info.download_file_info.file_crc) &&
|
||||
(file_size == sg_ota_info.download_file_info.file_size)) {
|
||||
ota_reply_info.last_file_size = HTONL(ble_ota_download_size_get());
|
||||
}
|
||||
#endif //BLE_QIOT_SUPPORT_RESUMING
|
||||
|
||||
sg_ota_info.download_file_info.file_size = file_size;
|
||||
sg_ota_info.download_file_info.file_crc = file_crc;
|
||||
memcpy(sg_ota_info.download_file_info.file_version, p, version_len);
|
||||
|
||||
ble_ota_user_start_cb();
|
||||
ble_ota_timer_start();
|
||||
// handler the ota data after ota request
|
||||
BLE_QIOT_OTA_FLAG_SET(BLE_QIOT_OTA_REQUEST_BIT);
|
||||
notify_data = (char *)&ota_reply_info;
|
||||
notify_len = sizeof(ble_ota_reply_info) - sizeof(ota_reply_info.rsv);
|
||||
|
||||
os_sem_create(&sg_ota_sem, 0);
|
||||
} else {
|
||||
reply_flag &= ~BLE_QIOT_OTA_ENABLE;
|
||||
notify_data = (char *)&ret;
|
||||
notify_len = sizeof(uint8_t);
|
||||
}
|
||||
return ble_event_notify(BLE_QIOT_EVENT_UP_REPLY_OTA_REPORT, &reply_flag, sizeof(uint8_t), (const char *)notify_data,
|
||||
notify_len);
|
||||
}
|
||||
|
||||
/* static int ble_ota_verify_result_hdl(int calc_crc){ */
|
||||
/* os_sem_post(&sg_ota_sem); */
|
||||
/* return 0; */
|
||||
/* } */
|
||||
// call the function after the server inform or the device receive the last package
|
||||
static void ble_ota_reboot_timer(void *priv)
|
||||
{
|
||||
cpu_reset();
|
||||
}
|
||||
|
||||
static int ble_ota_write_boot_info_callback(int err)
|
||||
{
|
||||
#if OTA_TWS_SAME_TIME_ENABLE
|
||||
if (sg_ota_tws_same_api && sg_ota_tws_same_api->tws_ota_result_hdl) {
|
||||
sg_ota_tws_same_api->tws_ota_result_hdl(err);
|
||||
}
|
||||
#else
|
||||
if (err == 0) {
|
||||
sys_timeout_add(NULL, ble_ota_reboot_timer, 500);
|
||||
}
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
ble_qiot_ret_status_t ble_ota_file_end_handle(void)
|
||||
{
|
||||
int crc_buf_len = 0;
|
||||
uint32_t crc_file_len = 0;
|
||||
uint32_t crc = 0;
|
||||
int slave_boot_info_state = 0;
|
||||
// the function called only once in the same ota process
|
||||
sg_ota_flag = 0;
|
||||
ble_ota_timer_delete();
|
||||
|
||||
ble_qiot_log_i("calc crc start");
|
||||
|
||||
/* u32 dual_bank_update_read_data(u32 offset, u8 *read_buf, u32 read_len); */
|
||||
while (crc_file_len < sg_ota_info.download_file_info.file_size) {
|
||||
crc_buf_len = sizeof(sg_ota_data_buf) > (sg_ota_info.download_file_info.file_size - crc_file_len)
|
||||
? (sg_ota_info.download_file_info.file_size - crc_file_len)
|
||||
: sizeof(sg_ota_data_buf);
|
||||
memset(sg_ota_data_buf, 0, sizeof(sg_ota_data_buf));
|
||||
dual_bank_update_read_data(ble_ota_download_address_get() + crc_file_len, (char *)sg_ota_data_buf, crc_buf_len);
|
||||
crc_file_len += crc_buf_len;
|
||||
crc = ble_qiot_crc32(crc, (const uint8_t *)sg_ota_data_buf, crc_buf_len);
|
||||
// maybe need task delay
|
||||
}
|
||||
|
||||
ble_qiot_log_i("calc crc %x, file crc %x", crc, sg_ota_info.download_file_info.file_crc);
|
||||
|
||||
#if OTA_TWS_SAME_TIME_ENABLE
|
||||
if (sg_ota_tws_same_api && sg_ota_tws_same_api->enter_verfiy_hdl) {
|
||||
if (sg_ota_tws_same_api->enter_verfiy_hdl(NULL)) { //slave verify err
|
||||
crc = 0;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
if (crc == sg_ota_info.download_file_info.file_crc) {
|
||||
#if OTA_TWS_SAME_TIME_ENABLE
|
||||
if (sg_ota_tws_same_api && sg_ota_tws_same_api->exit_verify_hdl) {
|
||||
u8 update_boot_info_flag, verify_err;
|
||||
if (sg_ota_tws_same_api->exit_verify_hdl(&verify_err, &update_boot_info_flag) == 0) { //slave write boot_info err
|
||||
slave_boot_info_state = 1;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
if (BLE_QIOT_RS_OK == ble_ota_user_valid_cb() && !slave_boot_info_state) {
|
||||
dual_bank_update_burn_boot_info(ble_ota_write_boot_info_callback);
|
||||
int ret = ble_ota_report_check_result(BLE_QIOT_OTA_VALID_SUCCESS, 0);
|
||||
ble_ota_user_stop_cb(BLE_QIOT_OTA_SUCCESS);
|
||||
} else {
|
||||
ble_ota_report_check_result(BLE_QIOT_OTA_VALID_FAIL, BLE_QIOT_OTA_FILE_ERROR);
|
||||
ble_ota_user_stop_cb(BLE_QIOT_OTA_ERR_FILE);
|
||||
}
|
||||
} else {
|
||||
ble_ota_report_check_result(BLE_QIOT_OTA_VALID_FAIL, BLE_QIOT_OTA_CRC_ERROR);
|
||||
ble_ota_user_stop_cb(BLE_QIOT_OTA_ERR_CRC);
|
||||
}
|
||||
ble_ota_clear_info();
|
||||
return BLE_QIOT_RS_OK;
|
||||
}
|
||||
|
||||
static ble_qiot_ret_status_t ble_qiot_ota_data_saved(char *data, uint16_t data_len)
|
||||
{
|
||||
int ret = 0;
|
||||
uint8_t percent = 0;
|
||||
|
||||
// write data to flash if the buffer overflow
|
||||
if ((data_len + sg_ota_data_buf_size) > sizeof(sg_ota_data_buf)) {
|
||||
// ble_qiot_log_e("data buf overflow, write data");
|
||||
if (BLE_QIOT_RS_OK != ble_ota_write_data_to_flash()) {
|
||||
return BLE_QIOT_RS_ERR;
|
||||
}
|
||||
// update the ota info if support resuming
|
||||
percent = (ble_ota_download_size_get() + sg_ota_data_buf_size) * 100 / sg_ota_info.download_file_info.file_size;
|
||||
if (percent > ble_ota_file_percent_get()) {
|
||||
ble_ota_file_percent_set(percent);
|
||||
ret = ble_ota_write_info();
|
||||
if (ret != BLE_QIOT_RS_OK) {
|
||||
ble_qiot_log_e("update ota info failed");
|
||||
return BLE_QIOT_RS_ERR;
|
||||
}
|
||||
}
|
||||
memset(sg_ota_data_buf, 0, sizeof(sg_ota_data_buf));
|
||||
sg_ota_data_buf_size = 0;
|
||||
}
|
||||
|
||||
memcpy(sg_ota_data_buf + sg_ota_data_buf_size, data, data_len);
|
||||
sg_ota_data_buf_size += data_len;
|
||||
ble_ota_download_size_inc(data_len);
|
||||
|
||||
// if the last package, write to flash and reply the server
|
||||
if (ble_ota_download_size_get() == sg_ota_info.download_file_info.file_size) {
|
||||
ble_qiot_log_i("receive the last package");
|
||||
if (BLE_QIOT_RS_OK != ble_ota_write_data_to_flash()) {
|
||||
return BLE_QIOT_RS_ERR;
|
||||
}
|
||||
ble_ota_reply_ota_data();
|
||||
// set the file receive end bit
|
||||
BLE_QIOT_OTA_FLAG_SET(BLE_QIOT_OTA_RECV_END_BIT);
|
||||
memset(sg_ota_data_buf, 0, sizeof(sg_ota_data_buf));
|
||||
sg_ota_data_buf_size = 0;
|
||||
}
|
||||
|
||||
return BLE_QIOT_RS_OK;
|
||||
}
|
||||
|
||||
ble_qiot_ret_status_t ble_ota_data_handle(const char *in_buf, int buf_len)
|
||||
{
|
||||
POINTER_SANITY_CHECK(in_buf, BLE_QIOT_RS_ERR_PARA);
|
||||
|
||||
uint8_t seq = 0;
|
||||
char *data = NULL;
|
||||
uint16_t data_len = 0;
|
||||
|
||||
if (!BLE_QIOT_OTA_FLAG_IS_SET(BLE_QIOT_OTA_REQUEST_BIT)) {
|
||||
ble_qiot_log_w("ota request is need first");
|
||||
return BLE_QIOT_RS_ERR;
|
||||
}
|
||||
|
||||
seq = in_buf[0];
|
||||
data = (char *)in_buf + 1;
|
||||
data_len = (uint16_t)buf_len - 1;
|
||||
|
||||
// ble_qiot_log_hex(BLE_QIOT_LOG_LEVEL_ERR, "data", in_buf, buf_len);
|
||||
if (seq == ble_ota_next_seq_get()) {
|
||||
BLE_QIOT_OTA_FLAG_SET(BLE_QIOT_OTA_RECV_DATA_BIT);
|
||||
BLE_QIOT_OTA_FLAG_SET(BLE_QIOT_OTA_FIRST_RETRY_BIT);
|
||||
sg_ota_timeout_cnt = 0;
|
||||
ble_ota_next_seq_inc();
|
||||
|
||||
if (BLE_QIOT_RS_OK != ble_qiot_ota_data_saved(data, data_len)) {
|
||||
// stop ota and inform the server
|
||||
ble_qiot_log_e("stop ota because save data failed");
|
||||
return BLE_QIOT_RS_ERR;
|
||||
}
|
||||
if (BLE_QIOT_OTA_FLAG_IS_SET(BLE_QIOT_OTA_RECV_END_BIT)) {
|
||||
return BLE_QIOT_RS_OK;
|
||||
}
|
||||
// reply the server if received the last package in the loop
|
||||
if (BLE_QIOT_TOTAL_PACKAGES == ble_ota_next_seq_get()) {
|
||||
ble_qiot_log_e("reply loop");
|
||||
ble_ota_reply_ota_data();
|
||||
sg_ota_next_seq = 0;
|
||||
}
|
||||
BLE_QIOT_OTA_FLAG_SET(BLE_QIOT_OTA_RECV_DATA_BIT);
|
||||
} else {
|
||||
// request data only once in the loop, controlled by the flag
|
||||
ble_qiot_log_w("unexpect seq %d, expect seq %d", seq, ble_ota_next_seq_get());
|
||||
if (BLE_QIOT_OTA_FLAG_IS_SET(BLE_QIOT_OTA_FIRST_RETRY_BIT)) {
|
||||
BLE_QIOT_OTA_FLAG_CLR(BLE_QIOT_OTA_FIRST_RETRY_BIT);
|
||||
BLE_QIOT_OTA_FLAG_CLR(BLE_QIOT_OTA_RECV_DATA_BIT);
|
||||
ble_ota_reply_ota_data();
|
||||
// refresh the timer
|
||||
ble_ota_timer_start();
|
||||
}
|
||||
}
|
||||
return BLE_QIOT_RS_OK;
|
||||
}
|
||||
#endif //BLE_QIOT_SUPPORT_OTA
|
||||
|
||||
#endif //BLE_QIOT_LLSYNC_STANDARD
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
@ -0,0 +1,664 @@
|
||||
/*
|
||||
* Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved.
|
||||
* Licensed under the MIT License (the "License"); you may not use this file except in
|
||||
* compliance with the License. You may obtain a copy of the License at
|
||||
* http://opensource.org/licenses/MIT
|
||||
* 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.
|
||||
*
|
||||
*/
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include <printf.h>
|
||||
|
||||
#include "ble_qiot_config.h"
|
||||
|
||||
#include "ble_qiot_export.h"
|
||||
#include "ble_qiot_import.h"
|
||||
#include "ble_qiot_llsync_data.h"
|
||||
#include "ble_qiot_llsync_device.h"
|
||||
#include "ble_qiot_llsync_event.h"
|
||||
#include "ble_qiot_log.h"
|
||||
#include "ble_qiot_llsync_ota.h"
|
||||
#include "ble_qiot_param_check.h"
|
||||
#include "ble_qiot_service.h"
|
||||
#include "ble_qiot_template.h"
|
||||
#include "ble_qiot_service.h"
|
||||
#include "ble_qiot_crc.h"
|
||||
#include "asm/clock.h"
|
||||
#include "app_config.h"
|
||||
#include "update_loader_download.h"
|
||||
#include "os/os_api.h"
|
||||
|
||||
#define BLE_QIOT_OTA_HZ (120 * 1000000L)
|
||||
|
||||
// llsync support data fragment, so we need to package all the data before parsing if the data is slice
|
||||
static ble_event_slice_t sg_ble_slice_data;
|
||||
|
||||
#if BLE_QIOT_BUTTON_BROADCAST
|
||||
static ble_timer_t sg_bind_timer = NULL;
|
||||
#endif //BLE_QIOT_BUTTON_BROADCAST
|
||||
|
||||
#if BLE_QIOT_SECURE_BIND
|
||||
static ble_bind_data sg_bind_auth_data;
|
||||
#endif //BLE_QIOT_SECURE_BIND
|
||||
|
||||
static qiot_service_init_s service_info = {
|
||||
.service_uuid16 = IOT_BLE_UUID_SERVICE,
|
||||
.service_uuid128 = IOT_BLE_UUID_BASE,
|
||||
.device_info =
|
||||
{
|
||||
.uuid16 = IOT_BLE_UUID_DEVICE_INFO,
|
||||
.gatt_char_props = GATT_CHAR_WRITE,
|
||||
.on_write = ble_device_info_write_cb,
|
||||
},
|
||||
.event =
|
||||
{
|
||||
.uuid16 = IOT_BLE_UUID_EVENT,
|
||||
.gatt_char_props = GATT_CHAR_NOTIFY,
|
||||
.on_write = NULL,
|
||||
},
|
||||
#if BLE_QIOT_LLSYNC_STANDARD
|
||||
.data =
|
||||
{
|
||||
.uuid16 = IOT_BLE_UUID_DATA,
|
||||
.gatt_char_props = GATT_CHAR_WRITE,
|
||||
.on_write = ble_lldata_write_cb,
|
||||
},
|
||||
.ota =
|
||||
{
|
||||
.uuid16 = IOT_BLE_UUID_OTA,
|
||||
.gatt_char_props = GATT_CHAR_WRITE_WO_RESP,
|
||||
.on_write = ble_ota_write_cb,
|
||||
},
|
||||
#endif //BLE_QIOT_LLSYNC_STANDARD
|
||||
};
|
||||
|
||||
const qiot_service_init_s *ble_get_qiot_services(void)
|
||||
{
|
||||
return &service_info;
|
||||
}
|
||||
|
||||
#if BLE_QIOT_LLSYNC_STANDARD
|
||||
|
||||
#if BLE_QIOT_SECURE_BIND
|
||||
static ble_qiot_ret_status_t ble_secure_bind_handle(const char *data, uint16_t len)
|
||||
{
|
||||
memset(&sg_bind_auth_data, 0, sizeof(ble_bind_data));
|
||||
memcpy(&sg_bind_auth_data, data, sizeof(ble_bind_data));
|
||||
ble_event_sync_wait_time();
|
||||
ble_secure_bind_user_cb();
|
||||
|
||||
return BLE_QIOT_RS_OK;
|
||||
}
|
||||
|
||||
ble_qiot_ret_status_t ble_secure_bind_user_confirm(ble_qiot_secure_bind_t choose)
|
||||
{
|
||||
char out_buf[80] = {0};
|
||||
int ret_len = 0;
|
||||
uint8_t flag = 0;
|
||||
|
||||
ble_qiot_log_i("user choose: %d", choose);
|
||||
ret_len = ble_bind_get_authcode(&sg_bind_auth_data, sizeof(ble_bind_data), out_buf, sizeof(out_buf));
|
||||
if (ret_len <= 0) {
|
||||
ble_qiot_log_e("get bind authcode failed");
|
||||
return BLE_QIOT_RS_ERR;
|
||||
}
|
||||
flag = choose << 5;
|
||||
return ble_event_notify2((uint8_t)BLE_QIOT_EVENT_UP_BIND_SIGN_RET, flag, NULL, 0, out_buf, ret_len);
|
||||
}
|
||||
#endif //BLE_QIOT_SECURE_BIND
|
||||
|
||||
void ble_lldata_write_cb(const uint8_t *buf, uint16_t len)
|
||||
{
|
||||
(void)ble_lldata_msg_handle((const char *)buf, len);
|
||||
}
|
||||
|
||||
void ble_ota_write_cb(const uint8_t *buf, uint16_t len)
|
||||
{
|
||||
(void)ble_ota_msg_handle((const char *)buf, len);
|
||||
}
|
||||
|
||||
#endif //BLE_QIOT_LLSYNC_STANDARD
|
||||
|
||||
#if BLE_QIOT_BUTTON_BROADCAST
|
||||
static void ble_bind_timer_callback(void *param)
|
||||
{
|
||||
ble_qiot_log_i("timer timeout");
|
||||
if (E_LLSYNC_BIND_WAIT == llsync_bind_state_get()) {
|
||||
ble_advertising_stop();
|
||||
llsync_bind_state_set(E_LLSYNC_BIND_IDLE);
|
||||
ble_qiot_log_i("stop advertising");
|
||||
}
|
||||
}
|
||||
#endif //BLE_QIOT_BUTTON_BROADCAST
|
||||
|
||||
ble_qiot_ret_status_t ble_qiot_advertising_start(void)
|
||||
{
|
||||
printf("ble_qiot_advertising_start\n");
|
||||
adv_info_s my_adv_info;
|
||||
uint16_t uuids[1];
|
||||
uint8_t adv_data[32] = {0};
|
||||
uint8_t adv_data_len = 0;
|
||||
|
||||
uuids[0] = IOT_BLE_UUID_SERVICE;
|
||||
my_adv_info.uuid_info.uuid_num = 1;
|
||||
my_adv_info.uuid_info.uuids = uuids;
|
||||
|
||||
if (E_LLSYNC_BIND_IDLE == llsync_bind_state_get()) {
|
||||
#if BLE_QIOT_BUTTON_BROADCAST
|
||||
if (NULL == sg_bind_timer) {
|
||||
sg_bind_timer = ble_timer_create(BLE_TIMER_ONE_SHOT_TYPE, ble_bind_timer_callback);
|
||||
if (NULL == sg_bind_timer) {
|
||||
ble_qiot_log_e("create bind timer failed");
|
||||
return BLE_QIOT_RS_ERR;
|
||||
}
|
||||
}
|
||||
#endif //BLE_QIOT_BUTTON_BROADCAST
|
||||
|
||||
ble_advertising_stop();
|
||||
|
||||
llsync_bind_state_set(E_LLSYNC_BIND_WAIT);
|
||||
adv_data_len = ble_get_my_broadcast_data((char *)adv_data, sizeof(adv_data));
|
||||
my_adv_info.manufacturer_info.company_identifier = TENCENT_COMPANY_IDENTIFIER;
|
||||
my_adv_info.manufacturer_info.adv_data = adv_data;
|
||||
my_adv_info.manufacturer_info.adv_data_len = adv_data_len;
|
||||
printf("adv_data:");
|
||||
put_buf(adv_data, adv_data_len);
|
||||
ble_advertising_start(&my_adv_info);
|
||||
ble_qiot_log_i("start wait advertising");
|
||||
|
||||
#if BLE_QIOT_BUTTON_BROADCAST
|
||||
ble_timer_start(sg_bind_timer, BLE_QIOT_BIND_TIMEOUT);
|
||||
#endif //BLE_QIOT_BUTTON_BROADCAST
|
||||
} else if (E_LLSYNC_BIND_WAIT == llsync_bind_state_get()) {
|
||||
ble_advertising_stop();
|
||||
adv_data_len = ble_get_my_broadcast_data((char *)adv_data, sizeof(adv_data));
|
||||
my_adv_info.manufacturer_info.company_identifier = TENCENT_COMPANY_IDENTIFIER;
|
||||
my_adv_info.manufacturer_info.adv_data = adv_data;
|
||||
my_adv_info.manufacturer_info.adv_data_len = adv_data_len;
|
||||
ble_advertising_start(&my_adv_info);
|
||||
ble_qiot_log_i("restart wait advertising");
|
||||
|
||||
#if BLE_QIOT_BUTTON_BROADCAST
|
||||
ble_timer_stop(sg_bind_timer);
|
||||
ble_timer_start(sg_bind_timer, BLE_QIOT_BIND_TIMEOUT);
|
||||
#endif //BLE_QIOT_BUTTON_BROADCAST
|
||||
} else if (E_LLSYNC_BIND_SUCC == llsync_bind_state_get()) {
|
||||
ble_advertising_stop();
|
||||
adv_data_len = ble_get_my_broadcast_data((char *)adv_data, sizeof(adv_data));
|
||||
my_adv_info.manufacturer_info.company_identifier = TENCENT_COMPANY_IDENTIFIER;
|
||||
my_adv_info.manufacturer_info.adv_data = adv_data;
|
||||
my_adv_info.manufacturer_info.adv_data_len = adv_data_len;
|
||||
ble_advertising_start(&my_adv_info);
|
||||
ble_qiot_log_i("start bind advertising");
|
||||
} else {
|
||||
// do nothing
|
||||
}
|
||||
|
||||
return BLE_QIOT_RS_OK;
|
||||
}
|
||||
|
||||
ble_qiot_ret_status_t ble_qiot_advertising_stop(void)
|
||||
{
|
||||
return 0 == ble_advertising_stop() ? BLE_QIOT_RS_OK : BLE_QIOT_RS_ERR;
|
||||
}
|
||||
|
||||
ble_qiot_ret_status_t ble_qiot_explorer_init(void)
|
||||
{
|
||||
printf("ble_qiot_explorer_init\n");
|
||||
ble_qiot_ret_status_t ret_code = BLE_QIOT_RS_OK;
|
||||
const qiot_service_init_s *service_info = NULL;
|
||||
|
||||
ble_qiot_set_log_level(BLE_QIOT_LOG_LEVEL_INFO);
|
||||
|
||||
service_info = ble_get_qiot_services();
|
||||
//ble_services_add(service_info);
|
||||
|
||||
ret_code = ble_init_flash_data();
|
||||
if (ret_code != BLE_QIOT_RS_OK) {
|
||||
ble_qiot_log_e("flash init failed, ret code %d", ret_code);
|
||||
return ret_code;
|
||||
}
|
||||
|
||||
return ret_code;
|
||||
}
|
||||
|
||||
void ll_sync_init()
|
||||
{
|
||||
ble_qiot_explorer_init();
|
||||
#if BLE_QIOT_SUPPORT_OTA && OTA_TWS_SAME_TIME_ENABLE
|
||||
tws_sync_update_crc_handler_register(ble_qiot_crc32_init, ble_qiot_crc32);
|
||||
#endif
|
||||
}
|
||||
|
||||
void ble_device_info_write_cb(const uint8_t *buf, uint16_t len)
|
||||
{
|
||||
(void)ble_device_info_msg_handle((const char *)buf, len);
|
||||
}
|
||||
|
||||
// when gap get ble connect event, use this function
|
||||
void ble_gap_connect_cb(void)
|
||||
{
|
||||
ble_connection_state_set(E_BLE_CONNECTED);
|
||||
}
|
||||
|
||||
// when gap get ble disconnect event, use this function
|
||||
void ble_gap_disconnect_cb(void)
|
||||
{
|
||||
llsync_mtu_update(0);
|
||||
llsync_connection_state_set(E_LLSYNC_DISCONNECTED);
|
||||
ble_connection_state_set(E_BLE_DISCONNECTED);
|
||||
#if BLE_QIOT_SUPPORT_OTA
|
||||
ble_ota_stop();
|
||||
#endif //BLE_QIOT_SUPPORT_OTA
|
||||
}
|
||||
|
||||
static uint8_t ble_msg_type_header_len(uint8_t type)
|
||||
{
|
||||
if (type == BLE_QIOT_GET_STATUS_REPLY_DATA_TYPE) {
|
||||
return BLE_QIOT_GET_STATUS_REPLY_HEADER_LEN;
|
||||
} else {
|
||||
return BLE_QIOT_DATA_FIXED_HEADER_LEN;
|
||||
}
|
||||
}
|
||||
|
||||
static int8_t ble_package_slice_data(uint8_t data_type, uint8_t flag, uint8_t header_len, const char *in_buf,
|
||||
int in_len)
|
||||
{
|
||||
if (!BLE_QIOT_IS_SLICE_HEADER(flag)) {
|
||||
if (!sg_ble_slice_data.have_data) {
|
||||
ble_qiot_log_e("slice no header");
|
||||
return -1;
|
||||
}
|
||||
if (data_type != sg_ble_slice_data.type) {
|
||||
ble_qiot_log_e("msg type: %d != %d", data_type, sg_ble_slice_data.type);
|
||||
return -1;
|
||||
}
|
||||
if (sg_ble_slice_data.buf_len + (in_len - header_len) > sizeof(sg_ble_slice_data.buf)) {
|
||||
ble_qiot_log_e("too long data: %d > %d", sg_ble_slice_data.buf_len + (in_len - header_len),
|
||||
sizeof(sg_ble_slice_data.buf));
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
if (BLE_QIOT_IS_SLICE_HEADER(flag)) {
|
||||
if (sg_ble_slice_data.have_data) {
|
||||
ble_qiot_log_i("new data coming, clean the package buffer");
|
||||
memset(&sg_ble_slice_data, 0, sizeof(sg_ble_slice_data));
|
||||
}
|
||||
sg_ble_slice_data.have_data = true;
|
||||
sg_ble_slice_data.type = data_type;
|
||||
// reserved space for payload length field
|
||||
sg_ble_slice_data.buf_len += header_len;
|
||||
sg_ble_slice_data.buf[0] = in_buf[0];
|
||||
memcpy(sg_ble_slice_data.buf + sg_ble_slice_data.buf_len, in_buf + header_len, in_len - header_len);
|
||||
sg_ble_slice_data.buf_len += (in_len - header_len);
|
||||
|
||||
return 1;
|
||||
} else if (BLE_QIOT_IS_SLICE_BODY(flag)) {
|
||||
memcpy(sg_ble_slice_data.buf + sg_ble_slice_data.buf_len, in_buf + header_len, in_len - header_len);
|
||||
sg_ble_slice_data.buf_len += (in_len - header_len);
|
||||
return 1;
|
||||
} else {
|
||||
memcpy(sg_ble_slice_data.buf + sg_ble_slice_data.buf_len, in_buf + header_len, in_len - header_len);
|
||||
sg_ble_slice_data.buf_len += (in_len - header_len);
|
||||
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
int ble_device_info_msg_handle(const char *in_buf, int in_len)
|
||||
{
|
||||
POINTER_SANITY_CHECK(in_buf, BLE_QIOT_RS_ERR_PARA);
|
||||
uint8_t ch;
|
||||
char out_buf[80] = {0};
|
||||
char *p_data = NULL;
|
||||
int p_data_len = 0;
|
||||
int ret_len = 0;
|
||||
uint16_t tmp_len = 0;
|
||||
uint8_t header_len = 0;
|
||||
int ret = BLE_QIOT_RS_OK;
|
||||
char *p_ssid = NULL;
|
||||
char *p_passwd = NULL;
|
||||
// This flag is use to avoid attacker jump "ble_conn_get_authcode()" step, then
|
||||
// send 'E_DEV_MSG_CONN_SUCC' msg, and device straightly set 'E_LLSYNC_CONNECTED' flag.
|
||||
// This behavior make signature check useless lead to risk.
|
||||
static bool conn_flag = false;
|
||||
|
||||
p_data = (char *)in_buf;
|
||||
p_data_len = in_len;
|
||||
|
||||
// E_DEV_MSG_SYNC_TIME, E_DEV_MSG_CONN_VALID, E_DEV_MSG_BIND_SUCC, E_DEV_MSG_UNBIND this 4 type
|
||||
// of message has more than one bytes data, it may cut to several slices, here need to merge them
|
||||
// together, other type message only has 1 byte data, not need merge.
|
||||
if ((in_len > 3) && BLE_QIOT_IS_SLICE_PACKAGE(in_buf[1])) {
|
||||
// ble_qiot_log_hex(BLE_QIOT_LOG_LEVEL_INFO, "slice", p_data, p_data_len);
|
||||
header_len = ble_msg_type_header_len(in_buf[0]);
|
||||
ret = ble_package_slice_data(in_buf[0], in_buf[1], header_len, in_buf, in_len);
|
||||
if (ret < 0) {
|
||||
return BLE_QIOT_RS_ERR;
|
||||
} else if (ret == 0) {
|
||||
tmp_len = HTONS(sg_ble_slice_data.buf_len - header_len);
|
||||
memcpy(&sg_ble_slice_data.buf[1], &tmp_len, sizeof(tmp_len));
|
||||
p_data = sg_ble_slice_data.buf;
|
||||
p_data_len = sg_ble_slice_data.buf_len;
|
||||
} else if (ret > 0) {
|
||||
return BLE_QIOT_RS_OK;
|
||||
}
|
||||
}
|
||||
// ble_qiot_log_hex(BLE_QIOT_LOG_LEVEL_INFO, "tlv", p_data, p_data_len);
|
||||
|
||||
ch = p_data[0];
|
||||
printf("msg ch = %d\n", ch);
|
||||
switch (ch) {
|
||||
#if BLE_QIOT_LLSYNC_STANDARD
|
||||
case E_DEV_MSG_SYNC_TIME:
|
||||
#if BLE_QIOT_SECURE_BIND
|
||||
ret = ble_secure_bind_handle(p_data + 3, p_data_len - 3);
|
||||
#else
|
||||
ret_len = ble_bind_get_authcode(p_data + 3, p_data_len - 3, out_buf, sizeof(out_buf));
|
||||
if (ret_len <= 0) {
|
||||
ble_qiot_log_e("get bind authcode failed");
|
||||
ret = BLE_QIOT_RS_ERR;
|
||||
break;
|
||||
}
|
||||
ret = ble_event_notify((uint8_t)BLE_QIOT_EVENT_UP_BIND_SIGN_RET, NULL, 0, out_buf, ret_len);
|
||||
#endif //BLE_QIOT_SECURE_BIND
|
||||
break;
|
||||
case E_DEV_MSG_CONN_VALID:
|
||||
ret_len = ble_conn_get_authcode(p_data + 3, p_data_len - 3, out_buf, sizeof(out_buf));
|
||||
if (ret_len <= 0) {
|
||||
ble_qiot_log_e("get connect authcode failed");
|
||||
ret = BLE_QIOT_RS_ERR;
|
||||
break;
|
||||
}
|
||||
ret = ble_event_notify((uint8_t)BLE_QIOT_EVENT_UP_CONN_SIGN_RET, NULL, 0, out_buf, ret_len);
|
||||
conn_flag = true;
|
||||
break;
|
||||
case E_DEV_MSG_BIND_SUCC:
|
||||
if (BLE_QIOT_RS_OK != ble_bind_write_result(p_data + 3, p_data_len - 3)) {
|
||||
ble_qiot_log_e("write bind result failed");
|
||||
ret = BLE_QIOT_RS_ERR;
|
||||
}
|
||||
break;
|
||||
case E_DEV_MSG_BIND_FAIL:
|
||||
ble_qiot_log_i("get msg bind fail");
|
||||
break;
|
||||
case E_DEV_MSG_UNBIND:
|
||||
ret_len = ble_unbind_get_authcode(p_data + 3, p_data_len - 3, out_buf, sizeof(out_buf));
|
||||
if (ret_len <= 0) {
|
||||
ble_qiot_log_e("get unbind authcode failed");
|
||||
ret = BLE_QIOT_RS_ERR;
|
||||
break;
|
||||
}
|
||||
ret = ble_event_notify((uint8_t)BLE_QIOT_EVENT_UP_UNBIND_SIGN_RET, NULL, 0, out_buf, ret_len);
|
||||
break;
|
||||
case E_DEV_MSG_CONN_SUCC:
|
||||
if (!conn_flag) {
|
||||
break;
|
||||
}
|
||||
conn_flag = false;
|
||||
ble_qiot_log_i("get msg connect success");
|
||||
llsync_connection_state_set(E_LLSYNC_CONNECTED);
|
||||
ret = ble_event_report_device_info();
|
||||
//llsync_device_state_sync();
|
||||
break;
|
||||
case E_DEV_MSG_CONN_FAIL:
|
||||
ble_qiot_log_i("get msg connect fail");
|
||||
break;
|
||||
case E_DEV_MSG_UNBIND_SUCC:
|
||||
ble_qiot_log_i("get msg unbind success");
|
||||
if (BLE_QIOT_RS_OK != ble_unbind_write_result()) {
|
||||
ble_qiot_log_e("write unbind result failed");
|
||||
ret = BLE_QIOT_RS_ERR;
|
||||
}
|
||||
break;
|
||||
case E_DEV_MSG_UNBIND_FAIL:
|
||||
ble_qiot_log_i("get msg unbind fail");
|
||||
break;
|
||||
case E_DEV_MSG_BIND_TIMEOUT:
|
||||
ble_qiot_log_i("get msg bind result: %d", p_data[1]);
|
||||
#if (1 == BLE_QIOT_SECURE_BIND)
|
||||
ble_secure_bind_user_notify(p_data[1]);
|
||||
#endif
|
||||
break;
|
||||
#endif //BLE_QIOT_LLSYNC_STANDARD
|
||||
#if BLE_QIOT_LLSYNC_CONFIG_NET
|
||||
case E_DEV_MSG_GET_DEV_INFO:
|
||||
llsync_connection_state_set(E_LLSYNC_CONNECTED);
|
||||
ret = ble_event_report_device_info();
|
||||
break;
|
||||
case E_DEV_MSG_SET_WIFI_MODE:
|
||||
ret = ble_combo_wifi_mode_set(p_data[1]);
|
||||
break;
|
||||
case E_DEV_MSG_SET_WIFI_INFO:
|
||||
// 1 byte ssid len + N bytes ssid + 1 byte pwd len + N bytes pwd
|
||||
p_ssid = &p_data[3];
|
||||
p_passwd = &p_ssid[p_ssid[0] + 1];
|
||||
ret = ble_combo_wifi_info_set((const char *)&p_ssid[1], p_ssid[0], (const char *)&p_passwd[1], p_passwd[0]);
|
||||
break;
|
||||
case E_DEV_MSG_SET_WIFI_CONNECT:
|
||||
ret = ble_combo_wifi_connect();
|
||||
break;
|
||||
case E_DEV_MSG_SET_WIFI_TOKEN:
|
||||
ret = ble_combo_wifi_token_set(p_data + 3, p_data_len - 3);
|
||||
break;
|
||||
case E_DEV_MSG_GET_DEV_LOG:
|
||||
ret = ble_combo_wifi_log_get();
|
||||
break;
|
||||
#endif
|
||||
case E_DEV_MSG_SET_MTU_RESULT:
|
||||
ble_inform_mtu_result(p_data + 1, p_data_len - 1);
|
||||
llsync_device_state_sync();
|
||||
break;
|
||||
default:
|
||||
ble_qiot_log_e("unknow type %d", ch);
|
||||
break;
|
||||
}
|
||||
memset(&sg_ble_slice_data, 0, sizeof(sg_ble_slice_data));
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
#if BLE_QIOT_LLSYNC_STANDARD
|
||||
// lldata message from remote
|
||||
int ble_lldata_msg_handle(const char *in_buf, int in_len)
|
||||
{
|
||||
POINTER_SANITY_CHECK(in_buf, BLE_QIOT_RS_ERR_PARA);
|
||||
|
||||
uint8_t data_type = 0;
|
||||
uint8_t data_effect = 0;
|
||||
uint8_t id = 0;
|
||||
uint8_t slice_flag = 0;
|
||||
uint8_t header_len = 0;
|
||||
uint8_t slice_type = 0;
|
||||
uint16_t tmp_len = 0;
|
||||
char *p_data = NULL;
|
||||
int p_data_len = 0;
|
||||
int ret = 0;
|
||||
|
||||
if (!llsync_is_connected()) {
|
||||
ble_qiot_log_e("operation negate, device not connected");
|
||||
return BLE_QIOT_RS_ERR;
|
||||
}
|
||||
|
||||
p_data = (char *)in_buf;
|
||||
p_data_len = in_len;
|
||||
|
||||
data_type = BLE_QIOT_PARSE_MSG_HEAD_TYPE(in_buf[0]);
|
||||
if (data_type >= BLE_QIOT_DATA_TYPE_BUTT) {
|
||||
ble_qiot_log_e("invalid data type: %d", data_type);
|
||||
return BLE_QIOT_RS_ERR;
|
||||
}
|
||||
data_effect = BLE_QIOT_PARSE_MSG_HEAD_EFFECT(in_buf[0]);
|
||||
if (data_effect >= BLE_QIOT_EFFECT_BUTT) {
|
||||
ble_qiot_log_e("invalid data eff: ect");
|
||||
return BLE_QIOT_RS_ERR;
|
||||
}
|
||||
id = BLE_QIOT_PARSE_MSG_HEAD_ID(in_buf[0]);
|
||||
ble_qiot_log_d("data type: %d, effect: %d, id: %d", data_type, data_effect, id);
|
||||
|
||||
// if data is action_reply, control or get_status_reply, the data maybe need package
|
||||
if ((data_type == BLE_QIOT_MSG_TYPE_ACTION) || (in_buf[0] == BLE_QIOT_CONTROL_DATA_TYPE) ||
|
||||
(in_buf[0] == BLE_QIOT_GET_STATUS_REPLY_DATA_TYPE)) {
|
||||
slice_flag = (in_buf[0] == BLE_QIOT_GET_STATUS_REPLY_DATA_TYPE) ? in_buf[2] : in_buf[1];
|
||||
slice_type = (in_buf[0] == BLE_QIOT_GET_STATUS_REPLY_DATA_TYPE) ? in_buf[0] : data_type;
|
||||
|
||||
// ble_qiot_log_hex(BLE_QIOT_LOG_LEVEL_INFO, "slice", p_data, p_data_len);
|
||||
if (BLE_QIOT_IS_SLICE_PACKAGE(slice_flag)) {
|
||||
header_len = ble_msg_type_header_len(slice_type);
|
||||
ret = ble_package_slice_data(slice_type, slice_flag, header_len, in_buf, in_len);
|
||||
if (ret < 0) {
|
||||
return BLE_QIOT_RS_ERR;
|
||||
} else if (ret == 0) {
|
||||
tmp_len = HTONS(sg_ble_slice_data.buf_len - header_len);
|
||||
if (BLE_QIOT_GET_STATUS_REPLY_DATA_TYPE == slice_type) {
|
||||
sg_ble_slice_data.buf[1] = in_buf[1];
|
||||
memcpy(&sg_ble_slice_data.buf[2], &tmp_len, sizeof(tmp_len));
|
||||
} else {
|
||||
memcpy(&sg_ble_slice_data.buf[1], &tmp_len, sizeof(tmp_len));
|
||||
}
|
||||
p_data = sg_ble_slice_data.buf;
|
||||
p_data_len = sg_ble_slice_data.buf_len;
|
||||
} else if (ret > 0) {
|
||||
return BLE_QIOT_RS_OK;
|
||||
}
|
||||
}
|
||||
}
|
||||
// ble_qiot_log_hex(BLE_QIOT_LOG_LEVEL_INFO, "tlv", p_data, p_data_len);
|
||||
|
||||
switch (data_type) {
|
||||
case BLE_QIOT_MSG_TYPE_PROPERTY:
|
||||
if (BLE_QIOT_EFFECT_REQUEST == data_effect) {
|
||||
// default E_BLE_DATA_DOWN_TYPE_CONTROL
|
||||
ret = ble_lldata_property_request_handle(p_data + 3, p_data_len - 3);
|
||||
} else if (BLE_QIOT_EFFECT_REPLY == data_effect) {
|
||||
// id means BLE_QIOT_DATA_DOWN_GET_STATUS_REPLY or BLE_QIOT_DATA_DOWN_REPORT_REPLY
|
||||
ret = ble_lldata_property_reply_handle(id, p_data + 1, p_data_len - 1);
|
||||
} else {
|
||||
ret = BLE_QIOT_RS_ERR;
|
||||
}
|
||||
break;
|
||||
case BLE_QIOT_MSG_TYPE_EVENT:
|
||||
if (BLE_QIOT_EFFECT_REPLY == data_effect) {
|
||||
ret = ble_lldata_event_handle(id, p_data + 1, p_data_len - 1);
|
||||
} else {
|
||||
ble_qiot_log_e("invalid event data effect");
|
||||
ret = BLE_QIOT_RS_ERR;
|
||||
}
|
||||
break;
|
||||
case BLE_QIOT_MSG_TYPE_ACTION:
|
||||
if (BLE_QIOT_EFFECT_REQUEST == data_effect) {
|
||||
ret = ble_lldata_action_handle(id, p_data + 3, p_data_len - 3);
|
||||
} else {
|
||||
ble_qiot_log_e("invalid action data effect");
|
||||
ret = BLE_QIOT_RS_ERR;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
memset(&sg_ble_slice_data, 0, sizeof(sg_ble_slice_data));
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
#if BLE_QIOT_SUPPORT_OTA
|
||||
static uint8_t ble_ota_type_header_len(uint8_t type)
|
||||
{
|
||||
return BLE_QIOT_GET_OTA_REQUEST_HEADER_LEN;
|
||||
}
|
||||
|
||||
int ble_ota_msg_handle(const char *buf, uint16_t len)
|
||||
{
|
||||
POINTER_SANITY_CHECK(buf, BLE_QIOT_RS_ERR_PARA);
|
||||
|
||||
uint8_t data_type = 0;
|
||||
int ret = BLE_QIOT_RS_OK;
|
||||
uint8_t header_len = 0;
|
||||
uint8_t slice_flag = 0;
|
||||
char *p_data = NULL;
|
||||
int p_data_len = 0;
|
||||
uint16_t tmp_len = 0;
|
||||
|
||||
if (!llsync_is_connected()) {
|
||||
ble_qiot_log_e("upgrade forbidden, device not connected");
|
||||
return BLE_QIOT_RS_ERR;
|
||||
}
|
||||
|
||||
data_type = (buf[0] == BLE_QIOT_OTA_MSG_REQUEST) ? BLE_QIOT_OTA_MSG_REQUEST : buf[0];
|
||||
slice_flag = (buf[0] == BLE_QIOT_OTA_MSG_REQUEST) ? buf[1] : buf[0];
|
||||
if (data_type >= BLE_QIOT_OTA_MSG_BUTT) {
|
||||
ble_qiot_log_e("invalid data type %d", data_type);
|
||||
return BLE_QIOT_RS_ERR;
|
||||
}
|
||||
p_data = (char *)buf;
|
||||
p_data_len = len;
|
||||
|
||||
// ble_qiot_log_i("ota data type %d, flag %d", data_type, slice_flag);
|
||||
if (BLE_QIOT_IS_SLICE_PACKAGE(slice_flag)) {
|
||||
ble_qiot_log_hex(BLE_QIOT_LOG_LEVEL_INFO, "tlv", p_data, p_data_len);
|
||||
header_len = ble_ota_type_header_len(data_type);
|
||||
ret = ble_package_slice_data(data_type, slice_flag, header_len, buf, len);
|
||||
if (ret < 0) {
|
||||
return BLE_QIOT_RS_ERR;
|
||||
} else if (ret == 0) {
|
||||
if (data_type == BLE_QIOT_OTA_MSG_REQUEST) {
|
||||
tmp_len = HTONS(sg_ble_slice_data.buf_len - header_len);
|
||||
memcpy(&sg_ble_slice_data.buf[1], &tmp_len, sizeof(tmp_len));
|
||||
} else {
|
||||
sg_ble_slice_data.buf[1] = sg_ble_slice_data.buf_len - header_len;
|
||||
}
|
||||
if (data_type == BLE_QIOT_OTA_MSG_DATA) {
|
||||
sg_ble_slice_data.buf[2] = buf[2];
|
||||
}
|
||||
p_data = sg_ble_slice_data.buf;
|
||||
p_data_len = sg_ble_slice_data.buf_len;
|
||||
} else if (ret > 0) {
|
||||
return BLE_QIOT_RS_OK;
|
||||
}
|
||||
}
|
||||
|
||||
// ble_qiot_log_hex(BLE_QIOT_LOG_LEVEL_INFO, "tlv", p_data, p_data_len);
|
||||
switch (data_type) {
|
||||
case BLE_QIOT_OTA_MSG_REQUEST:
|
||||
clk_set("sys", BLE_QIOT_OTA_HZ);
|
||||
|
||||
#if (!defined CONFIG_TRANSFER_ENABLE)
|
||||
update_start_exit_sniff();
|
||||
#endif
|
||||
set_ota_status(1);
|
||||
ret = ble_ota_request_handle(p_data + 3, p_data_len);
|
||||
break;
|
||||
case BLE_QIOT_OTA_MSG_DATA:
|
||||
ret = ble_ota_data_handle(p_data + 2, p_data_len - 2);
|
||||
break;
|
||||
case BLE_QIOT_OTA_MSG_END:
|
||||
clk_set("sys", BT_NORMAL_HZ);
|
||||
set_ota_status(0);
|
||||
ret = ble_ota_file_end_handle();
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
memset(&sg_ble_slice_data, 0, sizeof(sg_ble_slice_data));
|
||||
|
||||
return ret;
|
||||
}
|
||||
#else
|
||||
int ble_ota_msg_handle(const char *buf, uint16_t len)
|
||||
{
|
||||
return BLE_QIOT_RS_OK;
|
||||
}
|
||||
#endif //BLE_QIOT_SUPPORT_OTA
|
||||
|
||||
#endif //BLE_QIOT_LLSYNC_STANDARD
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
@ -0,0 +1,264 @@
|
||||
/*
|
||||
* Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved.
|
||||
* Licensed under the MIT License (the "License"); you may not use this file except in
|
||||
* compliance with the License. You may obtain a copy of the License at
|
||||
* http://opensource.org/licenses/MIT
|
||||
* 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.
|
||||
*
|
||||
*/
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include "ble_qiot_template.h"
|
||||
|
||||
#include <printf.h>
|
||||
//#include <stdbool.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "ble_qiot_export.h"
|
||||
#include "ble_qiot_common.h"
|
||||
#include "ble_qiot_param_check.h"
|
||||
#include "ble_qiot_llsync_event.h"
|
||||
#include "ble_qiot_service.h"
|
||||
#include "ble_qiot_llsync_device.h"
|
||||
#include "gpio.h"
|
||||
|
||||
static uint8_t LL_led = 0;
|
||||
#define LLSYNC_SWITCH_PIN IO_PORTA_01
|
||||
static int ble_property_power_switch_set(const char *data, uint16_t len)
|
||||
{
|
||||
printf("ble_property_power_switch_set led to %d\n", data[0]);
|
||||
LL_led = data[0];
|
||||
gpio_write(LLSYNC_SWITCH_PIN, LL_led);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int ble_property_power_switch_get(char *data, uint16_t buf_len)
|
||||
{
|
||||
printf("ble_property_power_switch_get, led state is %d\n", LL_led);
|
||||
data[0] = LL_led;
|
||||
return sizeof(uint8_t);
|
||||
}
|
||||
|
||||
static ble_property_t sg_ble_property_array[BLE_QIOT_PROPERTY_ID_BUTT] = {
|
||||
{ble_property_power_switch_set, ble_property_power_switch_get, BLE_QIOT_PROPERTY_AUTH_RW, BLE_QIOT_DATA_TYPE_BOOL},
|
||||
};
|
||||
|
||||
ble_qiot_ret_status_t ble_event_report_device_switch_state(u8 led_state)
|
||||
{
|
||||
char device_info[2] = {0};
|
||||
|
||||
device_info[0] = BLE_QIOT_PROPERTY_ID_POWER_SWITCH;
|
||||
device_info[1] = led_state;
|
||||
|
||||
return ble_event_notify(BLE_QIOT_EVENT_UP_PROPERTY_REPORT, NULL, 0, device_info, sizeof(device_info));
|
||||
}
|
||||
|
||||
void ll_sync_led_switch(void)
|
||||
{
|
||||
LL_led = !LL_led;
|
||||
|
||||
printf("ll_sync set led to %d\n", LL_led);
|
||||
gpio_write(LLSYNC_SWITCH_PIN, LL_led);
|
||||
ble_event_report_device_switch_state(LL_led);
|
||||
}
|
||||
|
||||
void ll_sync_unbind(void)
|
||||
{
|
||||
printf("ll_sync factory data reset\n");
|
||||
ble_unbind_write_result();
|
||||
}
|
||||
|
||||
void llsync_device_state_sync(void)
|
||||
{
|
||||
printf("llsync_device_state_sync, led = %d\n", LL_led);
|
||||
ble_event_report_device_switch_state(LL_led);
|
||||
}
|
||||
|
||||
static bool ble_check_space_enough_by_type(uint8_t type, uint16_t left_size)
|
||||
{
|
||||
switch (type) {
|
||||
case BLE_QIOT_DATA_TYPE_BOOL:
|
||||
return left_size >= sizeof(uint8_t);
|
||||
case BLE_QIOT_DATA_TYPE_INT:
|
||||
case BLE_QIOT_DATA_TYPE_FLOAT:
|
||||
case BLE_QIOT_DATA_TYPE_TIME:
|
||||
return left_size >= sizeof(uint32_t);
|
||||
case BLE_QIOT_DATA_TYPE_ENUM:
|
||||
return left_size >= sizeof(uint16_t);
|
||||
default:
|
||||
// string length is unknow, default true
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
static uint16_t ble_check_ret_value_by_type(uint8_t type, uint16_t buf_len, uint16_t ret_val)
|
||||
{
|
||||
switch (type) {
|
||||
case BLE_QIOT_DATA_TYPE_BOOL:
|
||||
return ret_val <= sizeof(uint8_t);
|
||||
case BLE_QIOT_DATA_TYPE_INT:
|
||||
case BLE_QIOT_DATA_TYPE_FLOAT:
|
||||
case BLE_QIOT_DATA_TYPE_TIME:
|
||||
return ret_val <= sizeof(uint32_t);
|
||||
case BLE_QIOT_DATA_TYPE_ENUM:
|
||||
return ret_val <= sizeof(uint16_t);
|
||||
default:
|
||||
// string length is unknow, default true
|
||||
return ret_val <= buf_len;
|
||||
}
|
||||
}
|
||||
|
||||
uint8_t ble_get_property_type_by_id(uint8_t id)
|
||||
{
|
||||
if (id >= BLE_QIOT_PROPERTY_ID_BUTT) {
|
||||
ble_qiot_log_e("invalid property id %d", id);
|
||||
return BLE_QIOT_DATA_TYPE_BUTT;
|
||||
}
|
||||
return sg_ble_property_array[id].type;
|
||||
}
|
||||
|
||||
int ble_user_property_set_data(const e_ble_tlv *tlv)
|
||||
{
|
||||
POINTER_SANITY_CHECK(tlv, BLE_QIOT_RS_ERR_PARA);
|
||||
if (tlv->id >= BLE_QIOT_PROPERTY_ID_BUTT) {
|
||||
ble_qiot_log_e("invalid property id %d", tlv->id);
|
||||
return BLE_QIOT_RS_ERR;
|
||||
}
|
||||
|
||||
if (NULL != sg_ble_property_array[tlv->id].set_cb) {
|
||||
if (0 != sg_ble_property_array[tlv->id].set_cb(tlv->val, tlv->len)) {
|
||||
ble_qiot_log_e("set property id %d failed", tlv->id);
|
||||
return BLE_QIOT_RS_ERR;
|
||||
} else {
|
||||
return BLE_QIOT_RS_OK;
|
||||
}
|
||||
}
|
||||
ble_qiot_log_e("invalid set callback, id %d", tlv->id);
|
||||
|
||||
return BLE_QIOT_RS_ERR;
|
||||
}
|
||||
|
||||
int ble_user_property_get_data_by_id(uint8_t id, char *buf, uint16_t buf_len)
|
||||
{
|
||||
int ret_len = 0;
|
||||
|
||||
POINTER_SANITY_CHECK(buf, BLE_QIOT_RS_ERR_PARA);
|
||||
if (id >= BLE_QIOT_PROPERTY_ID_BUTT) {
|
||||
ble_qiot_log_e("invalid property id %d", id);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (NULL != sg_ble_property_array[id].get_cb) {
|
||||
if (!ble_check_space_enough_by_type(sg_ble_property_array[id].type, buf_len)) {
|
||||
ble_qiot_log_e("not enough space get property id %d data", id);
|
||||
return -1;
|
||||
}
|
||||
ret_len = sg_ble_property_array[id].get_cb(buf, buf_len);
|
||||
if (ret_len < 0) {
|
||||
ble_qiot_log_e("get property id %d data failed", id);
|
||||
return -1;
|
||||
} else {
|
||||
if (ble_check_ret_value_by_type(sg_ble_property_array[id].type, buf_len, ret_len)) {
|
||||
return ret_len;
|
||||
} else {
|
||||
ble_qiot_log_e("property id %d length invalid", id);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
ble_qiot_log_e("invalid callback, property id %d", id);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int ble_user_property_report_reply_handle(uint8_t result)
|
||||
{
|
||||
ble_qiot_log_d("report reply result %d", result);
|
||||
|
||||
return BLE_QIOT_RS_OK;
|
||||
}
|
||||
|
||||
int ble_user_property_struct_handle(const char *in_buf, uint16_t buf_len, ble_property_t struct_arr[], uint8_t arr_size)
|
||||
{
|
||||
uint16_t parse_len = 0;
|
||||
uint16_t ret_len = 0;
|
||||
e_ble_tlv tlv;
|
||||
|
||||
while (parse_len < buf_len) {
|
||||
memset(&tlv, 0, sizeof(e_ble_tlv));
|
||||
ret_len = ble_lldata_parse_tlv(in_buf + parse_len, buf_len - parse_len, &tlv);
|
||||
parse_len += ret_len;
|
||||
if (parse_len > buf_len) {
|
||||
ble_qiot_log_e("parse struct failed");
|
||||
return parse_len;
|
||||
}
|
||||
|
||||
if (tlv.id >= arr_size) {
|
||||
ble_qiot_log_e("invalid array index %d", tlv.id);
|
||||
return parse_len;
|
||||
}
|
||||
if (NULL == struct_arr[tlv.id].set_cb) {
|
||||
ble_qiot_log_e("invalid member id %d", tlv.id);
|
||||
return parse_len;
|
||||
}
|
||||
if (BLE_QIOT_RS_OK != struct_arr[tlv.id].set_cb(tlv.val, tlv.len)) {
|
||||
ble_qiot_log_e("user handle property error, member id %d, type %d, len %d", tlv.id, tlv.type, tlv.len);
|
||||
return parse_len;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int ble_user_property_struct_get_data(char *in_buf, uint16_t buf_len, ble_property_t struct_arr[], uint8_t arr_size)
|
||||
{
|
||||
uint8_t property_id = 0;
|
||||
uint8_t property_type = 0;
|
||||
int property_len = 0;
|
||||
char *data_buf = in_buf;
|
||||
uint16_t data_len = 0;
|
||||
uint16_t string_len = 0;
|
||||
|
||||
for (property_id = 0; property_id < arr_size; property_id++) {
|
||||
property_type = struct_arr[property_id].type;
|
||||
if (property_type >= BLE_QIOT_DATA_TYPE_BUTT) {
|
||||
ble_qiot_log_e("member id %d type %d invalid", property_id, property_type);
|
||||
return BLE_QIOT_RS_ERR;
|
||||
}
|
||||
data_buf[data_len++] = BLE_QIOT_PACKAGE_TLV_HEAD(property_type, property_id);
|
||||
if (BLE_QIOT_DATA_TYPE_STRING == property_type) {
|
||||
// reserved 2 bytes for string length
|
||||
property_len = struct_arr[property_id].get_cb((char *)data_buf + data_len + 2, buf_len - data_len - 2);
|
||||
} else {
|
||||
property_len = struct_arr[property_id].get_cb((char *)data_buf + data_len, buf_len - data_len);
|
||||
}
|
||||
if (property_len < 0) {
|
||||
ble_qiot_log_e("too long data, member id %d, data length %d", property_id, data_len);
|
||||
return BLE_QIOT_RS_ERR;
|
||||
} else if (property_len == 0) {
|
||||
// no data to post
|
||||
data_len--;
|
||||
data_buf[data_len] = '0';
|
||||
ble_qiot_log_d("member id %d no data to post", property_id);
|
||||
} else {
|
||||
if (BLE_QIOT_DATA_TYPE_STRING == property_type) {
|
||||
string_len = HTONS(property_len);
|
||||
memcpy(data_buf + data_len, &string_len, sizeof(uint16_t));
|
||||
data_len += sizeof(uint16_t);
|
||||
}
|
||||
data_len += property_len;
|
||||
}
|
||||
}
|
||||
|
||||
return data_len;
|
||||
}
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
@ -0,0 +1,194 @@
|
||||
/*
|
||||
* Tencent is pleased to support the open source community by making IoT Hub available.
|
||||
* Copyright (C) 2018-2020 THL A29 Limited, a Tencent company. All rights reserved.
|
||||
|
||||
* Licensed under the MIT License (the "License"); you may not use this file except in
|
||||
* compliance with the License. You may obtain a copy of the License at
|
||||
* http://opensource.org/licenses/MIT
|
||||
|
||||
* 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.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include "ble_qiot_utils_base64.h"
|
||||
#include "ble_qiot_export.h"
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
static const unsigned char base64_enc_map[64] = {
|
||||
'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V',
|
||||
'W', 'X', 'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r',
|
||||
's', 't', 'u', 'v', 'w', 'x', 'y', 'z', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '+', '/'
|
||||
};
|
||||
|
||||
static const unsigned char base64_dec_map[128] = {
|
||||
127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127,
|
||||
127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 62,
|
||||
127, 127, 127, 63, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 127, 127, 127, 64, 127, 127, 127, 0,
|
||||
1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22,
|
||||
23, 24, 25, 127, 127, 127, 127, 127, 127, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38,
|
||||
39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 127, 127, 127, 127, 127
|
||||
};
|
||||
|
||||
#define BASE64_SIZE_T_MAX ((size_t)-1) /* SIZE_T_MAX is not standard */
|
||||
|
||||
ble_qiot_ret_status_t qcloud_iot_utils_base64encode(unsigned char *dst, size_t dlen, size_t *olen,
|
||||
const unsigned char *src, size_t slen)
|
||||
{
|
||||
size_t i, n;
|
||||
unsigned char *p;
|
||||
|
||||
if (slen == 0) {
|
||||
*olen = 0;
|
||||
return (BLE_QIOT_RS_OK);
|
||||
}
|
||||
|
||||
n = slen / 3 + (slen % 3 != 0);
|
||||
|
||||
if (n > (BASE64_SIZE_T_MAX - 1) / 4) {
|
||||
*olen = BASE64_SIZE_T_MAX;
|
||||
return (BLE_QIOT_RS_ERR);
|
||||
}
|
||||
|
||||
n *= 4;
|
||||
|
||||
if ((dlen < n + 1) || (NULL == dst)) {
|
||||
*olen = n + 1;
|
||||
return (BLE_QIOT_RS_ERR);
|
||||
}
|
||||
|
||||
n = (slen / 3) * 3;
|
||||
|
||||
int C1, C2, C3;
|
||||
for (i = 0, p = dst; i < n; i += 3) {
|
||||
C1 = *src++;
|
||||
C2 = *src++;
|
||||
C3 = *src++;
|
||||
|
||||
*p++ = base64_enc_map[(C1 >> 2) & 0x3F];
|
||||
*p++ = base64_enc_map[(((C1 & 3) << 4) + (C2 >> 4)) & 0x3F];
|
||||
*p++ = base64_enc_map[(((C2 & 15) << 2) + (C3 >> 6)) & 0x3F];
|
||||
*p++ = base64_enc_map[C3 & 0x3F];
|
||||
}
|
||||
|
||||
if (i < slen) {
|
||||
C1 = *src++;
|
||||
C2 = ((i + 1) < slen) ? *src++ : 0;
|
||||
|
||||
*p++ = base64_enc_map[(C1 >> 2) & 0x3F];
|
||||
*p++ = base64_enc_map[(((C1 & 3) << 4) + (C2 >> 4)) & 0x3F];
|
||||
|
||||
if ((i + 1) < slen) {
|
||||
*p++ = base64_enc_map[((C2 & 15) << 2) & 0x3F];
|
||||
} else {
|
||||
*p++ = '=';
|
||||
}
|
||||
|
||||
*p++ = '=';
|
||||
}
|
||||
|
||||
*olen = p - dst;
|
||||
*p = 0;
|
||||
|
||||
return (BLE_QIOT_RS_OK);
|
||||
}
|
||||
|
||||
ble_qiot_ret_status_t qcloud_iot_utils_base64decode(unsigned char *dst, size_t dlen, size_t *olen,
|
||||
const unsigned char *src, size_t slen)
|
||||
{
|
||||
size_t i, n;
|
||||
uint32_t j, x;
|
||||
unsigned char *p;
|
||||
|
||||
/* First pass: check for validity and get output length */
|
||||
for (i = n = j = 0; i < slen; i++) {
|
||||
/* Skip spaces before checking for EOL */
|
||||
x = 0;
|
||||
while (i < slen && src[i] == ' ') {
|
||||
++i;
|
||||
++x;
|
||||
}
|
||||
|
||||
/* Spaces at end of buffer are OK */
|
||||
if (i == slen) {
|
||||
break;
|
||||
}
|
||||
|
||||
if ((slen - i) >= 2 && src[i] == '\r' && src[i + 1] == '\n') {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (src[i] == '\n') {
|
||||
continue;
|
||||
}
|
||||
|
||||
/* Space inside a line is an error */
|
||||
if (x != 0) {
|
||||
return (BLE_QIOT_RS_ERR);
|
||||
}
|
||||
|
||||
if (src[i] == '=' && ++j > 2) {
|
||||
return (BLE_QIOT_RS_ERR);
|
||||
}
|
||||
|
||||
if (src[i] > 127 || base64_dec_map[src[i]] == 127) {
|
||||
return (BLE_QIOT_RS_ERR);
|
||||
}
|
||||
|
||||
if (base64_dec_map[src[i]] < 64 && j != 0) {
|
||||
return (BLE_QIOT_RS_ERR);
|
||||
}
|
||||
|
||||
n++;
|
||||
}
|
||||
|
||||
if (n == 0) {
|
||||
*olen = 0;
|
||||
return (BLE_QIOT_RS_OK);
|
||||
}
|
||||
|
||||
n = ((n * 6) + 7) >> 3;
|
||||
n -= j;
|
||||
|
||||
if (dst == NULL || dlen < n) {
|
||||
*olen = n;
|
||||
return (BLE_QIOT_RS_ERR);
|
||||
}
|
||||
|
||||
for (j = 3, n = x = 0, p = dst; i > 0; i--, src++) {
|
||||
if (*src == '\r' || *src == '\n' || *src == ' ') {
|
||||
continue;
|
||||
}
|
||||
|
||||
j -= (base64_dec_map[*src] == 64);
|
||||
x = (x << 6) | (base64_dec_map[*src] & 0x3F);
|
||||
|
||||
if (++n == 4) {
|
||||
n = 0;
|
||||
if (j > 0) {
|
||||
*p++ = (unsigned char)(x >> 16);
|
||||
}
|
||||
if (j > 1) {
|
||||
*p++ = (unsigned char)(x >> 8);
|
||||
}
|
||||
if (j > 2) {
|
||||
*p++ = (unsigned char)(x);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
*olen = p - dst;
|
||||
|
||||
return (BLE_QIOT_RS_OK);
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
@ -0,0 +1,76 @@
|
||||
/*
|
||||
* Tencent is pleased to support the open source community by making IoT Hub available.
|
||||
* Copyright (C) 2018-2020 THL A29 Limited, a Tencent company. All rights reserved.
|
||||
|
||||
* Licensed under the MIT License (the "License"); you may not use this file except in
|
||||
* compliance with the License. You may obtain a copy of the License at
|
||||
* http://opensource.org/licenses/MIT
|
||||
|
||||
* 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.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include "ble_qiot_crc.h"
|
||||
|
||||
#include <printf.h>
|
||||
|
||||
const uint32_t crc32_tab[] = {
|
||||
0x00000000, 0x77073096, 0xee0e612c, 0x990951ba, 0x076dc419, 0x706af48f, 0xe963a535, 0x9e6495a3, 0x0edb8832,
|
||||
0x79dcb8a4, 0xe0d5e91e, 0x97d2d988, 0x09b64c2b, 0x7eb17cbd, 0xe7b82d07, 0x90bf1d91, 0x1db71064, 0x6ab020f2,
|
||||
0xf3b97148, 0x84be41de, 0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7, 0x136c9856, 0x646ba8c0, 0xfd62f97a,
|
||||
0x8a65c9ec, 0x14015c4f, 0x63066cd9, 0xfa0f3d63, 0x8d080df5, 0x3b6e20c8, 0x4c69105e, 0xd56041e4, 0xa2677172,
|
||||
0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b, 0x35b5a8fa, 0x42b2986c, 0xdbbbc9d6, 0xacbcf940, 0x32d86ce3,
|
||||
0x45df5c75, 0xdcd60dcf, 0xabd13d59, 0x26d930ac, 0x51de003a, 0xc8d75180, 0xbfd06116, 0x21b4f4b5, 0x56b3c423,
|
||||
0xcfba9599, 0xb8bda50f, 0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924, 0x2f6f7c87, 0x58684c11, 0xc1611dab,
|
||||
0xb6662d3d, 0x76dc4190, 0x01db7106, 0x98d220bc, 0xefd5102a, 0x71b18589, 0x06b6b51f, 0x9fbfe4a5, 0xe8b8d433,
|
||||
0x7807c9a2, 0x0f00f934, 0x9609a88e, 0xe10e9818, 0x7f6a0dbb, 0x086d3d2d, 0x91646c97, 0xe6635c01, 0x6b6b51f4,
|
||||
0x1c6c6162, 0x856530d8, 0xf262004e, 0x6c0695ed, 0x1b01a57b, 0x8208f4c1, 0xf50fc457, 0x65b0d9c6, 0x12b7e950,
|
||||
0x8bbeb8ea, 0xfcb9887c, 0x62dd1ddf, 0x15da2d49, 0x8cd37cf3, 0xfbd44c65, 0x4db26158, 0x3ab551ce, 0xa3bc0074,
|
||||
0xd4bb30e2, 0x4adfa541, 0x3dd895d7, 0xa4d1c46d, 0xd3d6f4fb, 0x4369e96a, 0x346ed9fc, 0xad678846, 0xda60b8d0,
|
||||
0x44042d73, 0x33031de5, 0xaa0a4c5f, 0xdd0d7cc9, 0x5005713c, 0x270241aa, 0xbe0b1010, 0xc90c2086, 0x5768b525,
|
||||
0x206f85b3, 0xb966d409, 0xce61e49f, 0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4, 0x59b33d17, 0x2eb40d81,
|
||||
0xb7bd5c3b, 0xc0ba6cad, 0xedb88320, 0x9abfb3b6, 0x03b6e20c, 0x74b1d29a, 0xead54739, 0x9dd277af, 0x04db2615,
|
||||
0x73dc1683, 0xe3630b12, 0x94643b84, 0x0d6d6a3e, 0x7a6a5aa8, 0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1,
|
||||
0xf00f9344, 0x8708a3d2, 0x1e01f268, 0x6906c2fe, 0xf762575d, 0x806567cb, 0x196c3671, 0x6e6b06e7, 0xfed41b76,
|
||||
0x89d32be0, 0x10da7a5a, 0x67dd4acc, 0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5, 0xd6d6a3e8, 0xa1d1937e,
|
||||
0x38d8c2c4, 0x4fdff252, 0xd1bb67f1, 0xa6bc5767, 0x3fb506dd, 0x48b2364b, 0xd80d2bda, 0xaf0a1b4c, 0x36034af6,
|
||||
0x41047a60, 0xdf60efc3, 0xa867df55, 0x316e8eef, 0x4669be79, 0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236,
|
||||
0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f, 0xc5ba3bbe, 0xb2bd0b28, 0x2bb45a92, 0x5cb36a04, 0xc2d7ffa7,
|
||||
0xb5d0cf31, 0x2cd99e8b, 0x5bdeae1d, 0x9b64c2b0, 0xec63f226, 0x756aa39c, 0x026d930a, 0x9c0906a9, 0xeb0e363f,
|
||||
0x72076785, 0x05005713, 0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38, 0x92d28e9b, 0xe5d5be0d, 0x7cdcefb7,
|
||||
0x0bdbdf21, 0x86d3d2d4, 0xf1d4e242, 0x68ddb3f8, 0x1fda836e, 0x81be16cd, 0xf6b9265b, 0x6fb077e1, 0x18b74777,
|
||||
0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c, 0x8f659eff, 0xf862ae69, 0x616bffd3, 0x166ccf45, 0xa00ae278,
|
||||
0xd70dd2ee, 0x4e048354, 0x3903b3c2, 0xa7672661, 0xd06016f7, 0x4969474d, 0x3e6e77db, 0xaed16a4a, 0xd9d65adc,
|
||||
0x40df0b66, 0x37d83bf0, 0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9, 0xbdbdf21c, 0xcabac28a, 0x53b39330,
|
||||
0x24b4a3a6, 0xbad03605, 0xcdd70693, 0x54de5729, 0x23d967bf, 0xb3667a2e, 0xc4614ab8, 0x5d681b02, 0x2a6f2b94,
|
||||
0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, 0x2d02ef8d
|
||||
};
|
||||
void ble_qiot_crc32_init(void)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
uint32_t ble_qiot_crc32(uint32_t crc, const uint8_t *buf, int len)
|
||||
{
|
||||
const uint8_t *p;
|
||||
|
||||
p = buf;
|
||||
crc = crc ^ ~0U;
|
||||
|
||||
while (len--) {
|
||||
crc = crc32_tab[(crc ^ *p++) & 0xFF] ^ (crc >> 8);
|
||||
}
|
||||
|
||||
return crc ^ ~0U;
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
@ -0,0 +1,83 @@
|
||||
/*
|
||||
* Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved.
|
||||
* Licensed under the MIT License (the "License"); you may not use this file except in
|
||||
* compliance with the License. You may obtain a copy of the License at
|
||||
* http://opensource.org/licenses/MIT
|
||||
* 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.
|
||||
*
|
||||
*/
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#include "ble_qiot_log.h"
|
||||
#include "ble_qiot_sha1.h"
|
||||
#include "ble_qiot_hmac.h"
|
||||
|
||||
#define KEY_IOPAD_SIZE 64
|
||||
|
||||
int8_t utils_hb2hex(uint8_t hb)
|
||||
{
|
||||
hb = hb & 0xF;
|
||||
return (int8_t)(hb < 10 ? '0' + hb : hb - 10 + 'a');
|
||||
}
|
||||
|
||||
void utils_hmac_sha1(const char *msg, int msg_len, char *digest, const char *key, int key_len)
|
||||
{
|
||||
if ((NULL == msg) || (NULL == digest) || (NULL == key)) {
|
||||
ble_qiot_log_e("parameter is Null,failed!");
|
||||
return;
|
||||
}
|
||||
|
||||
if (key_len > KEY_IOPAD_SIZE) {
|
||||
ble_qiot_log_e("key_len > size(%d) of array", KEY_IOPAD_SIZE);
|
||||
return;
|
||||
}
|
||||
|
||||
iot_sha1_context context;
|
||||
unsigned char k_ipad[KEY_IOPAD_SIZE]; /* inner padding - key XORd with ipad */
|
||||
unsigned char k_opad[KEY_IOPAD_SIZE]; /* outer padding - key XORd with opad */
|
||||
unsigned char out[SHA1_DIGEST_SIZE];
|
||||
int i;
|
||||
|
||||
/* start out by storing key in pads */
|
||||
memset(k_ipad, 0, sizeof(k_ipad));
|
||||
memset(k_opad, 0, sizeof(k_opad));
|
||||
memcpy(k_ipad, key, key_len);
|
||||
memcpy(k_opad, key, key_len);
|
||||
|
||||
/* XOR key with ipad and opad values */
|
||||
for (i = 0; i < KEY_IOPAD_SIZE; i++) {
|
||||
k_ipad[i] ^= 0x36;
|
||||
k_opad[i] ^= 0x5c;
|
||||
}
|
||||
|
||||
/* perform inner SHA */
|
||||
utils_sha1_init(&context); /* init context for 1st pass */
|
||||
utils_sha1_starts(&context); /* setup context for 1st pass */
|
||||
utils_sha1_update(&context, k_ipad, KEY_IOPAD_SIZE); /* start with inner pad */
|
||||
utils_sha1_update(&context, (unsigned char *)msg, msg_len); /* then text of datagram */
|
||||
utils_sha1_finish(&context, out); /* finish up 1st pass */
|
||||
|
||||
/* perform outer SHA */
|
||||
utils_sha1_init(&context); /* init context for 2nd pass */
|
||||
utils_sha1_starts(&context); /* setup context for 2nd pass */
|
||||
utils_sha1_update(&context, k_opad, KEY_IOPAD_SIZE); /* start with outer pad */
|
||||
utils_sha1_update(&context, out, SHA1_DIGEST_SIZE); /* then results of 1st hash */
|
||||
utils_sha1_finish(&context, out); /* finish up 2nd pass */
|
||||
|
||||
memcpy(digest, out, SHA1_DIGEST_SIZE);
|
||||
/* for (i = 0; i < SHA1_DIGEST_SIZE; ++i) {
|
||||
digest[i * 2] = utils_hb2hex(out[i] >> 4);
|
||||
digest[i * 2 + 1] = utils_hb2hex(out[i]);
|
||||
}*/
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
@ -0,0 +1,84 @@
|
||||
/*
|
||||
* Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved.
|
||||
* Licensed under the MIT License (the "License"); you may not use this file except in
|
||||
* compliance with the License. You may obtain a copy of the License at
|
||||
* http://opensource.org/licenses/MIT
|
||||
* 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.
|
||||
*
|
||||
*/
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include "ble_qiot_log.h"
|
||||
|
||||
#include <stdint.h>
|
||||
#include <printf.h>
|
||||
#include <string.h>
|
||||
|
||||
#define HEX_DUMP_BYTE_PER_LINE 16
|
||||
|
||||
e_ble_qiot_log_level g_log_level = BLE_QIOT_LOG_LEVEL_INFO;
|
||||
|
||||
void ble_qiot_set_log_level(e_ble_qiot_log_level level)
|
||||
{
|
||||
g_log_level = level;
|
||||
return;
|
||||
}
|
||||
|
||||
#if !BLE_QIOT_USER_DEFINE_HEXDUMP
|
||||
void ble_qiot_log_hex(e_ble_qiot_log_level level, const char *hex_name, const char *data, uint32_t data_len)
|
||||
{
|
||||
char buf[HEX_DUMP_BYTE_PER_LINE * 5] = {0};
|
||||
int line_count = 0, line = 0, byte = 0, rest = 0, start_byte = 0;
|
||||
|
||||
if (g_log_level < level) {
|
||||
return;
|
||||
}
|
||||
|
||||
line_count = data_len / HEX_DUMP_BYTE_PER_LINE;
|
||||
if (data_len % HEX_DUMP_BYTE_PER_LINE) {
|
||||
line_count += 1;
|
||||
}
|
||||
|
||||
ble_qiot_log_raw("\r\nble qiot dump: %s, length: %d\r\n", hex_name, data_len);
|
||||
ble_qiot_log_raw(" 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15\r\n");
|
||||
ble_qiot_log_raw("===============================================\r\n");
|
||||
for (line = 0; line < line_count; line++) {
|
||||
start_byte = line * HEX_DUMP_BYTE_PER_LINE;
|
||||
if (data_len - start_byte < HEX_DUMP_BYTE_PER_LINE) {
|
||||
rest = data_len % HEX_DUMP_BYTE_PER_LINE;
|
||||
} else {
|
||||
rest = HEX_DUMP_BYTE_PER_LINE;
|
||||
}
|
||||
|
||||
for (byte = 0; byte < HEX_DUMP_BYTE_PER_LINE; byte++) {
|
||||
if (byte < rest) {
|
||||
sprintf(&buf[byte * 3], "%02X ", data[start_byte + byte]);
|
||||
} else {
|
||||
sprintf(&buf[byte * 3], " ");
|
||||
}
|
||||
}
|
||||
|
||||
sprintf(&buf[HEX_DUMP_BYTE_PER_LINE * 3], "| ");
|
||||
for (byte = 0; byte < rest; byte++) {
|
||||
if (data[start_byte + byte] >= ' ' && data[start_byte + byte] <= '~') {
|
||||
buf[HEX_DUMP_BYTE_PER_LINE * 3 + 2 + byte] = data[start_byte + byte];
|
||||
} else {
|
||||
buf[HEX_DUMP_BYTE_PER_LINE * 3 + 2 + byte] = '.';
|
||||
}
|
||||
}
|
||||
sprintf(&buf[HEX_DUMP_BYTE_PER_LINE * 3 + 2 + rest], "\r\n");
|
||||
|
||||
ble_qiot_log_raw("%s", buf); // do not use printf(buf), that cause '%' transfer next character
|
||||
}
|
||||
ble_qiot_log_raw("\r\n");
|
||||
}
|
||||
#endif // BLE_QIOT_USER_DEFINE_HEXDUMP
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
@ -0,0 +1,302 @@
|
||||
/*
|
||||
* Tencent is pleased to support the open source community by making IoT Hub available.
|
||||
* Copyright (C) 2018-2020 THL A29 Limited, a Tencent company. All rights reserved.
|
||||
|
||||
* Licensed under the MIT License (the "License"); you may not use this file except in
|
||||
* compliance with the License. You may obtain a copy of the License at
|
||||
* http://opensource.org/licenses/MIT
|
||||
|
||||
* 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.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include "ble_qiot_md5.h"
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
/* Implementation that should never be optimized out by the compiler */
|
||||
static void _utils_md5_zeroize(void *v, size_t n)
|
||||
{
|
||||
volatile unsigned char *p = v;
|
||||
while (n--) {
|
||||
*p++ = 0;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* 32-bit integer manipulation macros (little endian)
|
||||
*/
|
||||
#ifndef IOT_MD5_GET_UINT32_LE
|
||||
#define IOT_MD5_GET_UINT32_LE(n, b, i) \
|
||||
{ \
|
||||
(n) = ((uint32_t)(b)[(i)]) | ((uint32_t)(b)[(i) + 1] << 8) | ((uint32_t)(b)[(i) + 2] << 16) | \
|
||||
((uint32_t)(b)[(i) + 3] << 24); \
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef IOT_MD5_PUT_UINT32_LE
|
||||
#define IOT_MD5_PUT_UINT32_LE(n, b, i) \
|
||||
{ \
|
||||
(b)[(i)] = (unsigned char)(((n)) & 0xFF); \
|
||||
(b)[(i) + 1] = (unsigned char)(((n) >> 8) & 0xFF); \
|
||||
(b)[(i) + 2] = (unsigned char)(((n) >> 16) & 0xFF); \
|
||||
(b)[(i) + 3] = (unsigned char)(((n) >> 24) & 0xFF); \
|
||||
}
|
||||
#endif
|
||||
|
||||
void utils_md5_init(iot_md5_context *ctx)
|
||||
{
|
||||
memset(ctx, 0, sizeof(iot_md5_context));
|
||||
}
|
||||
|
||||
void utils_md5_free(iot_md5_context *ctx)
|
||||
{
|
||||
if (ctx == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
_utils_md5_zeroize(ctx, sizeof(iot_md5_context));
|
||||
}
|
||||
|
||||
void utils_md5_clone(iot_md5_context *dst, const iot_md5_context *src)
|
||||
{
|
||||
*dst = *src;
|
||||
}
|
||||
|
||||
/*
|
||||
* MD5 context setup
|
||||
*/
|
||||
void utils_md5_starts(iot_md5_context *ctx)
|
||||
{
|
||||
ctx->total[0] = 0;
|
||||
ctx->total[1] = 0;
|
||||
|
||||
ctx->state[0] = 0x67452301;
|
||||
ctx->state[1] = 0xEFCDAB89;
|
||||
ctx->state[2] = 0x98BADCFE;
|
||||
ctx->state[3] = 0x10325476;
|
||||
}
|
||||
|
||||
void utils_md5_process(iot_md5_context *ctx, const unsigned char data[64])
|
||||
{
|
||||
uint32_t X[16], A, B, C, D;
|
||||
|
||||
IOT_MD5_GET_UINT32_LE(X[0], data, 0);
|
||||
IOT_MD5_GET_UINT32_LE(X[1], data, 4);
|
||||
IOT_MD5_GET_UINT32_LE(X[2], data, 8);
|
||||
IOT_MD5_GET_UINT32_LE(X[3], data, 12);
|
||||
IOT_MD5_GET_UINT32_LE(X[4], data, 16);
|
||||
IOT_MD5_GET_UINT32_LE(X[5], data, 20);
|
||||
IOT_MD5_GET_UINT32_LE(X[6], data, 24);
|
||||
IOT_MD5_GET_UINT32_LE(X[7], data, 28);
|
||||
IOT_MD5_GET_UINT32_LE(X[8], data, 32);
|
||||
IOT_MD5_GET_UINT32_LE(X[9], data, 36);
|
||||
IOT_MD5_GET_UINT32_LE(X[10], data, 40);
|
||||
IOT_MD5_GET_UINT32_LE(X[11], data, 44);
|
||||
IOT_MD5_GET_UINT32_LE(X[12], data, 48);
|
||||
IOT_MD5_GET_UINT32_LE(X[13], data, 52);
|
||||
IOT_MD5_GET_UINT32_LE(X[14], data, 56);
|
||||
IOT_MD5_GET_UINT32_LE(X[15], data, 60);
|
||||
|
||||
#define S(x, n) ((x << n) | ((x & 0xFFFFFFFF) >> (32 - n)))
|
||||
|
||||
#define P(a, b, c, d, k, s, t) \
|
||||
{ \
|
||||
a += F(b, c, d) + X[k] + t; \
|
||||
a = S(a, s) + b; \
|
||||
}
|
||||
|
||||
A = ctx->state[0];
|
||||
B = ctx->state[1];
|
||||
C = ctx->state[2];
|
||||
D = ctx->state[3];
|
||||
|
||||
#define F(x, y, z) (z ^ (x & (y ^ z)))
|
||||
|
||||
P(A, B, C, D, 0, 7, 0xD76AA478);
|
||||
P(D, A, B, C, 1, 12, 0xE8C7B756);
|
||||
P(C, D, A, B, 2, 17, 0x242070DB);
|
||||
P(B, C, D, A, 3, 22, 0xC1BDCEEE);
|
||||
P(A, B, C, D, 4, 7, 0xF57C0FAF);
|
||||
P(D, A, B, C, 5, 12, 0x4787C62A);
|
||||
P(C, D, A, B, 6, 17, 0xA8304613);
|
||||
P(B, C, D, A, 7, 22, 0xFD469501);
|
||||
P(A, B, C, D, 8, 7, 0x698098D8);
|
||||
P(D, A, B, C, 9, 12, 0x8B44F7AF);
|
||||
P(C, D, A, B, 10, 17, 0xFFFF5BB1);
|
||||
P(B, C, D, A, 11, 22, 0x895CD7BE);
|
||||
P(A, B, C, D, 12, 7, 0x6B901122);
|
||||
P(D, A, B, C, 13, 12, 0xFD987193);
|
||||
P(C, D, A, B, 14, 17, 0xA679438E);
|
||||
P(B, C, D, A, 15, 22, 0x49B40821);
|
||||
|
||||
#undef F
|
||||
|
||||
#define F(x, y, z) (y ^ (z & (x ^ y)))
|
||||
|
||||
P(A, B, C, D, 1, 5, 0xF61E2562);
|
||||
P(D, A, B, C, 6, 9, 0xC040B340);
|
||||
P(C, D, A, B, 11, 14, 0x265E5A51);
|
||||
P(B, C, D, A, 0, 20, 0xE9B6C7AA);
|
||||
P(A, B, C, D, 5, 5, 0xD62F105D);
|
||||
P(D, A, B, C, 10, 9, 0x02441453);
|
||||
P(C, D, A, B, 15, 14, 0xD8A1E681);
|
||||
P(B, C, D, A, 4, 20, 0xE7D3FBC8);
|
||||
P(A, B, C, D, 9, 5, 0x21E1CDE6);
|
||||
P(D, A, B, C, 14, 9, 0xC33707D6);
|
||||
P(C, D, A, B, 3, 14, 0xF4D50D87);
|
||||
P(B, C, D, A, 8, 20, 0x455A14ED);
|
||||
P(A, B, C, D, 13, 5, 0xA9E3E905);
|
||||
P(D, A, B, C, 2, 9, 0xFCEFA3F8);
|
||||
P(C, D, A, B, 7, 14, 0x676F02D9);
|
||||
P(B, C, D, A, 12, 20, 0x8D2A4C8A);
|
||||
|
||||
#undef F
|
||||
|
||||
#define F(x, y, z) (x ^ y ^ z)
|
||||
|
||||
P(A, B, C, D, 5, 4, 0xFFFA3942);
|
||||
P(D, A, B, C, 8, 11, 0x8771F681);
|
||||
P(C, D, A, B, 11, 16, 0x6D9D6122);
|
||||
P(B, C, D, A, 14, 23, 0xFDE5380C);
|
||||
P(A, B, C, D, 1, 4, 0xA4BEEA44);
|
||||
P(D, A, B, C, 4, 11, 0x4BDECFA9);
|
||||
P(C, D, A, B, 7, 16, 0xF6BB4B60);
|
||||
P(B, C, D, A, 10, 23, 0xBEBFBC70);
|
||||
P(A, B, C, D, 13, 4, 0x289B7EC6);
|
||||
P(D, A, B, C, 0, 11, 0xEAA127FA);
|
||||
P(C, D, A, B, 3, 16, 0xD4EF3085);
|
||||
P(B, C, D, A, 6, 23, 0x04881D05);
|
||||
P(A, B, C, D, 9, 4, 0xD9D4D039);
|
||||
P(D, A, B, C, 12, 11, 0xE6DB99E5);
|
||||
P(C, D, A, B, 15, 16, 0x1FA27CF8);
|
||||
P(B, C, D, A, 2, 23, 0xC4AC5665);
|
||||
|
||||
#undef F
|
||||
|
||||
#define F(x, y, z) (y ^ (x | ~z))
|
||||
|
||||
P(A, B, C, D, 0, 6, 0xF4292244);
|
||||
P(D, A, B, C, 7, 10, 0x432AFF97);
|
||||
P(C, D, A, B, 14, 15, 0xAB9423A7);
|
||||
P(B, C, D, A, 5, 21, 0xFC93A039);
|
||||
P(A, B, C, D, 12, 6, 0x655B59C3);
|
||||
P(D, A, B, C, 3, 10, 0x8F0CCC92);
|
||||
P(C, D, A, B, 10, 15, 0xFFEFF47D);
|
||||
P(B, C, D, A, 1, 21, 0x85845DD1);
|
||||
P(A, B, C, D, 8, 6, 0x6FA87E4F);
|
||||
P(D, A, B, C, 15, 10, 0xFE2CE6E0);
|
||||
P(C, D, A, B, 6, 15, 0xA3014314);
|
||||
P(B, C, D, A, 13, 21, 0x4E0811A1);
|
||||
P(A, B, C, D, 4, 6, 0xF7537E82);
|
||||
P(D, A, B, C, 11, 10, 0xBD3AF235);
|
||||
P(C, D, A, B, 2, 15, 0x2AD7D2BB);
|
||||
P(B, C, D, A, 9, 21, 0xEB86D391);
|
||||
|
||||
#undef F
|
||||
|
||||
ctx->state[0] += A;
|
||||
ctx->state[1] += B;
|
||||
ctx->state[2] += C;
|
||||
ctx->state[3] += D;
|
||||
}
|
||||
|
||||
/*
|
||||
* MD5 process buffer
|
||||
*/
|
||||
void utils_md5_update(iot_md5_context *ctx, const unsigned char *input, unsigned int ilen)
|
||||
{
|
||||
uint32_t fill;
|
||||
uint32_t left;
|
||||
|
||||
if (ilen == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
left = ctx->total[0] & 0x3F;
|
||||
fill = 64 - left;
|
||||
|
||||
ctx->total[0] += (uint32_t)ilen;
|
||||
ctx->total[0] &= 0xFFFFFFFF;
|
||||
|
||||
if (ctx->total[0] < (uint32_t)ilen) {
|
||||
ctx->total[1]++;
|
||||
}
|
||||
|
||||
if (left && ilen >= fill) {
|
||||
memcpy((void *)(ctx->buffer + left), input, fill);
|
||||
utils_md5_process(ctx, ctx->buffer);
|
||||
input += fill;
|
||||
ilen -= fill;
|
||||
left = 0;
|
||||
}
|
||||
|
||||
while (ilen >= 64) {
|
||||
utils_md5_process(ctx, input);
|
||||
input += 64;
|
||||
ilen -= 64;
|
||||
}
|
||||
|
||||
if (ilen > 0) {
|
||||
memcpy((void *)(ctx->buffer + left), input, ilen);
|
||||
}
|
||||
}
|
||||
|
||||
static const unsigned char iot_md5_padding[64] = {0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
|
||||
};
|
||||
|
||||
/*
|
||||
* MD5 final digest
|
||||
*/
|
||||
void utils_md5_finish(iot_md5_context *ctx, unsigned char output[16])
|
||||
{
|
||||
uint32_t last, padn;
|
||||
uint32_t high, low;
|
||||
unsigned char msglen[8];
|
||||
|
||||
high = (ctx->total[0] >> 29) | (ctx->total[1] << 3);
|
||||
low = (ctx->total[0] << 3);
|
||||
|
||||
IOT_MD5_PUT_UINT32_LE(low, msglen, 0);
|
||||
IOT_MD5_PUT_UINT32_LE(high, msglen, 4);
|
||||
|
||||
last = ctx->total[0] & 0x3F;
|
||||
padn = (last < 56) ? (56 - last) : (120 - last);
|
||||
|
||||
utils_md5_update(ctx, iot_md5_padding, padn);
|
||||
utils_md5_update(ctx, msglen, 8);
|
||||
|
||||
IOT_MD5_PUT_UINT32_LE(ctx->state[0], output, 0);
|
||||
IOT_MD5_PUT_UINT32_LE(ctx->state[1], output, 4);
|
||||
IOT_MD5_PUT_UINT32_LE(ctx->state[2], output, 8);
|
||||
IOT_MD5_PUT_UINT32_LE(ctx->state[3], output, 12);
|
||||
}
|
||||
|
||||
/*
|
||||
* output = MD5( input buffer )
|
||||
*/
|
||||
void utils_md5(const unsigned char *input, unsigned int ilen, unsigned char output[16])
|
||||
{
|
||||
iot_md5_context ctx;
|
||||
|
||||
utils_md5_init(&ctx);
|
||||
utils_md5_starts(&ctx);
|
||||
utils_md5_update(&ctx, input, ilen);
|
||||
utils_md5_finish(&ctx, output);
|
||||
utils_md5_free(&ctx);
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
@ -0,0 +1,328 @@
|
||||
/*
|
||||
* Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved.
|
||||
* Licensed under the MIT License (the "License"); you may not use this file except in
|
||||
* compliance with the License. You may obtain a copy of the License at
|
||||
* http://opensource.org/licenses/MIT
|
||||
* 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.
|
||||
*
|
||||
*/
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include "ble_qiot_sha1.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
/* Implementation that should never be optimized out by the compiler */
|
||||
static void utils_sha1_zeroize(void *v, size_t n)
|
||||
{
|
||||
volatile unsigned char *p = v;
|
||||
while (n--) {
|
||||
*p++ = 0;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* 32-bit integer manipulation macros (big endian)
|
||||
*/
|
||||
#ifndef IOT_SHA1_GET_UINT32_BE
|
||||
#define IOT_SHA1_GET_UINT32_BE(n, b, i) \
|
||||
{ \
|
||||
(n) = ((uint32_t)(b)[(i)] << 24) | ((uint32_t)(b)[(i) + 1] << 16) | ((uint32_t)(b)[(i) + 2] << 8) | \
|
||||
((uint32_t)(b)[(i) + 3]); \
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef IOT_SHA1_PUT_UINT32_BE
|
||||
#define IOT_SHA1_PUT_UINT32_BE(n, b, i) \
|
||||
{ \
|
||||
(b)[(i)] = (unsigned char)((n) >> 24); \
|
||||
(b)[(i) + 1] = (unsigned char)((n) >> 16); \
|
||||
(b)[(i) + 2] = (unsigned char)((n) >> 8); \
|
||||
(b)[(i) + 3] = (unsigned char)((n)); \
|
||||
}
|
||||
#endif
|
||||
|
||||
void utils_sha1_init(iot_sha1_context *ctx)
|
||||
{
|
||||
memset(ctx, 0, sizeof(iot_sha1_context));
|
||||
}
|
||||
|
||||
void utils_sha1_free(iot_sha1_context *ctx)
|
||||
{
|
||||
if (ctx == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
utils_sha1_zeroize(ctx, sizeof(iot_sha1_context));
|
||||
}
|
||||
|
||||
void utils_sha1_clone(iot_sha1_context *dst, const iot_sha1_context *src)
|
||||
{
|
||||
*dst = *src;
|
||||
}
|
||||
|
||||
/*
|
||||
* SHA-1 context setup
|
||||
*/
|
||||
void utils_sha1_starts(iot_sha1_context *ctx)
|
||||
{
|
||||
ctx->total[0] = 0;
|
||||
ctx->total[1] = 0;
|
||||
|
||||
ctx->state[0] = 0x67452301;
|
||||
ctx->state[1] = 0xEFCDAB89;
|
||||
ctx->state[2] = 0x98BADCFE;
|
||||
ctx->state[3] = 0x10325476;
|
||||
ctx->state[4] = 0xC3D2E1F0;
|
||||
}
|
||||
|
||||
void utils_sha1_process(iot_sha1_context *ctx, const unsigned char data[64])
|
||||
{
|
||||
uint32_t temp, W[16], A, B, C, D, E;
|
||||
|
||||
IOT_SHA1_GET_UINT32_BE(W[0], data, 0);
|
||||
IOT_SHA1_GET_UINT32_BE(W[1], data, 4);
|
||||
IOT_SHA1_GET_UINT32_BE(W[2], data, 8);
|
||||
IOT_SHA1_GET_UINT32_BE(W[3], data, 12);
|
||||
IOT_SHA1_GET_UINT32_BE(W[4], data, 16);
|
||||
IOT_SHA1_GET_UINT32_BE(W[5], data, 20);
|
||||
IOT_SHA1_GET_UINT32_BE(W[6], data, 24);
|
||||
IOT_SHA1_GET_UINT32_BE(W[7], data, 28);
|
||||
IOT_SHA1_GET_UINT32_BE(W[8], data, 32);
|
||||
IOT_SHA1_GET_UINT32_BE(W[9], data, 36);
|
||||
IOT_SHA1_GET_UINT32_BE(W[10], data, 40);
|
||||
IOT_SHA1_GET_UINT32_BE(W[11], data, 44);
|
||||
IOT_SHA1_GET_UINT32_BE(W[12], data, 48);
|
||||
IOT_SHA1_GET_UINT32_BE(W[13], data, 52);
|
||||
IOT_SHA1_GET_UINT32_BE(W[14], data, 56);
|
||||
IOT_SHA1_GET_UINT32_BE(W[15], data, 60);
|
||||
|
||||
#define S(x, n) ((x << n) | ((x & 0xFFFFFFFF) >> (32 - n)))
|
||||
|
||||
#define R(t) \
|
||||
(temp = W[(t - 3) & 0x0F] ^ W[(t - 8) & 0x0F] ^ W[(t - 14) & 0x0F] ^ W[t & 0x0F], (W[t & 0x0F] = S(temp, 1)))
|
||||
|
||||
#define P(a, b, c, d, e, x) \
|
||||
{ \
|
||||
e += S(a, 5) + F(b, c, d) + K + x; \
|
||||
b = S(b, 30); \
|
||||
}
|
||||
|
||||
A = ctx->state[0];
|
||||
B = ctx->state[1];
|
||||
C = ctx->state[2];
|
||||
D = ctx->state[3];
|
||||
E = ctx->state[4];
|
||||
|
||||
#define F(x, y, z) (z ^ (x & (y ^ z)))
|
||||
#define K 0x5A827999
|
||||
|
||||
P(A, B, C, D, E, W[0]);
|
||||
P(E, A, B, C, D, W[1]);
|
||||
P(D, E, A, B, C, W[2]);
|
||||
P(C, D, E, A, B, W[3]);
|
||||
P(B, C, D, E, A, W[4]);
|
||||
P(A, B, C, D, E, W[5]);
|
||||
P(E, A, B, C, D, W[6]);
|
||||
P(D, E, A, B, C, W[7]);
|
||||
P(C, D, E, A, B, W[8]);
|
||||
P(B, C, D, E, A, W[9]);
|
||||
P(A, B, C, D, E, W[10]);
|
||||
P(E, A, B, C, D, W[11]);
|
||||
P(D, E, A, B, C, W[12]);
|
||||
P(C, D, E, A, B, W[13]);
|
||||
P(B, C, D, E, A, W[14]);
|
||||
P(A, B, C, D, E, W[15]);
|
||||
P(E, A, B, C, D, R(16));
|
||||
P(D, E, A, B, C, R(17));
|
||||
P(C, D, E, A, B, R(18));
|
||||
P(B, C, D, E, A, R(19));
|
||||
|
||||
#undef K
|
||||
#undef F
|
||||
|
||||
#define F(x, y, z) (x ^ y ^ z)
|
||||
#define K 0x6ED9EBA1
|
||||
|
||||
P(A, B, C, D, E, R(20));
|
||||
P(E, A, B, C, D, R(21));
|
||||
P(D, E, A, B, C, R(22));
|
||||
P(C, D, E, A, B, R(23));
|
||||
P(B, C, D, E, A, R(24));
|
||||
P(A, B, C, D, E, R(25));
|
||||
P(E, A, B, C, D, R(26));
|
||||
P(D, E, A, B, C, R(27));
|
||||
P(C, D, E, A, B, R(28));
|
||||
P(B, C, D, E, A, R(29));
|
||||
P(A, B, C, D, E, R(30));
|
||||
P(E, A, B, C, D, R(31));
|
||||
P(D, E, A, B, C, R(32));
|
||||
P(C, D, E, A, B, R(33));
|
||||
P(B, C, D, E, A, R(34));
|
||||
P(A, B, C, D, E, R(35));
|
||||
P(E, A, B, C, D, R(36));
|
||||
P(D, E, A, B, C, R(37));
|
||||
P(C, D, E, A, B, R(38));
|
||||
P(B, C, D, E, A, R(39));
|
||||
|
||||
#undef K
|
||||
#undef F
|
||||
|
||||
#define F(x, y, z) ((x & y) | (z & (x | y)))
|
||||
#define K 0x8F1BBCDC
|
||||
|
||||
P(A, B, C, D, E, R(40));
|
||||
P(E, A, B, C, D, R(41));
|
||||
P(D, E, A, B, C, R(42));
|
||||
P(C, D, E, A, B, R(43));
|
||||
P(B, C, D, E, A, R(44));
|
||||
P(A, B, C, D, E, R(45));
|
||||
P(E, A, B, C, D, R(46));
|
||||
P(D, E, A, B, C, R(47));
|
||||
P(C, D, E, A, B, R(48));
|
||||
P(B, C, D, E, A, R(49));
|
||||
P(A, B, C, D, E, R(50));
|
||||
P(E, A, B, C, D, R(51));
|
||||
P(D, E, A, B, C, R(52));
|
||||
P(C, D, E, A, B, R(53));
|
||||
P(B, C, D, E, A, R(54));
|
||||
P(A, B, C, D, E, R(55));
|
||||
P(E, A, B, C, D, R(56));
|
||||
P(D, E, A, B, C, R(57));
|
||||
P(C, D, E, A, B, R(58));
|
||||
P(B, C, D, E, A, R(59));
|
||||
|
||||
#undef K
|
||||
#undef F
|
||||
|
||||
#define F(x, y, z) (x ^ y ^ z)
|
||||
#define K 0xCA62C1D6
|
||||
|
||||
P(A, B, C, D, E, R(60));
|
||||
P(E, A, B, C, D, R(61));
|
||||
P(D, E, A, B, C, R(62));
|
||||
P(C, D, E, A, B, R(63));
|
||||
P(B, C, D, E, A, R(64));
|
||||
P(A, B, C, D, E, R(65));
|
||||
P(E, A, B, C, D, R(66));
|
||||
P(D, E, A, B, C, R(67));
|
||||
P(C, D, E, A, B, R(68));
|
||||
P(B, C, D, E, A, R(69));
|
||||
P(A, B, C, D, E, R(70));
|
||||
P(E, A, B, C, D, R(71));
|
||||
P(D, E, A, B, C, R(72));
|
||||
P(C, D, E, A, B, R(73));
|
||||
P(B, C, D, E, A, R(74));
|
||||
P(A, B, C, D, E, R(75));
|
||||
P(E, A, B, C, D, R(76));
|
||||
P(D, E, A, B, C, R(77));
|
||||
P(C, D, E, A, B, R(78));
|
||||
P(B, C, D, E, A, R(79));
|
||||
|
||||
#undef K
|
||||
#undef F
|
||||
|
||||
ctx->state[0] += A;
|
||||
ctx->state[1] += B;
|
||||
ctx->state[2] += C;
|
||||
ctx->state[3] += D;
|
||||
ctx->state[4] += E;
|
||||
}
|
||||
|
||||
/*
|
||||
* SHA-1 process buffer
|
||||
*/
|
||||
void utils_sha1_update(iot_sha1_context *ctx, const unsigned char *input, size_t ilen)
|
||||
{
|
||||
size_t fill;
|
||||
uint32_t left;
|
||||
|
||||
if (ilen == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
left = ctx->total[0] & 0x3F;
|
||||
fill = 64 - left;
|
||||
|
||||
ctx->total[0] += (uint32_t)ilen;
|
||||
ctx->total[0] &= 0xFFFFFFFF;
|
||||
|
||||
if (ctx->total[0] < (uint32_t)ilen) {
|
||||
ctx->total[1]++;
|
||||
}
|
||||
|
||||
if (left && ilen >= fill) {
|
||||
memcpy((void *)(ctx->buffer + left), input, fill);
|
||||
utils_sha1_process(ctx, ctx->buffer);
|
||||
input += fill;
|
||||
ilen -= fill;
|
||||
left = 0;
|
||||
}
|
||||
|
||||
while (ilen >= 64) {
|
||||
utils_sha1_process(ctx, input);
|
||||
input += 64;
|
||||
ilen -= 64;
|
||||
}
|
||||
|
||||
if (ilen > 0) {
|
||||
memcpy((void *)(ctx->buffer + left), input, ilen);
|
||||
}
|
||||
}
|
||||
|
||||
static const unsigned char iot_sha1_padding[64] = {0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
|
||||
};
|
||||
|
||||
/*
|
||||
* SHA-1 final digest
|
||||
*/
|
||||
void utils_sha1_finish(iot_sha1_context *ctx, unsigned char output[20])
|
||||
{
|
||||
uint32_t last, padn;
|
||||
uint32_t high, low;
|
||||
unsigned char msglen[8];
|
||||
|
||||
high = (ctx->total[0] >> 29) | (ctx->total[1] << 3);
|
||||
low = (ctx->total[0] << 3);
|
||||
|
||||
IOT_SHA1_PUT_UINT32_BE(high, msglen, 0);
|
||||
IOT_SHA1_PUT_UINT32_BE(low, msglen, 4);
|
||||
|
||||
last = ctx->total[0] & 0x3F;
|
||||
padn = (last < 56) ? (56 - last) : (120 - last);
|
||||
|
||||
utils_sha1_update(ctx, iot_sha1_padding, padn);
|
||||
utils_sha1_update(ctx, msglen, 8);
|
||||
|
||||
IOT_SHA1_PUT_UINT32_BE(ctx->state[0], output, 0);
|
||||
IOT_SHA1_PUT_UINT32_BE(ctx->state[1], output, 4);
|
||||
IOT_SHA1_PUT_UINT32_BE(ctx->state[2], output, 8);
|
||||
IOT_SHA1_PUT_UINT32_BE(ctx->state[3], output, 12);
|
||||
IOT_SHA1_PUT_UINT32_BE(ctx->state[4], output, 16);
|
||||
}
|
||||
|
||||
/*
|
||||
* output = SHA-1( input buffer )
|
||||
*/
|
||||
void utils_sha1(const unsigned char *input, size_t ilen, unsigned char output[20])
|
||||
{
|
||||
iot_sha1_context ctx;
|
||||
|
||||
utils_sha1_init(&ctx);
|
||||
utils_sha1_starts(&ctx);
|
||||
utils_sha1_update(&ctx, input, ilen);
|
||||
utils_sha1_finish(&ctx, output);
|
||||
utils_sha1_free(&ctx);
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
115
apps/common/third_party_profile/common/3th_profile_api.c
Normal file
115
apps/common/third_party_profile/common/3th_profile_api.c
Normal file
@ -0,0 +1,115 @@
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "typedef.h"
|
||||
#include "3th_profile_api.h"
|
||||
#include "bt_tws.h"
|
||||
#include "key_event_deal.h"
|
||||
#include "system/timer.h"
|
||||
#include "bt_common.h"
|
||||
#include "btstack/avctp_user.h"
|
||||
#include "os/os_api.h"
|
||||
|
||||
#if BT_FOR_APP_EN
|
||||
|
||||
#if (OTA_TWS_SAME_TIME_ENABLE && RCSP_ADV_EN && USER_APP_EN)
|
||||
#include "rcsp_adv_tws_ota.h"
|
||||
#endif
|
||||
|
||||
#if (OTA_TWS_SAME_TIME_ENABLE && SMART_BOX_EN)
|
||||
#include "smartbox_update_tws.h"
|
||||
#else
|
||||
#include "update_tws.h"
|
||||
#endif
|
||||
|
||||
static u8 mic_data_type = SOURCE_TYPE;
|
||||
static u8 connect_type = TYPE_NULL;
|
||||
static u8 tws_ble_type = TYPE_NULL;
|
||||
|
||||
void mic_set_data_source(u8 data_type)
|
||||
{
|
||||
mic_data_type = data_type;
|
||||
}
|
||||
|
||||
u8 mic_get_data_source(void)
|
||||
{
|
||||
return mic_data_type;
|
||||
}
|
||||
|
||||
u8 get_ble_connect_type(void)
|
||||
{
|
||||
return tws_ble_type;
|
||||
}
|
||||
|
||||
void set_ble_connect_type(u8 type)
|
||||
{
|
||||
tws_ble_type = type;
|
||||
}
|
||||
|
||||
u8 get_app_connect_type(void)
|
||||
{
|
||||
return connect_type;
|
||||
}
|
||||
|
||||
void set_app_connect_type(u8 type)
|
||||
{
|
||||
connect_type = type;
|
||||
}
|
||||
|
||||
|
||||
#if TCFG_USER_TWS_ENABLE
|
||||
|
||||
int tws_data_to_sibling_send(u8 opcode, u8 *data, u8 len)
|
||||
{
|
||||
u8 send_data[len + 2];
|
||||
printf(">>>>>>>>>>send data to sibling \n");
|
||||
send_data[0] = opcode;
|
||||
send_data[1] = len;
|
||||
memcpy(send_data + 2, data, len);
|
||||
|
||||
return tws_api_send_data_to_sibling(send_data, sizeof(send_data), TWS_FUNC_ID_AI_SYNC);
|
||||
}
|
||||
|
||||
static void __ai_tws_rx_from_sibling(u8 *data)
|
||||
{
|
||||
u8 opcode = data[0];
|
||||
u8 len = data[1];
|
||||
u8 *rx_data = data + 2;
|
||||
|
||||
#if (OTA_TWS_SAME_TIME_ENABLE && (RCSP_BTMATE_EN || RCSP_ADV_EN || SMART_BOX_EN))
|
||||
tws_ota_get_data_from_sibling(opcode, rx_data, len);
|
||||
#endif
|
||||
|
||||
free(data);
|
||||
}
|
||||
|
||||
static void ai_tws_rx_from_sibling(void *_data, u16 len, bool rx)
|
||||
{
|
||||
int err = 0;
|
||||
if (rx) {
|
||||
printf(">>>%s \n", __func__);
|
||||
printf("len :%d\n", len);
|
||||
put_buf(_data, len);
|
||||
u8 *rx_data = malloc(len);
|
||||
memcpy(rx_data, _data, len);
|
||||
|
||||
int msg[4];
|
||||
msg[0] = (int)__ai_tws_rx_from_sibling;
|
||||
msg[1] = 1;
|
||||
msg[2] = (int)rx_data;
|
||||
err = os_taskq_post_type("app_core", Q_CALLBACK, 3, msg);
|
||||
if (err) {
|
||||
printf("tws rx post fail\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//发送给对耳
|
||||
REGISTER_TWS_FUNC_STUB(app_vol_sync_stub) = {
|
||||
.func_id = TWS_FUNC_ID_AI_SYNC,
|
||||
.func = ai_tws_rx_from_sibling,
|
||||
};
|
||||
|
||||
#endif
|
||||
#endif
|
||||
34
apps/common/third_party_profile/common/3th_profile_api.h
Normal file
34
apps/common/third_party_profile/common/3th_profile_api.h
Normal file
@ -0,0 +1,34 @@
|
||||
|
||||
|
||||
#ifndef _3TH_PROFILE_API_H
|
||||
#define _3TH_PROFILE_API_H
|
||||
|
||||
#include<string.h>
|
||||
#include <stdint.h>
|
||||
#include "le_common.h"
|
||||
|
||||
|
||||
#define TYPE_NULL 0
|
||||
#define TYPE_BLE 1
|
||||
#define TYPE_SPP 2
|
||||
|
||||
#define TYPE_MASTER_BLE 3
|
||||
#define TYPE_SLAVE_BLE 4
|
||||
|
||||
#define TYPE_MASTER_SPP 5
|
||||
#define TYPE_SLAVE_SPP 6
|
||||
|
||||
#define SOURCE_TYPE 0
|
||||
#define SINK_TYPE_MASTER 1
|
||||
#define SINK_TYPE_SLAVE 2
|
||||
|
||||
void set_app_connect_type(u8 type);
|
||||
u8 get_app_connect_type(void);
|
||||
u8 get_ble_connect_type(void);
|
||||
void set_ble_connect_type(u8 type);
|
||||
void mic_set_data_source(u8 data_type);
|
||||
u8 mic_get_data_source(void);
|
||||
|
||||
int tws_data_to_sibling_send(u8 opcode, u8 *data, u8 len); //发送数据给对耳
|
||||
|
||||
#endif
|
||||
1485
apps/common/third_party_profile/common/custom_cfg.c
Normal file
1485
apps/common/third_party_profile/common/custom_cfg.c
Normal file
File diff suppressed because it is too large
Load Diff
114
apps/common/third_party_profile/common/custom_cfg.h
Normal file
114
apps/common/third_party_profile/common/custom_cfg.h
Normal file
@ -0,0 +1,114 @@
|
||||
#ifndef _CUSTOM_CFG_H_
|
||||
#define _CUSTOM_CFG_H_
|
||||
|
||||
#include "typedef.h"
|
||||
//#include "hw_cpu.h"
|
||||
#include <string.h>
|
||||
#include "app_config.h"
|
||||
|
||||
#define BT_CONNECTION_VERIFY 0 // 0是校验,1是不校验
|
||||
|
||||
#if (JL_EARPHONE_APP_EN && RCSP_UPDATE_EN)
|
||||
#define VER_INFO_EXT_COUNT 2 //2
|
||||
#else
|
||||
#define VER_INFO_EXT_COUNT 0 //2
|
||||
#endif
|
||||
#define VER_INFO_EXT_MAX_LEN 24
|
||||
|
||||
enum {
|
||||
CFG_ITEM_ADV_IND = 0,
|
||||
CFG_ITEM_SCAN_RSP,
|
||||
CFG_ITEM_BLE_NAME,
|
||||
CFG_ITEM_BT_ADDR,
|
||||
|
||||
CFG_ITEM_BT_NAME = 4,
|
||||
CFG_ITEM_PIN_CODE,
|
||||
CFG_ITEM_VER_INFO,
|
||||
CFG_ITEM_LOW_POWER_VOLTAGE,
|
||||
|
||||
CFG_ITEM_EDR_ADDR = 8,
|
||||
CFG_ITEM_BLE_ADDR,
|
||||
CFG_ITEM_GATT_PROFILE,
|
||||
CFG_ITEM_RESET_IO_INFO,
|
||||
|
||||
CFG_ITEM_PILOT_LAMP_IO_INFO = 12,
|
||||
CFG_ITEM_LINK_KEY_INFO,
|
||||
CFG_ITEM_POWER_IO_ON_OFF,
|
||||
CFG_ITEM_LAST_DEVICE_LINK_KEY_INFO,
|
||||
|
||||
CFG_ITEM_BLE_READ_WRITE_UUID_INFO = 16,
|
||||
#if VER_INFO_EXT_COUNT
|
||||
CFG_ITEM_VER_INFO_AUTHKEY,
|
||||
CFG_ITEM_VER_INFO_PROCODE,
|
||||
#endif
|
||||
CFG_ITEM_PVID, //供loader使用
|
||||
CFG_ITEM_MD5,
|
||||
CFG_ITEM_SDK_TYPE,
|
||||
};
|
||||
|
||||
enum {
|
||||
EX_CFG_ERR_NONE = 0,
|
||||
EX_CFG_INDEX_ERR,
|
||||
EX_CFG_LEN_ERR,
|
||||
};
|
||||
|
||||
enum {
|
||||
GET_VID_FROM_EX_CFG = 0,
|
||||
GET_PID_FROM_EX_CFG,
|
||||
GET_VER_FROM_EX_CFG,
|
||||
#if VER_INFO_EXT_COUNT
|
||||
GET_AUTH_KEY_FROM_EX_CFG,
|
||||
GET_PRO_CODE_FROM_EX_CFG,
|
||||
#endif
|
||||
};
|
||||
|
||||
typedef struct _update_file_id {
|
||||
u8 vid[2];
|
||||
u8 pid[2];
|
||||
u8 ver[2];
|
||||
u8 len[4];
|
||||
u8 reserve[4];
|
||||
u8 crc[2];
|
||||
} update_file_id_t;
|
||||
|
||||
typedef struct _update_file_ext_id {
|
||||
update_file_id_t update_file_id_info;
|
||||
#if VER_INFO_EXT_COUNT
|
||||
u8 ext[VER_INFO_EXT_COUNT * (VER_INFO_EXT_MAX_LEN * 2)];
|
||||
#endif
|
||||
} update_file_ext_id_t;
|
||||
|
||||
typedef struct _update_file_reset_io {
|
||||
u8 io_num;
|
||||
u8 resever[15];
|
||||
} update_file_reset_io_t;
|
||||
|
||||
typedef struct _update_file_pilot_lamp_io {
|
||||
u8 pilot_lamp_io[16];
|
||||
} update_file_pilot_lamp_io_t;
|
||||
|
||||
typedef struct _update_file_link_key {
|
||||
u8 link_key[16];
|
||||
} update_file_link_key_t;
|
||||
|
||||
struct excfg_rsp_payload {
|
||||
u16 vid;
|
||||
u8 logo[5];
|
||||
u8 version;
|
||||
u8 addr[6];
|
||||
};
|
||||
//u32 custom_cfg_file_init(void);
|
||||
//void ex_cfg_write_to_flash(void);
|
||||
//u32 ex_cfg_fill_content_api(u8 cfg_index, u8 *data, u16 len);
|
||||
u32 ex_cfg_fill_content_api(void);
|
||||
u16 get_vid_pid_ver_from_cfg_file(u8 type);
|
||||
#if VER_INFO_EXT_COUNT
|
||||
u32 get_authkey_procode_from_cfg_file(u8 *data[], u8 *len, u8 type);
|
||||
#endif
|
||||
|
||||
#if RCSP_UPDATE_EN
|
||||
extern int rcsp_update_msg[10];
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
391
apps/common/third_party_profile/common/mic_rec.c
Normal file
391
apps/common/third_party_profile/common/mic_rec.c
Normal file
@ -0,0 +1,391 @@
|
||||
/*****************************************************************
|
||||
>file name : mic_rec.c
|
||||
>author : lichao
|
||||
>create time : Wed 26 Jun 2019 04:31:50 PM CST
|
||||
*****************************************************************/
|
||||
#include "system/includes.h"
|
||||
#include "media/includes.h"
|
||||
#include "app_config.h"
|
||||
#include "audio_config.h"
|
||||
#include "classic/tws_local_media_sync.h"
|
||||
#include "3th_profile_api.h"
|
||||
#include "classic/tws_api.h"
|
||||
#include "btstack/avctp_user.h"
|
||||
#include "bt_tws.h"
|
||||
|
||||
#if (BT_MIC_EN)
|
||||
|
||||
#define LOG_TAG "[MIC_REC]"
|
||||
#define LOG_ERROR_ENABLE
|
||||
#define LOG_DEBUG_ENABLE
|
||||
#define LOG_INFO_ENABLE
|
||||
#define LOG_CLI_ENABLE
|
||||
#include "debug.h"
|
||||
|
||||
enum {
|
||||
STANDARD_OPUS = 0 << 6,
|
||||
KUGOU_OPUS = 1 << 6,
|
||||
};
|
||||
|
||||
enum {
|
||||
ENC_OPUS_16KBPS = 0,
|
||||
ENC_OPUS_32KBPS = 1,
|
||||
ENC_OPUS_64KBPS = 2,
|
||||
};
|
||||
|
||||
typedef struct __ai_encode_info {
|
||||
const u8 *info;
|
||||
u32 enc_type;
|
||||
u8 opus_type;
|
||||
u16(*sender)(u8 *buf, u16 len);
|
||||
} _ai_encode_info;
|
||||
|
||||
struct __speech_buf_ctl {
|
||||
cbuffer_t cbuffer;
|
||||
volatile u8 speech_init_flg;
|
||||
u16 cbuf_size;
|
||||
u8 *speech_cbuf;
|
||||
};
|
||||
|
||||
struct __mic_rec_t {
|
||||
struct __speech_buf_ctl buf_ctl;
|
||||
struct __ai_encode_info ai_enc_info;
|
||||
u8 ai_mic_busy_flg;
|
||||
u8 init_ok;
|
||||
u16 frame_num;
|
||||
u16 frame_size;
|
||||
OS_MUTEX mutex_ai_mic;
|
||||
};
|
||||
static struct __mic_rec_t mic_rec;
|
||||
#define __this (&mic_rec)
|
||||
|
||||
extern void bt_sniff_ready_clean(void);
|
||||
bool get_tws_sibling_connect_state(void);
|
||||
int a2dp_tws_dec_suspend(void *p);
|
||||
void a2dp_tws_dec_resume(void);
|
||||
int audio_mic_enc_open(int (*mic_output)(void *priv, void *buf, int len), u32 code_type, u8 ai_type);
|
||||
int audio_mic_enc_close();
|
||||
static void ai_mic_tws_stop_opus();
|
||||
|
||||
static void speech_cbuf_init(void)
|
||||
{
|
||||
__this->buf_ctl.speech_init_flg = 1;
|
||||
|
||||
ASSERT(__this->buf_ctl.speech_cbuf == NULL, "speech_cbuf is err\n");
|
||||
__this->buf_ctl.speech_cbuf = malloc(__this->buf_ctl.cbuf_size);
|
||||
ASSERT(__this->buf_ctl.speech_cbuf, "speech_cbuf is not ok\n");
|
||||
|
||||
cbuf_init(&(__this->buf_ctl.cbuffer), __this->buf_ctl.speech_cbuf, __this->buf_ctl.cbuf_size);
|
||||
}
|
||||
|
||||
static void speech_cbuf_exit(void)
|
||||
{
|
||||
__this->buf_ctl.speech_init_flg = 0;
|
||||
cbuf_clear(&(__this->buf_ctl.cbuffer));
|
||||
|
||||
free(__this->buf_ctl.speech_cbuf);
|
||||
__this->buf_ctl.speech_cbuf = NULL;
|
||||
}
|
||||
|
||||
static u16 speech_data_send(u8 *buf, u16 len, u16(*send_data)(u8 *buf, u16 len))
|
||||
{
|
||||
u16 res = 0;
|
||||
u16 send_len = __this->frame_num * len;
|
||||
u8 temp_buf[send_len];
|
||||
|
||||
if (__this->buf_ctl.speech_init_flg == 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (cbuf_write(&(__this->buf_ctl.cbuffer), buf, len) != len) {
|
||||
res = (u16)(-1);
|
||||
}
|
||||
|
||||
/* printf("cl %d\n",cbuf_get_data_size(&(__this->buf_ctl.cbuffer))); */
|
||||
|
||||
while (cbuf_get_data_size(&(__this->buf_ctl.cbuffer)) >= send_len) {
|
||||
cbuf_read_alloc_len(&(__this->buf_ctl.cbuffer), temp_buf, send_len);
|
||||
if (send_data) {
|
||||
if (!send_data(temp_buf, send_len)) {
|
||||
putchar('S');
|
||||
cbuf_read_alloc_len_updata(&(__this->buf_ctl.cbuffer), send_len);
|
||||
} else {
|
||||
putchar('E');
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
#if TCFG_USER_TWS_ENABLE
|
||||
#if 0
|
||||
void tws_api_local_media_sync_rx_handler_notify()
|
||||
{
|
||||
u8 *tws_buf = NULL;
|
||||
int len = 0;
|
||||
|
||||
if (mic_get_data_source() == SINK_TYPE_SLAVE) {
|
||||
if (dma_tws_mic_pool) {
|
||||
tws_buf = tws_api_local_media_trans_pop(&len);
|
||||
/* log_info("sf %d %0x\n",len, tws_buf); */
|
||||
if (tws_buf) {
|
||||
tws_api_local_media_trans_free(tws_buf);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static u16 tws_data_send_slave_to_master(u8 *buf, u16 len)
|
||||
{
|
||||
u8 *tws_buf = NULL;
|
||||
|
||||
if (dma_tws_mic_pool == 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
tws_buf = tws_api_local_media_trans_alloc(len);
|
||||
if (tws_buf == NULL) {
|
||||
return -1;
|
||||
}
|
||||
/* log_info("sd %0x %d\n",tws_buf,len); */
|
||||
memcpy(tws_buf, buf, len);
|
||||
/* printf("tdlen\n"); */
|
||||
/* put_buf(tws_buf,len); */
|
||||
tws_api_local_media_trans_push(tws_buf, len);
|
||||
return 0;
|
||||
|
||||
}
|
||||
#endif
|
||||
|
||||
enum {
|
||||
//send to sibling
|
||||
TWS_AI_A2DP_DROP_FRAME_CTL_V2 = 0,
|
||||
|
||||
//tws sync deal
|
||||
TWS_AI_MIC_RESUME_A2DP = 0x80,
|
||||
};
|
||||
|
||||
static int mic_rec_tws_send_cmd(u8 cmd)
|
||||
{
|
||||
return tws_api_send_data_to_sibling(&cmd, sizeof(cmd), 0x3890AB12);
|
||||
}
|
||||
|
||||
static void __mic_rec_tws_rx_cb_deal(int cmd)
|
||||
{
|
||||
switch (cmd) { //tws sync deal
|
||||
case TWS_AI_A2DP_DROP_FRAME_CTL_V2:
|
||||
a2dp_tws_dec_suspend(NULL);
|
||||
break;
|
||||
case TWS_AI_MIC_RESUME_A2DP:
|
||||
ai_mic_tws_stop_opus();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void mic_rec_tws_rx_data(void *_data, u16 len, bool rx)
|
||||
{
|
||||
int msg[4];
|
||||
int err = 0;
|
||||
u8 *data = (u8 *)_data;
|
||||
|
||||
printf(">>>%s \n", __func__);
|
||||
printf("len :%d\n", len);
|
||||
put_buf(_data, len);
|
||||
|
||||
if (!rx && data[0] < TWS_AI_MIC_RESUME_A2DP) { //not need deal
|
||||
return;
|
||||
}
|
||||
|
||||
msg[0] = (int)__mic_rec_tws_rx_cb_deal;
|
||||
msg[1] = 1;
|
||||
msg[2] = *data;
|
||||
err = os_taskq_post_type("app_core", Q_CALLBACK, 3, msg);
|
||||
if (err) {
|
||||
printf("tws rx post fail\n");
|
||||
}
|
||||
}
|
||||
|
||||
REGISTER_TWS_FUNC_STUB(mic_rec_sync_stub) = {
|
||||
.func_id = 0x3890AB12,
|
||||
.func = mic_rec_tws_rx_data,
|
||||
};
|
||||
#endif
|
||||
|
||||
u16 ai_mic_get_frame_size()
|
||||
{
|
||||
return __this->frame_size;
|
||||
}
|
||||
|
||||
static int rec_enc_output(void *priv, void *buf, int len)
|
||||
{
|
||||
bt_sniff_ready_clean();
|
||||
|
||||
u8 *send_buf = (u8 *)buf;
|
||||
int send_len = len;
|
||||
|
||||
//printf("len:%d\n", len);
|
||||
__this->frame_size = len;
|
||||
if (speech_data_send(send_buf, send_len, __this->ai_enc_info.sender) == (u16)(-1)) {
|
||||
log_info("opus data miss !!! line:%d \n", __LINE__);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
_WEAK_ int a2dp_tws_dec_suspend(void *p)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
_WEAK_ void a2dp_tws_dec_resume(void)
|
||||
{
|
||||
}
|
||||
|
||||
_WEAK_ void bt_sniff_ready_clean(void)
|
||||
{
|
||||
}
|
||||
|
||||
_WEAK_ void mic_rec_clock_set(void)
|
||||
{
|
||||
}
|
||||
|
||||
_WEAK_ void mic_rec_clock_recover(void)
|
||||
{
|
||||
}
|
||||
|
||||
int ai_mic_rec_start(void)
|
||||
{
|
||||
if (0 == __this->init_ok) {
|
||||
printf("init err\n");
|
||||
return -1;
|
||||
}
|
||||
os_mutex_pend(&__this->mutex_ai_mic, 0);
|
||||
|
||||
if (__this->ai_mic_busy_flg) {
|
||||
os_mutex_post(&__this->mutex_ai_mic);
|
||||
return -1;
|
||||
}
|
||||
|
||||
user_send_cmd_prepare(USER_CTRL_ALL_SNIFF_EXIT, 0, NULL);
|
||||
|
||||
#if TCFG_USER_TWS_ENABLE
|
||||
if (get_tws_sibling_connect_state() && (tws_api_get_role() == TWS_ROLE_MASTER)) {
|
||||
mic_rec_tws_send_cmd(TWS_AI_A2DP_DROP_FRAME_CTL_V2);
|
||||
}
|
||||
#endif
|
||||
|
||||
int err = a2dp_tws_dec_suspend(NULL);
|
||||
if (err == 0) {
|
||||
printf("opus init \n");
|
||||
|
||||
mic_rec_clock_set();
|
||||
|
||||
speech_cbuf_init();
|
||||
|
||||
printf("%s \n", __this->ai_enc_info.info);
|
||||
audio_mic_enc_open(rec_enc_output, __this->ai_enc_info.enc_type, __this->ai_enc_info.opus_type);
|
||||
__this->ai_mic_busy_flg = 1;
|
||||
}
|
||||
|
||||
os_mutex_post(&__this->mutex_ai_mic);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int ai_mic_is_busy(void)
|
||||
{
|
||||
return __this->ai_mic_busy_flg;
|
||||
}
|
||||
|
||||
static void ai_mic_tws_stop_opus()
|
||||
{
|
||||
if (__this->ai_mic_busy_flg == 0) {
|
||||
a2dp_tws_dec_resume();
|
||||
}
|
||||
}
|
||||
|
||||
static int ai_mic_resume_a2dp(void)
|
||||
{
|
||||
int err = 0;
|
||||
int msg[8];
|
||||
msg[0] = (int)ai_mic_tws_stop_opus;
|
||||
msg[1] = 1;
|
||||
msg[2] = 0;
|
||||
|
||||
while (1) {
|
||||
err = os_taskq_post_type("app_core", Q_CALLBACK, 3, msg);
|
||||
if (err != OS_Q_FULL) {
|
||||
break;
|
||||
}
|
||||
os_time_dly(2);
|
||||
}
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
int ai_mic_rec_close(void)
|
||||
{
|
||||
os_mutex_pend(&__this->mutex_ai_mic, 0);
|
||||
|
||||
if (__this->ai_mic_busy_flg) {
|
||||
printf(">>>>opus close: %d, %s\n", cpu_in_irq(), os_current_task());
|
||||
audio_mic_enc_close();
|
||||
|
||||
speech_cbuf_exit();
|
||||
|
||||
mic_rec_clock_recover();
|
||||
|
||||
__this->ai_mic_busy_flg = 0;
|
||||
}
|
||||
|
||||
os_mutex_post(&__this->mutex_ai_mic);
|
||||
|
||||
#if TCFG_USER_TWS_ENABLE
|
||||
if ((tws_api_get_tws_state() & TWS_STA_SIBLING_CONNECTED)) {
|
||||
if (tws_api_get_role() == TWS_ROLE_MASTER) {
|
||||
mic_rec_tws_send_cmd(TWS_AI_MIC_RESUME_A2DP);
|
||||
}
|
||||
} else {
|
||||
/*a2dp_tws_dec_resume();*/
|
||||
ai_mic_resume_a2dp();
|
||||
}
|
||||
#else
|
||||
ai_mic_resume_a2dp();
|
||||
/*a2dp_tws_dec_resume();*/
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int ai_mic_mutex_init(void)
|
||||
{
|
||||
os_mutex_create(&__this->mutex_ai_mic);
|
||||
return 0;
|
||||
}
|
||||
late_initcall(ai_mic_mutex_init);
|
||||
|
||||
int mic_rec_pram_init(/* const char **name, */u32 enc_type, u8 opus_type, u16(*speech_send)(u8 *buf, u16 len), u16 frame_num, u16 cbuf_size)
|
||||
{
|
||||
/* __this->ai_enc_info.info = name; */
|
||||
__this->init_ok = 0;
|
||||
if (enc_type == AUDIO_CODING_OPUS && !TCFG_ENC_OPUS_ENABLE) {
|
||||
printf("please enable opus deceder");
|
||||
return -1;
|
||||
} else if (enc_type == AUDIO_CODING_SPEEX && !TCFG_ENC_SPEEX_ENABLE) {
|
||||
printf("please enable speex deceder");
|
||||
return -1;
|
||||
}
|
||||
__this->ai_enc_info.enc_type = enc_type;
|
||||
__this->ai_enc_info.opus_type = opus_type;
|
||||
__this->ai_enc_info.sender = speech_send;
|
||||
__this->frame_num = frame_num;
|
||||
__this->buf_ctl.cbuf_size = cbuf_size;
|
||||
__this->init_ok = 1;
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
1294
apps/common/third_party_profile/interface/app_protocol_api.c
Normal file
1294
apps/common/third_party_profile/interface/app_protocol_api.c
Normal file
File diff suppressed because it is too large
Load Diff
84
apps/common/third_party_profile/interface/app_protocol_api.h
Normal file
84
apps/common/third_party_profile/interface/app_protocol_api.h
Normal file
@ -0,0 +1,84 @@
|
||||
|
||||
|
||||
#ifndef _3TH_PROTOCOL_API_H
|
||||
#define _3TH_PROTOCOL_API_H
|
||||
|
||||
#include<string.h>
|
||||
#include <stdint.h>
|
||||
#include "typedef.h"
|
||||
#include "os/os_api.h"
|
||||
#include "btstack/third_party/app_protocol_event.h"
|
||||
#include "app_protocol_common.h"
|
||||
|
||||
#define APP_PROTOCOL_TASK_NAME "app_proto"
|
||||
|
||||
//定义这几个宏仅仅用于编译优化代码量。需要那个选哪个,flash够大,可以全部都打开的。
|
||||
//不要在板级头文件重复定义。
|
||||
#define APP_PROTOCOL_DEMO_CODE 0
|
||||
#define APP_PROTOCOL_GMA_CODE 0
|
||||
#define APP_PROTOCOL_AMA_CODE 0
|
||||
#define APP_PROTOCOL_DMA_CODE 0
|
||||
#define APP_PROTOCOL_TME_CODE 0
|
||||
#define APP_PROTOCOL_MMA_CODE 0
|
||||
#define APP_PROTOCOL_GFPS_CODE 1
|
||||
|
||||
#define APP_PROTOCOL_SPEECH_EN 0 //语音助手功能,若无此功能则关掉
|
||||
#define APP_PROTOCOL_READ_CFG_EN 0 //从custom.dat中读取配置信息,若无此功能则关掉
|
||||
|
||||
#define DEMO_HANDLER_ID 0x300 /*作为一个使用的例子,同时也可作为客户自己添加协议的ID*/
|
||||
#define GMA_HANDLER_ID 0x400 /*阿里天猫协议接口ID*/
|
||||
#define MMA_HANDLER_ID 0x500 /*小米MMA协议接口ID*/
|
||||
#define DMA_HANDLER_ID 0x600 /*百度DMA协议接口ID*/
|
||||
#define TME_HANDLER_ID 0x700 /*腾讯酷狗TME协议接口ID*/
|
||||
#define AMA_HANDLER_ID 0x800 /*亚马逊的AMA协议接口ID*/
|
||||
#define GFPS_HANDLER_ID 0x900 /*谷歌快对的协议接口ID*/
|
||||
|
||||
//app os task message
|
||||
enum {
|
||||
//Q_USER =0x400000
|
||||
APP_PROTOCOL_RX_DATA_EVENT = (Q_USER + 100),
|
||||
APP_PROTOCOL_TX_DATA_EVENT,
|
||||
APP_PROTOCOL_TASK_EXIT,
|
||||
};
|
||||
|
||||
//参数配置类接口(在库外面的文件common区)
|
||||
//配置在init之前的参数接口
|
||||
void app_protocol_set_product_id(u32 handler_id, u32 pid);
|
||||
void app_protocol_set_vendor_id(u32 handler_id, u32 vid);
|
||||
void app_protocol_set_local_version(u32 handler_id, u32 version);
|
||||
void app_protocol_set_info_group(u32 handler_id, void *addr); //如配置三元组
|
||||
void app_protocol_tws_role_check_register(u8(*handler)(void)); /*注册获取tws状态的函数接口*/
|
||||
void app_protocol_set_tws_sibling_mac(u8 *mac);
|
||||
|
||||
|
||||
//公共类函数接口
|
||||
/*这个接口主要是建立一个线程,注册一些协议需要用的公共接口,比如resume,message_handler等函数。建立了线程之后,初始化*/
|
||||
void app_protocol_all_init();
|
||||
void app_protocol_init(int handler_id);
|
||||
/*主要是删除线程操作,在删除完之后再释放APP协议栈的资源*/
|
||||
void app_protocol_exit(int handler_id);
|
||||
/*开始语音识别功能*/
|
||||
int app_protocol_start_speech_cmd();
|
||||
/*手动停止语音识别功能*/
|
||||
int app_protocol_stop_speech_cmd();
|
||||
int app_protocol_left_start_speech_cmd();
|
||||
int app_protocol_right_start_speech_cmd();
|
||||
void app_protocol_update_battery(u8 main, u8 left, u8 right, u8 box);
|
||||
void app_protocol_ble_adv_switch(int sw);
|
||||
void app_protocol_ibeacon_switch(int sw);
|
||||
void app_protocol_disconnect(void *addr);
|
||||
void app_protocol_get_tws_data_for_lib(u8 *data, u32 len);
|
||||
/*发送mic相应编码后的数据*/
|
||||
int app_protocol_send_voice_data(uint8_t *voice_buf, uint16_t voice_len);
|
||||
/*获取有没有链路连接完成状态*/
|
||||
int app_protocol_check_connect_success();
|
||||
bool is_tws_master_role();
|
||||
|
||||
u32 app_protocol_get_cur_handle_id();
|
||||
|
||||
int app_protocol_get_version_by_id(int id);
|
||||
|
||||
int app_protocol_reply_frame_check_result(int result);
|
||||
void app_protocal_update_tws_state_to_lib(int state);
|
||||
|
||||
#endif
|
||||
774
apps/common/third_party_profile/interface/app_protocol_common.c
Normal file
774
apps/common/third_party_profile/interface/app_protocol_common.c
Normal file
@ -0,0 +1,774 @@
|
||||
#include "app_protocol_api.h"
|
||||
#include "app_protocol_common.h"
|
||||
#include "system/includes.h"
|
||||
#include "app_config.h"
|
||||
#include "audio_config.h"
|
||||
#include "app_chargestore.h"
|
||||
#include "app_power_manage.h"
|
||||
#include "asm/charge.h"
|
||||
#include "bt_tws.h"
|
||||
#include "btstack/avctp_user.h"
|
||||
#include "3th_profile_api.h"
|
||||
#include "bt_common.h"
|
||||
#include "tone_player.h"
|
||||
#include "app_main.h"
|
||||
#include "key_event_deal.h"
|
||||
|
||||
#if AI_APP_PROTOCOL
|
||||
|
||||
#if 1
|
||||
#define APP_PROTOCOL_LOG printf
|
||||
#define APP_PROTOCOL_DUMP put_buf
|
||||
#else
|
||||
#define APP_PROTOCOL_LOG(...)
|
||||
#define APP_PROTOCOL_DUMP(...)
|
||||
#endif
|
||||
|
||||
__attribute__((weak))
|
||||
void app_protocol_tone_play(int index, int tws_sync)
|
||||
{
|
||||
|
||||
}
|
||||
static const char **app_tone_table = NULL;
|
||||
static struct app_protocol_private_handle_t *private_handle;
|
||||
|
||||
extern u8 get_remote_dev_company(void);
|
||||
#define REMOTE_DEV_ANDROID 1
|
||||
#define REMOTE_DEV_IOS 2
|
||||
bool is_ios_system(void)
|
||||
{
|
||||
APP_PROTOCOL_LOG("remote_dev_company :%d \n", get_remote_dev_company());
|
||||
return (get_remote_dev_company() == REMOTE_DEV_IOS);
|
||||
}
|
||||
|
||||
void app_protocol_tone_register(const char **tone_table)
|
||||
{
|
||||
app_tone_table = tone_table;
|
||||
}
|
||||
|
||||
const char *app_protocol_get_tone(int index)
|
||||
{
|
||||
if (app_tone_table) {
|
||||
return app_tone_table[index];
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void app_protocol_handle_register(struct app_protocol_private_handle_t *hd)
|
||||
{
|
||||
private_handle = hd;
|
||||
}
|
||||
|
||||
struct app_protocol_private_handle_t *app_protocol_get_handle()
|
||||
{
|
||||
return private_handle;
|
||||
}
|
||||
|
||||
//协议私有同步消息处理函数
|
||||
void app_protocol_tws_sync_private_deal(int cmd, int value)
|
||||
{
|
||||
if (private_handle && private_handle->tws_sync_func) {
|
||||
private_handle->tws_sync_func(cmd, value);
|
||||
}
|
||||
}
|
||||
|
||||
//协议私有收到对耳数据处理函数
|
||||
void app_protocol_tws_rx_data_private_deal(u16 opcode, u8 *data, u16 len)
|
||||
{
|
||||
if (private_handle && private_handle->tws_rx_from_siblling) {
|
||||
private_handle->tws_rx_from_siblling(opcode, data, len);
|
||||
}
|
||||
}
|
||||
|
||||
int app_protocol_sys_event_private_deal(struct sys_event *event)
|
||||
{
|
||||
if (private_handle && private_handle->sys_event_handler) {
|
||||
return private_handle->sys_event_handler(event);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
#if APP_PROTOCOL_SPEECH_EN
|
||||
#define APP_PROTOCOL_MIC_TIMEOUT 8000 //mic使用超时时间,0不限时
|
||||
|
||||
static u16 mic_timer = 0;
|
||||
static u16 tone_after_exit_sniff_timer = 0;
|
||||
static u8 exit_sniff_cnt = 0;
|
||||
void __app_protocol_speech_stop(void)
|
||||
{
|
||||
if (ai_mic_is_busy()) {
|
||||
if (mic_timer) {
|
||||
sys_timeout_del(mic_timer);
|
||||
mic_timer = 0;
|
||||
}
|
||||
APP_PROTOCOL_LOG("app_protocol_speech_stop\n");
|
||||
|
||||
ai_mic_rec_close();
|
||||
app_protocol_stop_speech_cmd();
|
||||
}
|
||||
}
|
||||
|
||||
static void app_protocol_speech_timeout(void *priv)
|
||||
{
|
||||
APP_PROTOCOL_LOG(" speech timeout !!! \n");
|
||||
__app_protocol_speech_stop();
|
||||
}
|
||||
|
||||
static int app_protocol_speech_start_check()
|
||||
{
|
||||
if (BT_STATUS_TAKEING_PHONE == get_bt_connect_status()) {
|
||||
APP_PROTOCOL_LOG("phone ing...\n");
|
||||
return -1;
|
||||
}
|
||||
if (ai_mic_is_busy()) {
|
||||
APP_PROTOCOL_LOG("mic activing...\n");
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int __app_protocol_speech_start(void)
|
||||
{
|
||||
if (!app_protocol_speech_start_check() && ai_mic_rec_start() == 0) {
|
||||
#if APP_PROTOCOL_MIC_TIMEOUT
|
||||
mic_timer = sys_timeout_add(NULL, app_protocol_speech_timeout, APP_PROTOCOL_MIC_TIMEOUT);
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
APP_PROTOCOL_LOG("speech start fail\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
int app_protocol_start_speech_by_app(u8 tone_en)
|
||||
{
|
||||
if (app_protocol_speech_start_check()) {
|
||||
return -1;
|
||||
}
|
||||
if (app_var.siri_stu) {
|
||||
APP_PROTOCOL_LOG("siri activing...\n");
|
||||
return -1;
|
||||
}
|
||||
if (tone_en) {
|
||||
app_protocol_tone_play(APP_RROTOCOL_TONE_SPEECH_APP_START, 1);
|
||||
} else {
|
||||
app_protocol_post_bt_event(AI_EVENT_SPEECH_START, NULL);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int app_protocol_stop_speech_by_app()
|
||||
{
|
||||
app_protocol_post_bt_event(AI_EVENT_SPEECH_STOP, NULL);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void speech_tone_play_after_exit_sniff()
|
||||
{
|
||||
tone_after_exit_sniff_timer = 0;
|
||||
if (bt_is_sniff_close() && exit_sniff_cnt < 13) {
|
||||
exit_sniff_cnt++;
|
||||
tone_after_exit_sniff_timer = sys_timeout_add(NULL, speech_tone_play_after_exit_sniff, 100);
|
||||
return;
|
||||
}
|
||||
exit_sniff_cnt = 0;
|
||||
if (!app_protocol_speech_start_check()) {
|
||||
app_protocol_tone_play(APP_RROTOCOL_TONE_SPEECH_KEY_START, 1);
|
||||
}
|
||||
}
|
||||
|
||||
int app_protocol_start_speech_by_key(struct sys_event *event)
|
||||
{
|
||||
#if TCFG_USER_TWS_ENABLE
|
||||
if (get_bt_tws_connect_status() && !is_tws_master_role()) {
|
||||
APP_PROTOCOL_LOG("tws slave, return\n");
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
user_send_cmd_prepare(USER_CTRL_HFP_GET_SIRI_STATUS, 0, NULL);
|
||||
if (app_protocol_speech_start_check()) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (app_protocol_check_connect_success() && (get_curr_channel_state()&A2DP_CH)) {
|
||||
printf("no connect\n");
|
||||
} else {
|
||||
if (get_curr_channel_state()&A2DP_CH) {
|
||||
//<协议未连接, 但是A2DP已连接, 点击唤醒键, 提示TTS【请打开小度APP】
|
||||
if (is_ios_system()) {
|
||||
APP_PROTOCOL_LOG("ble adv ibeaconn");
|
||||
app_protocol_ibeacon_switch(1);
|
||||
} else {
|
||||
user_send_cmd_prepare(USER_CTRL_HFP_GET_SIRI_OPEN, 0, NULL);
|
||||
}
|
||||
app_protocol_tone_play(APP_PROTOCOL_TONE_DISCONNECTED_ALL, 1);
|
||||
} else {
|
||||
//<蓝牙完全关闭状态, 用户按唤醒键, 提示TTS【蓝牙未连接, 请用手机蓝牙和我连接吧】
|
||||
app_protocol_tone_play(APP_RROTOCOL_TONE_OPEN_APP, 1);
|
||||
}
|
||||
APP_PROTOCOL_LOG("A2dp or protocol no connect err!!!\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
#if 1//等退出sniff后再播提示音
|
||||
if (bt_is_sniff_close()) {
|
||||
user_send_cmd_prepare(USER_CTRL_ALL_SNIFF_EXIT, 0, NULL);
|
||||
if (tone_after_exit_sniff_timer == 0) {
|
||||
tone_after_exit_sniff_timer = sys_timeout_add(NULL, speech_tone_play_after_exit_sniff, 100);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
exit_sniff_cnt = 0;
|
||||
#endif
|
||||
|
||||
app_protocol_tone_play(APP_RROTOCOL_TONE_SPEECH_KEY_START, 1);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int app_protocol_stop_speech_by_key(void)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
#else
|
||||
void __app_protocol_speech_stop(void)
|
||||
{
|
||||
}
|
||||
#endif
|
||||
|
||||
void app_speech_tone_play_end_callback(void *priv, int flag)
|
||||
{
|
||||
u32 index = (u32)priv;
|
||||
switch (index) {
|
||||
#if APP_PROTOCOL_SPEECH_EN
|
||||
case APP_RROTOCOL_TONE_SPEECH_KEY_START:
|
||||
APP_PROTOCOL_LOG("APP_RROTOCOL_TONE_SPEECH_KEY_START\n");
|
||||
if (app_protocol_speech_start_check()) {
|
||||
break;
|
||||
}
|
||||
if (app_var.siri_stu) {
|
||||
APP_PROTOCOL_LOG("siri activing...\n");
|
||||
break;
|
||||
}
|
||||
///按键启动需要report, app启动, 直接启动语音即可
|
||||
if (is_tws_master_role() && !app_protocol_start_speech_cmd()) {//从转发mic数据给主机或主机上报完成开启mic
|
||||
APP_PROTOCOL_LOG("app_protocol_mic_status_report success\n");
|
||||
app_protocol_post_bt_event(AI_EVENT_SPEECH_START, NULL);
|
||||
}
|
||||
break;
|
||||
case APP_RROTOCOL_TONE_SPEECH_APP_START:
|
||||
APP_PROTOCOL_LOG("APP_RROTOCOL_TONE_SPEECH_APP_START\n");
|
||||
if (app_protocol_speech_start_check()) {
|
||||
break;
|
||||
}
|
||||
if (app_var.siri_stu) {
|
||||
APP_PROTOCOL_LOG("siri activing...\n");
|
||||
break;
|
||||
}
|
||||
if (is_tws_master_role()) {
|
||||
app_protocol_post_bt_event(AI_EVENT_SPEECH_START, NULL);
|
||||
}
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
int app_protocol_set_volume(u8 vol)
|
||||
{
|
||||
u8 vol_l = (vol * get_max_sys_vol()) / 0x64;
|
||||
u8 vol_r = (vol * get_max_sys_vol()) / 0x64;
|
||||
|
||||
app_audio_set_volume(APP_AUDIO_STATE_MUSIC, APP_AUDIO_STATE_MUSIC, vol_r);
|
||||
return 0;
|
||||
}
|
||||
__attribute__((weak))
|
||||
bool vbat_is_low_power(void)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
u8 app_protocal_get_bat_by_type(u8 type)
|
||||
{
|
||||
u8 value = 0;
|
||||
extern u8 get_tws_sibling_bat_persent(void);
|
||||
u8 sibling_val = get_tws_sibling_bat_persent();
|
||||
#if TCFG_CHARGESTORE_ENABLE
|
||||
if (sibling_val == 0xff) {
|
||||
sibling_val = chargestore_get_sibling_power_level();
|
||||
}
|
||||
#endif
|
||||
switch (type) {
|
||||
case APP_PROTOCOL_BAT_T_CHARGE_FLAG:
|
||||
value = get_charge_online_flag();
|
||||
break;
|
||||
case APP_PROTOCOL_BAT_T_MAIN:
|
||||
value = get_vbat_percent();
|
||||
break;
|
||||
#if TCFG_CHARGESTORE_ENABLE
|
||||
case APP_PROTOCOL_BAT_T_BOX:
|
||||
value = chargestore_get_power_level();
|
||||
break;
|
||||
#endif
|
||||
case APP_PROTOCOL_BAT_T_TWS_LEFT:
|
||||
value = (tws_api_get_local_channel() == 'L') ? get_vbat_percent() : sibling_val;
|
||||
break;
|
||||
case APP_PROTOCOL_BAT_T_TWS_RIGHT:
|
||||
value = (tws_api_get_local_channel() == 'R') ? get_vbat_percent() : sibling_val;
|
||||
break;
|
||||
case APP_PROTOCOL_BAT_T_TWS_SIBLING:
|
||||
value = sibling_val;
|
||||
break;
|
||||
case APP_PROTOCOL_BAT_T_LOW_POWER:
|
||||
value = vbat_is_low_power();
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
if (value == 0xff) { //获取不到电量返回0
|
||||
value = 0;
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
u32 read_cfg_file(void *buf, u16 len, char *path)
|
||||
{
|
||||
FILE *fp = fopen(path, "r");
|
||||
int rlen;
|
||||
|
||||
if (!fp) {
|
||||
//printf("read_cfg_file:fopen err!\n");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
rlen = fread(fp, buf, len);
|
||||
if (rlen <= 0) {
|
||||
//printf("read_cfg_file:fread err!\n");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
fclose(fp);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
#define LIC_PAGE_OFFSET 80
|
||||
#define FORCE_TO_ERASE 1
|
||||
|
||||
typedef enum _FLASH_ERASER {
|
||||
CHIP_ERASER = 0,
|
||||
BLOCK_ERASER,
|
||||
SECTOR_ERASER,
|
||||
PAGE_ERASER,
|
||||
} FLASH_ERASER;
|
||||
|
||||
typedef struct __flash_of_lic_para_head {
|
||||
s16 crc;
|
||||
u16 string_len;
|
||||
const u8 para_string[];
|
||||
} __attribute__((packed)) _flash_of_lic_para_head;
|
||||
|
||||
static bool license_para_head_check(u8 *para)
|
||||
{
|
||||
_flash_of_lic_para_head *head;
|
||||
|
||||
//fill head
|
||||
head = (_flash_of_lic_para_head *)para;
|
||||
|
||||
///crc check
|
||||
u8 *crc_data = (u8 *)(para + sizeof(((_flash_of_lic_para_head *)0)->crc));
|
||||
u32 crc_len = sizeof(_flash_of_lic_para_head) - sizeof(((_flash_of_lic_para_head *)0)->crc)/*head crc*/ + (head->string_len)/*content crc,include end character '\0'*/;
|
||||
s16 crc_sum = 0;
|
||||
|
||||
crc_sum = CRC16(crc_data, crc_len);
|
||||
|
||||
if (crc_sum != head->crc) {
|
||||
printf("license crc error !!! %x %x \n", (u32)crc_sum, (u32)head->crc);
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
//获取三元组信息的头指针
|
||||
const u8 *app_protocal_get_license_ptr(void)
|
||||
{
|
||||
u32 flash_capacity = sdfile_get_disk_capacity();
|
||||
u32 flash_addr = flash_capacity - 256 + LIC_PAGE_OFFSET;
|
||||
u8 *lic_ptr = NULL;
|
||||
_flash_of_lic_para_head *head;
|
||||
|
||||
printf("flash capacity:%x \n", flash_capacity);
|
||||
lic_ptr = (u8 *)sdfile_flash_addr2cpu_addr(flash_addr);
|
||||
|
||||
//head length check
|
||||
head = (_flash_of_lic_para_head *)lic_ptr;
|
||||
if (head->string_len >= 0xff) {
|
||||
printf("license length error !!! \n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
////crc check
|
||||
if (license_para_head_check(lic_ptr) == (false)) {
|
||||
printf("license head check fail\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
//put_buf(lic_ptr, 128);
|
||||
|
||||
lic_ptr += sizeof(_flash_of_lic_para_head);
|
||||
return lic_ptr;
|
||||
}
|
||||
|
||||
extern bool sfc_erase(int cmd, u32 addr);
|
||||
extern u32 sfc_write(const u8 *buf, u32 addr, u32 len);
|
||||
//将三元组信息保存到flash里面
|
||||
int app_protocol_license2flash(const u8 *data, u16 len)
|
||||
{
|
||||
_flash_of_lic_para_head header;
|
||||
u8 buffer[256];
|
||||
u32 flash_capacity = sdfile_get_disk_capacity();
|
||||
u32 sector = flash_capacity - 4 * 1024;
|
||||
u32 page_addr = flash_capacity - 256;
|
||||
u8 *auif_ptr = (u8 *)sdfile_flash_addr2cpu_addr(page_addr);
|
||||
|
||||
#if (!FORCE_TO_ERASE)
|
||||
APP_PROTOCOL_LOG("not supported flash erase !!! \n");
|
||||
return (-1);
|
||||
#endif
|
||||
|
||||
///save last 256 byte
|
||||
/* memset(buffer, 0xff, sizeof(buffer)); */
|
||||
memcpy(buffer, auif_ptr, sizeof(buffer));
|
||||
auif_ptr += LIC_PAGE_OFFSET;
|
||||
|
||||
header.string_len = len;
|
||||
///length
|
||||
memcpy(&buffer[LIC_PAGE_OFFSET + sizeof(header.crc)], &(header.string_len), sizeof(header.string_len));
|
||||
///context
|
||||
memcpy(&buffer[LIC_PAGE_OFFSET + sizeof(header)], data, len);
|
||||
///crc
|
||||
header.crc = CRC16(&buffer[LIC_PAGE_OFFSET + sizeof(header.crc)], sizeof(header.string_len) + header.string_len);
|
||||
memcpy(&buffer[LIC_PAGE_OFFSET], &(header.crc), sizeof(header.crc));
|
||||
|
||||
///check if need update data to flash,erease license erea if there are some informations in license erea
|
||||
if (!memcmp(auif_ptr, buffer + LIC_PAGE_OFFSET, len + sizeof(_flash_of_lic_para_head))) {
|
||||
APP_PROTOCOL_LOG("flash information the same with license\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
APP_PROTOCOL_LOG("erase license sector \n");
|
||||
sfc_erase(SECTOR_ERASER, sector);
|
||||
|
||||
APP_PROTOCOL_LOG("write license to flash \n");
|
||||
sfc_write(buffer, page_addr, 256);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int app_protocol_tws_send_to_sibling(u16 opcode, u8 *data, u16 len)
|
||||
{
|
||||
u8 send_data[len + 4];
|
||||
printf("app protocol send data to sibling \n");
|
||||
send_data[0] = opcode & 0xff;
|
||||
send_data[1] = opcode >> 8;
|
||||
send_data[2] = len & 0xff;
|
||||
send_data[3] = len >> 8;
|
||||
memcpy(send_data + 4, data, len);
|
||||
|
||||
return tws_api_send_data_to_sibling(send_data, sizeof(send_data), APP_PROTOCOL_TWS_SEND_ID);
|
||||
}
|
||||
|
||||
static void __tws_rx_from_sibling(u8 *data)
|
||||
{
|
||||
u16 opcode = (data[1] << 8) | data[0];
|
||||
u16 len = (data[3] << 8) | data[2];
|
||||
u8 *rx_data = data + 4;
|
||||
|
||||
switch (opcode) {
|
||||
case APP_PROTOCOL_TWS_FOR_LIB:
|
||||
APP_PROTOCOL_LOG("APP_PROTOCOL_TWS_FOR_LIB");
|
||||
app_protocol_get_tws_data_for_lib(rx_data, len);
|
||||
break;
|
||||
}
|
||||
app_protocol_tws_rx_data_private_deal(opcode, rx_data, len);
|
||||
|
||||
free(data);
|
||||
}
|
||||
|
||||
static void app_protocol_rx_from_sibling(void *_data, u16 len, bool rx)
|
||||
{
|
||||
int err = 0;
|
||||
if (rx) {
|
||||
printf(">>>%s \n", __func__);
|
||||
printf("len :%d\n", len);
|
||||
put_buf(_data, len);
|
||||
u8 *rx_data = malloc(len);
|
||||
memcpy(rx_data, _data, len);
|
||||
|
||||
int msg[4];
|
||||
msg[0] = (int)__tws_rx_from_sibling;
|
||||
msg[1] = 1;
|
||||
msg[2] = (int)rx_data;
|
||||
err = os_taskq_post_type("app_core", Q_CALLBACK, 3, msg);
|
||||
if (err) {
|
||||
printf("tws rx post fail\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//发送给对耳
|
||||
REGISTER_TWS_FUNC_STUB(app_vol_sync_stub) = {
|
||||
.func_id = APP_PROTOCOL_TWS_SEND_ID,
|
||||
.func = app_protocol_rx_from_sibling,
|
||||
};
|
||||
|
||||
//对耳同步执行
|
||||
int app_protocol_tws_sync_send(int cmd, int value)
|
||||
{
|
||||
int data[2];
|
||||
data[0] = cmd;
|
||||
data[1] = value;
|
||||
return tws_api_send_data_to_slave(data, sizeof(data), APP_PROTOCOL_TWS_SYNC_ID);
|
||||
}
|
||||
|
||||
void app_protocol_tws_sync_deal(int cmd, int value)
|
||||
{
|
||||
switch (cmd) {
|
||||
case APP_PROTOCOL_SYNC_TONE:
|
||||
printf("APP_PROTOCOL_SYNC_TONE:%d\n", value);
|
||||
app_protocol_tone_play(value, 0);
|
||||
break;
|
||||
}
|
||||
app_protocol_tws_sync_private_deal(cmd, value);
|
||||
}
|
||||
|
||||
static void app_protocol_tws_sync_rx(void *data, u16 len, bool rx)
|
||||
{
|
||||
int err = 0;
|
||||
int *arg = (int *)data;
|
||||
int msg[8];
|
||||
|
||||
msg[0] = (int)app_protocol_tws_sync_deal;
|
||||
msg[1] = len / sizeof(int);
|
||||
msg[2] = arg[0]; //cmd
|
||||
msg[3] = arg[1]; //value
|
||||
|
||||
err = os_taskq_post_type("app_core", Q_CALLBACK, 2 + len / sizeof(int), msg);
|
||||
if (err) {
|
||||
printf("tws sync post fail\n");
|
||||
}
|
||||
}
|
||||
|
||||
REGISTER_TWS_FUNC_STUB(app_protocol_sync) = {
|
||||
.func_id = APP_PROTOCOL_TWS_SYNC_ID,
|
||||
.func = app_protocol_tws_sync_rx,
|
||||
};
|
||||
|
||||
//在app_core任务里面进行处理
|
||||
int app_protocol_post_app_core_callback(int callback, void *priv)
|
||||
{
|
||||
int msg[8];
|
||||
msg[0] = callback;
|
||||
msg[1] = 1;
|
||||
msg[2] = (int)priv;
|
||||
return os_taskq_post_type("app_core", Q_CALLBACK, 3, msg);
|
||||
}
|
||||
|
||||
void app_protocol_post_bt_event(u8 event, void *priv)
|
||||
{
|
||||
struct sys_event e;
|
||||
|
||||
memset(&e, 0, sizeof(e));
|
||||
e.type = SYS_BT_EVENT;
|
||||
e.arg = (void *)SYS_BT_AI_EVENT_TYPE_STATUS;
|
||||
e.u.bt.event = event;
|
||||
e.u.bt.value = (int)priv;
|
||||
sys_event_notify(&e);
|
||||
}
|
||||
|
||||
|
||||
static int app_protocol_bt_status_event_handler(struct bt_event *bt)
|
||||
{
|
||||
switch (bt->event) {
|
||||
case BT_STATUS_INIT_OK:
|
||||
app_protocol_all_init();
|
||||
break;
|
||||
case BT_STATUS_SECOND_CONNECTED:
|
||||
case BT_STATUS_FIRST_CONNECTED:
|
||||
if (app_protocol_check_connect_success()) {
|
||||
app_protocol_tone_play(APP_PROTOCOL_TONE_CONNECTED_ALL_FINISH, 1);
|
||||
} else {
|
||||
app_protocol_tone_play(APP_PROTOCOL_TONE_CONNECTED_NEED_OPEN_APP, 1);
|
||||
}
|
||||
break;
|
||||
case BT_STATUS_FIRST_DISCONNECT:
|
||||
case BT_STATUS_SECOND_DISCONNECT:
|
||||
app_protocol_tone_play(APP_PROTOCOL_TONE_DISCONNECTED, 1);
|
||||
app_protocal_update_tws_state_to_lib(USER_NOTIFY_STATE_MOBILE_DISCONNECTED);
|
||||
break;
|
||||
case BT_STATUS_PHONE_INCOME:
|
||||
case BT_STATUS_PHONE_OUT:
|
||||
case BT_STATUS_PHONE_ACTIVE:
|
||||
__app_protocol_speech_stop();
|
||||
app_protocol_ble_adv_switch(0);
|
||||
break;
|
||||
case BT_STATUS_PHONE_HANGUP:
|
||||
app_protocol_ble_adv_switch(1);
|
||||
break;
|
||||
|
||||
case BT_STATUS_PHONE_MANUFACTURER:
|
||||
if (!app_protocol_check_connect_success()) {
|
||||
if (is_ios_system()) {
|
||||
app_protocol_ibeacon_switch(1);
|
||||
}
|
||||
|
||||
if (get_call_status() != BT_CALL_HANGUP) {
|
||||
app_protocol_ble_adv_switch(0);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case BT_STATUS_VOICE_RECOGNITION:
|
||||
if ((app_var.siri_stu == 1) || (app_var.siri_stu == 2)) {
|
||||
__app_protocol_speech_stop();
|
||||
app_protocol_ble_adv_switch(0);
|
||||
} else if (app_var.siri_stu == 0) {
|
||||
app_protocol_ble_adv_switch(1);
|
||||
}
|
||||
break;
|
||||
case BT_STATUS_CONN_A2DP_CH:
|
||||
app_protocal_update_tws_state_to_lib(USER_NOTIFY_STATE_MOBILE_CONNECTED);
|
||||
break;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void app_protocol_bt_tws_event_handler(struct bt_event *bt)
|
||||
{
|
||||
int role = bt->args[0];
|
||||
int phone_link_connection = bt->args[1];
|
||||
int reason = bt->args[2];
|
||||
|
||||
switch (bt->event) {
|
||||
case TWS_EVENT_CONNECTED:
|
||||
if (!is_tws_master_role()) {
|
||||
app_protocol_disconnect(NULL);
|
||||
app_protocol_ble_adv_switch(0);
|
||||
} else {
|
||||
#if APP_PROTOCOL_SPEECH_EN
|
||||
if (ai_mic_is_busy()) { //mic在解码过程中,从机连接成功,挂起音频
|
||||
ai_mic_tws_sync_suspend();
|
||||
}
|
||||
#endif
|
||||
}
|
||||
app_protocal_update_tws_state_to_lib(USER_NOTIFY_STATE_TWS_CONNECT);
|
||||
break;
|
||||
case TWS_EVENT_CONNECTION_DETACH:
|
||||
if (!app_protocol_check_connect_success()) { //APP未连接,开启广播
|
||||
if (0 == get_esco_coder_busy_flag()) {
|
||||
//esco在用的时候开广播会影响质量
|
||||
app_protocol_ble_adv_switch(1);
|
||||
}
|
||||
}
|
||||
#if APP_PROTOCOL_SPEECH_EN
|
||||
if (!ai_mic_is_busy()) {
|
||||
__app_protocol_speech_stop(); //对耳断开时没启动mic,停止语音
|
||||
}
|
||||
#endif
|
||||
app_protocal_update_tws_state_to_lib(USER_NOTIFY_STATE_BATTERY_LEVEL_UPDATE); //主动上报电量
|
||||
app_protocal_update_tws_state_to_lib(USER_NOTIFY_STATE_TWS_DISCONNECT);
|
||||
break;
|
||||
case TWS_EVENT_ROLE_SWITCH:
|
||||
app_protocal_update_tws_state_to_lib(USER_NOTIFY_STATE_ROLE_SWITCH_FINISH);
|
||||
app_protocol_disconnect(NULL);
|
||||
if (role == TWS_ROLE_MASTER && (0 == get_esco_coder_busy_flag())) {
|
||||
app_protocol_ble_adv_switch(1);
|
||||
} else {
|
||||
app_protocol_ble_adv_switch(0);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static int app_protocol_bt_ai_event_handler(struct bt_event *bt)
|
||||
{
|
||||
switch (bt->event) {
|
||||
#if APP_PROTOCOL_SPEECH_EN
|
||||
case AI_EVENT_SPEECH_START:
|
||||
APP_PROTOCOL_LOG("AI_EVENT_SPEECH_START");
|
||||
__app_protocol_speech_start();
|
||||
break;
|
||||
case AI_EVENT_SPEECH_STOP:
|
||||
APP_PROTOCOL_LOG("AI_EVENT_SPEECH_STOP");
|
||||
__app_protocol_speech_stop();
|
||||
break;
|
||||
#endif
|
||||
case AI_EVENT_APP_CONNECT:
|
||||
APP_PROTOCOL_LOG("AI_EVENT_APP_CONNECT");
|
||||
if (get_curr_channel_state()&A2DP_CH) {
|
||||
app_protocol_tone_play(APP_PROTOCOL_TONE_CONNECTED_ALL_FINISH, 1);
|
||||
} else {
|
||||
app_protocol_tone_play(APP_PROTOCOL_TONE_PROTOCOL_CONNECTED, 1);
|
||||
}
|
||||
break;
|
||||
case AI_EVENT_APP_DISCONNECT:
|
||||
APP_PROTOCOL_LOG("AI_EVENT_APP_DISCONNECT");
|
||||
__app_protocol_speech_stop();
|
||||
break;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int app_protocol_sys_event_handler(struct sys_event *event)
|
||||
{
|
||||
#if TCFG_USER_GFPS_PROCESS_CTL
|
||||
if (app_user_protocol_sys_event_remap_hdl(event) == true) {
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
switch (event->type) {
|
||||
case SYS_BT_EVENT:
|
||||
if ((u32)event->arg == SYS_BT_EVENT_TYPE_CON_STATUS) {
|
||||
app_protocol_bt_status_event_handler(&event->u.bt);
|
||||
}
|
||||
#if TCFG_USER_TWS_ENABLE
|
||||
else if (((u32)event->arg == SYS_BT_EVENT_FROM_TWS)) {
|
||||
app_protocol_bt_tws_event_handler(&event->u.bt);
|
||||
}
|
||||
#endif
|
||||
else if (((u32)event->arg == SYS_BT_AI_EVENT_TYPE_STATUS)) {
|
||||
app_protocol_bt_ai_event_handler(&event->u.bt);
|
||||
}
|
||||
break;
|
||||
|
||||
case SYS_KEY_EVENT:
|
||||
app_protocol_key_event_handler(event);
|
||||
break;
|
||||
}
|
||||
app_protocol_sys_event_private_deal(event);
|
||||
|
||||
return 0;
|
||||
}
|
||||
void tell_lib_start_role_switch()
|
||||
{
|
||||
app_protocol_ble_adv_switch(0);
|
||||
if (is_tws_master_role()) {
|
||||
printf("master dev will role switch\n");
|
||||
app_protocal_update_tws_state_to_lib(USER_NOTIFY_STATE_ROLE_SWITCH_START);
|
||||
/* os_time_dly(10); */
|
||||
}
|
||||
}
|
||||
#else
|
||||
int app_protocol_sys_event_handler(struct sys_event *event)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
void tell_lib_start_role_switch()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
108
apps/common/third_party_profile/interface/app_protocol_common.h
Normal file
108
apps/common/third_party_profile/interface/app_protocol_common.h
Normal file
@ -0,0 +1,108 @@
|
||||
|
||||
|
||||
#ifndef _3TH_PROTOCOL_COMMON_H
|
||||
#define _3TH_PROTOCOL_COMMON_H
|
||||
|
||||
#include <string.h>
|
||||
#include <stdint.h>
|
||||
#include "typedef.h"
|
||||
#include "tone_player.h"
|
||||
#include "audio_base.h"
|
||||
#include "system/event.h"
|
||||
|
||||
#ifndef TONE_RES_ROOT_PATH
|
||||
#if TCFG_NOR_FS && (TCFG_VIRFAT_FLASH_ENABLE == 0)
|
||||
#define NOR_FLASH_RES_ROOT_PATH "storage/res_nor/C/"
|
||||
#define TONE_RES_ROOT_PATH NOR_FLASH_RES_ROOT_PATH //内置flash提示音根路径
|
||||
#else
|
||||
#define TONE_RES_ROOT_PATH SDFILE_RES_ROOT_PATH //内置flash提示音根路径
|
||||
#endif//TCFG_NOR_FS
|
||||
#endif
|
||||
|
||||
#define APP_PROTOCOL_TWS_SYNC_ID 0xFFFF321A
|
||||
#define APP_PROTOCOL_TWS_SEND_ID 0xFFFF321B
|
||||
|
||||
enum {
|
||||
APP_PROTOCOL_TONE_CONNECTED_ALL_FINISH = 0,//所有连接完成【已连接,你可以按AI键来和我进行对话】 ok
|
||||
APP_PROTOCOL_TONE_PROTOCOL_CONNECTED,//APP已连接,经典蓝牙未连接【请在手机上完成蓝牙配对】 con
|
||||
APP_PROTOCOL_TONE_CONNECTED_NEED_OPEN_APP,//经典蓝牙已连接,app未连接【已配对,请打开app进行连接】 btcon
|
||||
APP_PROTOCOL_TONE_DISCONNECTED,//经典蓝牙已断开【蓝牙已断开,请在手机上完成蓝牙配对】 dis
|
||||
APP_PROTOCOL_TONE_DISCONNECTED_ALL,//经典蓝牙和【蓝牙未连接,请用手机蓝牙和我连接吧】alldis
|
||||
APP_RROTOCOL_TONE_OPEN_APP,//经典蓝牙已连接,APP未连接【请打开APP】 app
|
||||
APP_RROTOCOL_TONE_SPEECH_APP_START,//手机APP启动语音助手
|
||||
APP_RROTOCOL_TONE_SPEECH_KEY_START,//按键启动语音助手
|
||||
APP_RROTOCOL_TONE_MAX,//提示音最大数量
|
||||
};
|
||||
|
||||
//发送给对耳的消息,格式为:opcode len data
|
||||
enum {
|
||||
APP_PROTOCOL_TWS_FOR_LIB = 0,
|
||||
|
||||
GMA_TWS_CMD_SYNC_LIC,
|
||||
};
|
||||
|
||||
//对耳同步的命令,格式为cmd value
|
||||
enum {
|
||||
APP_PROTOCOL_SYNC_TONE = 0,
|
||||
};
|
||||
|
||||
//发送到系统事件处理的事件
|
||||
enum {
|
||||
AI_EVENT_SPEECH_START = 0,
|
||||
AI_EVENT_SPEECH_STOP,
|
||||
AI_EVENT_APP_CONNECT,
|
||||
AI_EVENT_APP_DISCONNECT,
|
||||
};
|
||||
|
||||
struct app_protocol_private_handle_t {
|
||||
void (*tws_rx_from_siblling)(u16 opcode, u8 *data, u16 len); //收到对耳数据的处理接口
|
||||
void (*tws_sync_func)(int cmd, int value); //对耳同步执行的接口
|
||||
int (*sys_event_handler)(struct sys_event *event); //系统事件
|
||||
};
|
||||
|
||||
//提示音注册和播放
|
||||
void app_protocol_tone_register(const char **tone_table);
|
||||
const char *app_protocol_get_tone(int index);
|
||||
void app_protocol_tone_play(int index, int tws_sync);
|
||||
void app_speech_tone_play_end_callback(void *priv, int flag); //提示音播放完毕回调函数
|
||||
|
||||
|
||||
extern int ai_mic_is_busy(void); //mic正在被使用
|
||||
extern int ai_mic_rec_start(void); //启动mic和编码模块
|
||||
extern int ai_mic_rec_close(void); //停止mic和编码模块
|
||||
extern bool bt_is_sniff_close(void);
|
||||
|
||||
//语音识别接口
|
||||
int mic_rec_pram_init(/* const char **name, */u32 enc_type, u8 opus_type, u16(*speech_send)(u8 *buf, u16 len), u16 frame_num, u16 cbuf_size);
|
||||
int __app_protocol_speech_start(void);
|
||||
void __app_protocol_speech_stop(void);
|
||||
int app_protocol_start_speech_by_app(u8 tone_en); //APP启动
|
||||
int app_protocol_stop_speech_by_app(); //APP停止
|
||||
int app_protocol_start_speech_by_key(struct sys_event *event); //按键启动
|
||||
int app_protocol_stop_speech_by_key(void); //按键停止
|
||||
|
||||
|
||||
//协议获取和设置一些设备信息接口
|
||||
int app_protocol_set_volume(u8 vol);
|
||||
u8 app_protocal_get_bat_by_type(u8 type);
|
||||
u32 read_cfg_file(void *buf, u16 len, char *path);
|
||||
const u8 *app_protocal_get_license_ptr(void); //获取三元组信息的头指针
|
||||
int app_protocol_license2flash(const u8 *data, u16 len); //将三元组信息保存到flash里面
|
||||
|
||||
//事件处理函数指针列表注册和接口
|
||||
void app_protocol_handle_register(struct app_protocol_private_handle_t *hd);
|
||||
struct app_protocol_private_handle_t *app_protocol_get_handle();
|
||||
void app_protocol_tws_sync_private_deal(int cmd, int value); //对耳同步事件私有协议处理函数
|
||||
void app_protocol_tws_rx_data_private_deal(u16 opcode, u8 *data, u16 len); //私有协议处理来自对耳的数据函数
|
||||
int app_protocol_sys_event_private_deal(struct sys_event *event); //私有协议处理系统事件函数
|
||||
|
||||
void app_protocol_post_bt_event(u8 event, void *priv); //发送到系统事件处理
|
||||
int app_protocol_post_app_core_callback(int callback, void *priv); //放到app_core中处理
|
||||
int app_protocol_tws_send_to_sibling(u16 opcode, u8 *data, u16 len); //发送命令数据给对耳
|
||||
int app_protocol_tws_sync_send(int cmd, int value); //对耳同步执行命令
|
||||
|
||||
int app_protocol_key_event_handler(struct sys_event *event); //按键事件处理函数
|
||||
int app_protocol_sys_event_handler(struct sys_event *event); //系统事件处理函数
|
||||
|
||||
#endif
|
||||
|
||||
147
apps/common/third_party_profile/interface/app_protocol_dma.c
Normal file
147
apps/common/third_party_profile/interface/app_protocol_dma.c
Normal file
@ -0,0 +1,147 @@
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "app_protocol_api.h"
|
||||
#include "system/includes.h"
|
||||
#include "vm.h"
|
||||
#include "audio_config.h"
|
||||
#include "app_power_manage.h"
|
||||
#include "user_cfg.h"
|
||||
#if APP_PROTOCOL_DMA_CODE
|
||||
|
||||
#if 1
|
||||
#define APP_DMA_LOG printf
|
||||
#define APP_DMA_DUMP put_buf
|
||||
#else
|
||||
#define APP_DMA_LOG(...)
|
||||
#define APP_DMA_DUMP(...)
|
||||
#endif
|
||||
|
||||
//*********************************************************************************//
|
||||
// DMA认证信息 //
|
||||
//*********************************************************************************//
|
||||
#define DMA_PRODUCT_INFO_TEST 0
|
||||
|
||||
#if DMA_PRODUCT_INFO_TEST
|
||||
static const char *dma_product_id = "abcdeYghv0fy6HFexl6bTIZU123Z4n6H";
|
||||
static const char *dma_triad_id = "A254BcBb000E00D200A0C0E3";
|
||||
static const char *dma_secret = "bab8d7e0dc616630";
|
||||
#endif
|
||||
static const char *dma_product_key = "rcPXDpFbBOxXaDL9GZ8qLTWq7Yz8rWFm";
|
||||
|
||||
#define DMA_PRODUCT_ID_LEN 65
|
||||
#define DMA_PRODUCT_KEY_LEN 65
|
||||
#define DMA_TRIAD_ID_LEN 32
|
||||
#define DMA_SECRET_LEN 32
|
||||
|
||||
#define DMA_LEGAL_CHAR(c) ((c >= '0' && c <= '9') || (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z'))
|
||||
|
||||
static u16 dma_get_one_info(const u8 *in, u8 *out)
|
||||
{
|
||||
int read_len = 0;
|
||||
const u8 *p = in;
|
||||
|
||||
while (DMA_LEGAL_CHAR(*p) && *p != ',') { //read Product ID
|
||||
*out++ = *p++;
|
||||
read_len++;
|
||||
}
|
||||
return read_len;
|
||||
}
|
||||
|
||||
u8 read_dma_product_info_from_flash(u8 *read_buf, u16 buflen)
|
||||
{
|
||||
u8 *rp = read_buf;
|
||||
const u8 *dma_ptr = (u8 *)app_protocal_get_license_ptr();
|
||||
|
||||
if (dma_ptr == NULL) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (dma_get_one_info(dma_ptr, rp) != 32) {
|
||||
return FALSE;
|
||||
}
|
||||
dma_ptr += 33;
|
||||
|
||||
rp = read_buf + DMA_PRODUCT_ID_LEN;
|
||||
memcpy(rp, dma_product_key, strlen(dma_product_key));
|
||||
|
||||
rp = read_buf + DMA_PRODUCT_ID_LEN + DMA_PRODUCT_KEY_LEN;
|
||||
if (dma_get_one_info(dma_ptr, rp) != 24) {
|
||||
return FALSE;
|
||||
}
|
||||
dma_ptr += 25;
|
||||
|
||||
rp = read_buf + DMA_PRODUCT_ID_LEN + DMA_PRODUCT_KEY_LEN + DMA_TRIAD_ID_LEN;
|
||||
if (dma_get_one_info(dma_ptr, rp) != 16) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
__attribute__((weak))
|
||||
void bt_update_testbox_addr(u8 *addr)
|
||||
{
|
||||
|
||||
}
|
||||
void dueros_dma_manufacturer_info_init()
|
||||
{
|
||||
u8 read_buf[DMA_PRODUCT_ID_LEN + DMA_PRODUCT_KEY_LEN + DMA_TRIAD_ID_LEN + DMA_SECRET_LEN + 1] = {0};
|
||||
bool ret = FALSE;
|
||||
|
||||
APP_DMA_LOG("dueros_dma_manufacturer_info_init\n");
|
||||
|
||||
#if DMA_PRODUCT_INFO_TEST
|
||||
memcpy(read_buf, dma_product_id, strlen(dma_product_id));
|
||||
memcpy(read_buf + DMA_PRODUCT_ID_LEN, dma_product_key, strlen(dma_product_key));
|
||||
memcpy(read_buf + DMA_PRODUCT_ID_LEN + DMA_PRODUCT_KEY_LEN, dma_triad_id, strlen(dma_triad_id));
|
||||
memcpy(read_buf + DMA_PRODUCT_ID_LEN + DMA_PRODUCT_KEY_LEN + DMA_TRIAD_ID_LEN, dma_secret, strlen(dma_secret));
|
||||
ret = TRUE;
|
||||
#else
|
||||
// ret = read_dma_product_info_from_flash(read_buf, sizeof(read_buf));
|
||||
#endif
|
||||
|
||||
if (ret == TRUE) {
|
||||
APP_DMA_LOG("read license success\n");
|
||||
APP_DMA_LOG("product id: %s\n", read_buf);
|
||||
APP_DMA_LOG("product key: %s\n", read_buf + DMA_PRODUCT_ID_LEN);
|
||||
APP_DMA_LOG("triad id: %s\n", read_buf + DMA_PRODUCT_ID_LEN + DMA_PRODUCT_KEY_LEN);
|
||||
APP_DMA_LOG("secret: %s\n", read_buf + DMA_PRODUCT_ID_LEN + DMA_PRODUCT_KEY_LEN + DMA_TRIAD_ID_LEN);
|
||||
app_protocol_set_info_group(DMA_HANDLER_ID, read_buf);
|
||||
} else {
|
||||
app_protocol_set_info_group(DMA_HANDLER_ID, NULL);
|
||||
}
|
||||
|
||||
#if 1
|
||||
u8 mac[] = {0xF4, 0x43, 0x8D, 0x29, 0x17, 0x02};
|
||||
u8 ble_mac[6];
|
||||
void bt_update_mac_addr(u8 * addr);
|
||||
void lmp_hci_write_local_address(const u8 * addr);
|
||||
void bt_update_testbox_addr(u8 * addr);
|
||||
extern int le_controller_set_mac(void *addr);
|
||||
//extern void lib_make_ble_address(u8 * ble_address, u8 * edr_address);
|
||||
bt_update_mac_addr(mac);
|
||||
lmp_hci_write_local_address(mac);
|
||||
bt_update_testbox_addr(mac);
|
||||
//lib_make_ble_address(ble_mac, mac);
|
||||
le_controller_set_mac(mac); //修改BLE地址
|
||||
APP_DMA_DUMP(mac, 6);
|
||||
APP_DMA_DUMP(ble_mac, 6);
|
||||
#endif
|
||||
}
|
||||
|
||||
//*********************************************************************************//
|
||||
// DMA提示音 //
|
||||
//*********************************************************************************//
|
||||
const char *dma_notice_tab[APP_RROTOCOL_TONE_MAX] = {
|
||||
[APP_PROTOCOL_TONE_CONNECTED_ALL_FINISH] = TONE_RES_ROOT_PATH"tone/xd_ok.*",//所有连接完成【已连接,你可以按AI键来和我进行对话】
|
||||
[APP_PROTOCOL_TONE_PROTOCOL_CONNECTED] = TONE_RES_ROOT_PATH"tone/xd_con.*",//小度APP已连接,经典蓝牙未连接【请在手机上完成蓝牙配对】
|
||||
[APP_PROTOCOL_TONE_CONNECTED_NEED_OPEN_APP] = TONE_RES_ROOT_PATH"tone/xd_btcon.*",//经典蓝牙已连接,小度app未连接【已配对,请打开小度app进行连接】
|
||||
[APP_PROTOCOL_TONE_DISCONNECTED] = TONE_RES_ROOT_PATH"tone/xd_dis.*",//经典蓝牙已断开【蓝牙已断开,请在手机上完成蓝牙配对】
|
||||
[APP_PROTOCOL_TONE_DISCONNECTED_ALL] = TONE_RES_ROOT_PATH"tone/xd_alldis.*",//经典蓝牙和小度都断开了【蓝牙未连接,请用手机蓝牙和我连接吧】
|
||||
[APP_RROTOCOL_TONE_SPEECH_APP_START] = TONE_NORMAL,
|
||||
[APP_RROTOCOL_TONE_SPEECH_KEY_START] = TONE_NORMAL,
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
424
apps/common/third_party_profile/interface/app_protocol_gfps.c
Normal file
424
apps/common/third_party_profile/interface/app_protocol_gfps.c
Normal file
@ -0,0 +1,424 @@
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "app_protocol_api.h"
|
||||
#include "system/includes.h"
|
||||
#include "vm.h"
|
||||
#include "audio_config.h"
|
||||
#include "app_power_manage.h"
|
||||
#include "user_cfg.h"
|
||||
#include "earphone.h"
|
||||
#include "btstack/avctp_user.h"
|
||||
#include "btstack/bluetooth.h"
|
||||
#include "bt_tws.h"
|
||||
|
||||
#if AI_APP_PROTOCOL
|
||||
#if APP_PROTOCOL_GFPS_CODE
|
||||
|
||||
extern void *gfps_app_ble_hdl;
|
||||
/* extern u32 unactice_device_cmd_prepare(USER_CMD_TYPE cmd, u16 param_len, u8 *param); */
|
||||
extern void tws_dual_conn_close();
|
||||
extern int gfps_tws_data_deal(u8 *data, int len);
|
||||
extern void audio_app_volume_set(u8 state, s16 volume, u8 fade);
|
||||
extern bool get_gfps_pair_state(void);
|
||||
extern void set_gfps_pair_state(u8 state);
|
||||
extern void gfps_set_battery_ui_enable(uint8_t enable);
|
||||
extern void gfps_set_pair_mode(void *priv);
|
||||
extern void gfps_all_info_recover(u8 name_reset);
|
||||
extern void gfps_sibling_sync_info();
|
||||
extern int gfps_disconnect(void *addr);
|
||||
extern void gfps_bt_ble_adv_enable(u8 enable);
|
||||
extern void gfps_adv_interval_set(u16 value);
|
||||
extern void gfps_sibling_data_send(u8 type, u8 *data, u16 len);
|
||||
extern int gfps_ble_adv_enable(u8 enable);
|
||||
extern void gfps_battery_update(void);
|
||||
extern void bt_set_need_keep_scan(u8 en);
|
||||
extern int audio_digital_vol_update_parm(u8 dvol_idx, s32 param);
|
||||
extern void set_wait_poweroff_time(u16 time);
|
||||
|
||||
/**
|
||||
弹窗的逻辑:
|
||||
1、没有任何手机配对记录情况,广播初始配对广播。
|
||||
2、开机有配对记录广播后续配对广播,回连超时进入配对状态时,广播初始配对广播。
|
||||
3、回连手机发现linkkey_missing,且没有任何手机配对记录了,广播初始配对广播。
|
||||
4、连上任意一台手机后, 广播后续配对广播,断开进入配对状态也是广播后续配对广播。(客户要求断开后也广播初始配对广播)
|
||||
5、恢复出厂设置时,需要调用一下gfps_all_info_recover(1)清除一下GFP的账号信息和修改的蓝牙名字
|
||||
6、认证的时候,需要有一个UI来触发初始配对广播(调用gfps_set_pair_mode(NULL)),可以为长按左右耳5秒之类的
|
||||
7、耳机关机要关电量显示
|
||||
*/
|
||||
|
||||
#define TONE_GOOGLE "tone_en/google.*"
|
||||
#define GFPS_SIBLING_SYNC_TYPE_ADV_MAC_STATE 0x04
|
||||
|
||||
#define ADV_INIT_PAIR_IN_PAIR_MODE 0 //进入配对状态广播初始配对广播
|
||||
|
||||
struct gfps_protocol_t {
|
||||
u8 poweron_reconn;
|
||||
u8 close_icon;
|
||||
};
|
||||
static struct gfps_protocol_t gfps_protocol = {0};
|
||||
|
||||
#define __this (&gfps_protocol)
|
||||
|
||||
#define INIT_PAIR_ADV_INTERVAL 150
|
||||
#define SUBS_PAIR_ADV_INTERVAL 352
|
||||
|
||||
void gfps_set_pair_mode_by_user(u8 disconn_ble)
|
||||
{
|
||||
if (disconn_ble) {
|
||||
gfps_disconnect(NULL);
|
||||
}
|
||||
gfps_adv_interval_set(INIT_PAIR_ADV_INTERVAL);
|
||||
set_gfps_pair_state(0);
|
||||
gfps_bt_ble_adv_enable(0);
|
||||
gfps_bt_ble_adv_enable(1);
|
||||
}
|
||||
|
||||
//重写弱函数,获取电量
|
||||
extern u8 get_charge_online_flag(void);
|
||||
extern u8 get_tws_sibling_bat_persent(void);
|
||||
void generate_rfcomm_battery_data(u8 *data)
|
||||
{
|
||||
u8 self_val = get_charge_online_flag() << 7 | get_vbat_percent();
|
||||
#if TCFG_USER_TWS_ENABLE
|
||||
u8 sibling_val = get_tws_sibling_bat_persent();
|
||||
|
||||
data[2] = 0xFF; //充电仓电量
|
||||
|
||||
#if TCFG_CHARGESTORE_ENABLE
|
||||
if (self_val >> 7 || sibling_val >> 7) { //有任意一直耳机充电时才显示充电仓电量
|
||||
data[2] = chargestore_get_power_level(); //充电仓电量
|
||||
}
|
||||
#endif
|
||||
|
||||
data[0] = (tws_api_get_local_channel() == 'L') ? self_val : sibling_val; //左耳电量
|
||||
data[1] = (tws_api_get_local_channel() == 'R') ? self_val : sibling_val; //右耳电量
|
||||
#else
|
||||
data[0] = self_val;
|
||||
data[1] = 0xFF;
|
||||
data[2] = 0xFF;
|
||||
#endif
|
||||
printf("%s, l:%x, r:%x, bat:%x", __func__, data[0], data[1], data[2]);
|
||||
}
|
||||
|
||||
extern int lmp_hci_write_scan_enable(u8 enable);
|
||||
static void gfps_ctl_bt_enter_pair_mode()
|
||||
{
|
||||
printf("%s", __func__);
|
||||
tws_dual_conn_close();
|
||||
lmp_hci_write_scan_enable((1 << 1) | 1);
|
||||
bt_set_need_keep_scan(1);
|
||||
}
|
||||
|
||||
//重写弱函数,GFP-BLE配对认证成功后,需要先断开一个设备或者开可连接,等手机连接经典蓝牙
|
||||
extern u8 *get_cur_connect_phone_mac_addr(void);
|
||||
void gfps_before_pair_new_device(u8 *seeker_addr)
|
||||
{
|
||||
#if TCFG_USER_GFPS_PROCESS_CTL
|
||||
app_user_gfps_before_pair_new_device(seeker_addr);
|
||||
#else
|
||||
u8 remote_edr_addr[6];
|
||||
u8 *tmp_addr = NULL;
|
||||
|
||||
for (int i = 0; i < 6; i ++) {
|
||||
remote_edr_addr[i] = seeker_addr[5 - i];
|
||||
}
|
||||
|
||||
if (get_curr_channel_state()) {
|
||||
tmp_addr = get_cur_connect_phone_mac_addr();
|
||||
if (memcmp(tmp_addr, remote_edr_addr, 6) != 0) {
|
||||
printf("Subsequent pair\n");
|
||||
printf("USER_CTRL_DISCONNECTION_HCI send\n");
|
||||
user_send_cmd_prepare(USER_CTRL_DISCONNECTION_HCI, 0, NULL);
|
||||
} else {
|
||||
printf("Retroactive Pair\n");
|
||||
}
|
||||
}
|
||||
printf("func:%s, line:%d", __FUNCTION__, __LINE__);
|
||||
#endif
|
||||
}
|
||||
|
||||
struct google_tone_ctl_t {
|
||||
u8 l_en;
|
||||
u8 r_en;
|
||||
u8 l_mute;
|
||||
u8 r_mute;
|
||||
};
|
||||
static struct google_tone_ctl_t google_tone_ctl = {0};
|
||||
|
||||
static void google_tone_set_volume()
|
||||
{
|
||||
printf("google_tone_set_volume");
|
||||
/* printf("func:%s:%d", __FUNCTION__, app_audio_volume_max_query(SysVol_TONE)); */
|
||||
/* u32 param = VOLUME_NODE_CMD_SET_VOL | app_audio_volume_max_query(SysVol_TONE); */
|
||||
/* jlstream_set_node_param(NODE_UUID_VOLUME_CTRLER, "Vol_BtcRing", ¶m, sizeof(param)); */
|
||||
}
|
||||
|
||||
/* #if TCFG_USER_TWS_ENABLE */
|
||||
/* static void tws_google_tone_callback(int priv, enum stream_event event) */
|
||||
/* { */
|
||||
/* printf("func:%s, event:%d", __FUNCTION__, event); */
|
||||
/* if (event == STREAM_EVENT_START) { */
|
||||
/* int msg[] = {(int)google_tone_set_volume, 0}; */
|
||||
/* os_taskq_post_type("app_core", Q_CALLBACK, ARRAY_SIZE(msg), msg); */
|
||||
/* } */
|
||||
/* } */
|
||||
/* REGISTER_TWS_TONE_CALLBACK(tws_google_tone_stub) = { */
|
||||
/* .func_uuid = 0x2EC850AE, */
|
||||
/* .callback = tws_google_tone_callback, */
|
||||
/* }; */
|
||||
/* #endif */
|
||||
|
||||
/* static int google_tone_play_callback(void *priv, enum stream_event event) */
|
||||
/* { */
|
||||
/* printf("func:%s, event:%d", __FUNCTION__, event); */
|
||||
/* if (event == STREAM_EVENT_START) { */
|
||||
/* int msg[] = {(int)google_tone_set_volume, 0}; */
|
||||
/* os_taskq_post_type("app_core", Q_CALLBACK, ARRAY_SIZE(msg), msg); */
|
||||
/* } */
|
||||
/* return 0; */
|
||||
/* } */
|
||||
|
||||
void google_tone_play_deal()
|
||||
{
|
||||
if (strcmp(os_current_task(), "app_core")) {
|
||||
printf("%s, task:%s", __func__, os_current_task());
|
||||
int msg[] = {(int)google_tone_play_deal, 0};
|
||||
os_taskq_post_type("app_core", Q_CALLBACK, ARRAY_SIZE(msg), msg);
|
||||
return;
|
||||
}
|
||||
|
||||
/* tone_player_stop(); */
|
||||
/* tone_player_play(); */
|
||||
}
|
||||
|
||||
void google_tone_mute_ctl(u8 self, u8 charge_flag)
|
||||
{
|
||||
u8 *mute = &google_tone_ctl.l_mute;
|
||||
|
||||
if ((tws_api_get_local_channel() == 'L' && !self) ||
|
||||
(tws_api_get_local_channel() == 'R' && self)) {
|
||||
mute = &google_tone_ctl.r_mute;
|
||||
printf("%s, r_mute:%d, charge_flag:%d", __func__, *mute, charge_flag);
|
||||
} else {
|
||||
printf("%s, l_mute:%d, charge_flag:%d", __func__, *mute, charge_flag);
|
||||
}
|
||||
|
||||
if (*mute != charge_flag) {
|
||||
*mute = charge_flag;
|
||||
google_tone_play_deal();
|
||||
}
|
||||
}
|
||||
|
||||
int gfps_protocol_tws_send_to_sibling(u16 opcode, u8 *data, u16 len)
|
||||
{
|
||||
return tws_api_send_data_to_sibling(data, len, 0x23080315);
|
||||
}
|
||||
|
||||
static void __tws_rx_from_sibling(u8 *data, int len)
|
||||
{
|
||||
gfps_tws_data_deal(data, len);
|
||||
|
||||
switch (data[0]) {
|
||||
case GFPS_SIBLING_SYNC_TYPE_ADV_MAC_STATE:
|
||||
gfps_adv_interval_set(data[1] ? SUBS_PAIR_ADV_INTERVAL : INIT_PAIR_ADV_INTERVAL);
|
||||
set_gfps_pair_state(data[1]);
|
||||
le_controller_set_mac((void *)&data[2]);
|
||||
gfps_bt_ble_adv_enable(0);
|
||||
gfps_bt_ble_adv_enable(1);
|
||||
break;
|
||||
}
|
||||
free(data);
|
||||
}
|
||||
|
||||
static void gfps_protocol_rx_from_sibling(void *_data, u16 len, bool rx)
|
||||
{
|
||||
int err = 0;
|
||||
if (rx) {
|
||||
printf(">>>%s \n", __func__);
|
||||
printf("len :%d\n", len);
|
||||
put_buf(_data, len);
|
||||
|
||||
u8 *rx_data = malloc(len);
|
||||
if (!rx_data) {
|
||||
return;
|
||||
}
|
||||
|
||||
memcpy(rx_data, _data, len);
|
||||
|
||||
int msg[4];
|
||||
msg[0] = (int)__tws_rx_from_sibling;
|
||||
msg[1] = 2;
|
||||
msg[2] = (int)rx_data;
|
||||
msg[3] = (int)len;
|
||||
err = os_taskq_post_type("app_core", Q_CALLBACK, ARRAY_SIZE(msg), msg);
|
||||
if (err) {
|
||||
printf("tws rx post fail\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//发送给对耳
|
||||
REGISTER_TWS_FUNC_STUB(app_vol_sync_stub) = {
|
||||
.func_id = 0x23080315,
|
||||
.func = gfps_protocol_rx_from_sibling,
|
||||
};
|
||||
|
||||
int gfps_message_deal_handler(int id, int opcode, u8 *data, u32 len)
|
||||
{
|
||||
switch (opcode) {
|
||||
case APP_PROTOCOL_LIB_TWS_DATA_SYNC:
|
||||
gfps_protocol_tws_send_to_sibling(opcode, data, len);
|
||||
break;
|
||||
case APP_PROTOCOL_GFPS_RING_STOP_ALL:
|
||||
printf("GFPS_RING_STOP_ALL");
|
||||
google_tone_ctl.l_en = 0;
|
||||
google_tone_ctl.r_en = 0;
|
||||
google_tone_play_deal();
|
||||
break;
|
||||
case APP_PROTOCOL_GFPS_RING_RIGHT:
|
||||
printf("GFPS_RING_RIGHT");
|
||||
google_tone_ctl.l_en = 0;
|
||||
google_tone_ctl.r_en = 1;
|
||||
google_tone_play_deal();
|
||||
break;
|
||||
case APP_PROTOCOL_GFPS_RING_LEFT:
|
||||
printf("GFPS_RING_LEFT");
|
||||
google_tone_ctl.l_en = 1;
|
||||
google_tone_ctl.r_en = 0;
|
||||
google_tone_play_deal();
|
||||
break;
|
||||
case APP_PROTOCOL_GFPS_RING_ALL:
|
||||
printf("GFPS_RING_ALL");
|
||||
google_tone_ctl.l_en = 1;
|
||||
google_tone_ctl.r_en = 1;
|
||||
google_tone_play_deal();
|
||||
break;
|
||||
case APP_PROTOCOL_GFPS_HEARABLE_CONTROLS:
|
||||
printf("APP_PROTOCOL_GFPS_HEARABLE_CONTROLS display:%x settable:%x current:%x\n", data[0], data[1], data[2]);
|
||||
break;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
//关机广播收仓
|
||||
void gfps_need_adv_close_icon_set(u8 en)
|
||||
{
|
||||
printf("func:%s, en:%d", __FUNCTION__, en);
|
||||
__this->close_icon = en;
|
||||
}
|
||||
|
||||
void gfps_poweroff_adv_close_icon()
|
||||
{
|
||||
printf("func:%s, line:%d", __FUNCTION__, __LINE__);
|
||||
if (__this->close_icon) {
|
||||
void set_wait_poweroff_time(u16 time);
|
||||
set_wait_poweroff_time(2000); //广播800ms
|
||||
gfps_adv_interval_set(48); //连接上手机间隔改为30ms
|
||||
gfps_set_battery_ui_enable(0); //关闭电量显示,会重新开关广播
|
||||
}
|
||||
}
|
||||
|
||||
int gfps_hci_event_handler(struct bt_event *bt)
|
||||
{
|
||||
switch (bt->event) {
|
||||
case HCI_EVENT_DISCONNECTION_COMPLETE:
|
||||
switch (bt->value) {
|
||||
case ERROR_CODE_PIN_OR_KEY_MISSING:
|
||||
printf("GFP linkkey missing");
|
||||
if (!btstack_get_num_of_remote_device_recorded()) { //没有配对记录的时候,广播初始配对广播
|
||||
gfps_all_info_recover(0);
|
||||
gfps_adv_interval_set(INIT_PAIR_ADV_INTERVAL); //连接上手机间隔改为93.75ms
|
||||
gfps_set_pair_mode_by_user(0);
|
||||
}
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int gfps_bt_status_event_handler(struct bt_event *bt)
|
||||
{
|
||||
u8 ret = 0;
|
||||
switch (bt->event) {
|
||||
// 需要切换蓝牙的命令
|
||||
case BT_STATUS_A2DP_MEDIA_START:
|
||||
break;
|
||||
case BT_STATUS_INIT_OK:
|
||||
if (btstack_get_num_of_remote_device_recorded()) {
|
||||
__this->poweron_reconn = 1;
|
||||
}
|
||||
break;
|
||||
case BT_STATUS_SECOND_CONNECTED:
|
||||
case BT_STATUS_FIRST_CONNECTED:
|
||||
__this->poweron_reconn = 0;
|
||||
gfps_adv_interval_set(SUBS_PAIR_ADV_INTERVAL); //连接上手机间隔改为220ms,防止fast pair validator测试fail
|
||||
set_gfps_pair_state(1);
|
||||
gfps_bt_ble_adv_enable(0);
|
||||
gfps_bt_ble_adv_enable(1);
|
||||
break;
|
||||
case BT_STATUS_PHONE_INCOME:
|
||||
case BT_STATUS_PHONE_OUT:
|
||||
case BT_STATUS_PHONE_ACTIVE:
|
||||
gfps_ble_adv_enable(0);
|
||||
break;
|
||||
case BT_STATUS_PHONE_HANGUP:
|
||||
gfps_ble_adv_enable(1);
|
||||
break;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static int gfps_app_power_event_handler(struct device_event *dev)
|
||||
{
|
||||
switch (dev->event) {
|
||||
#if TCFG_USER_TWS_ENABLE
|
||||
case POWER_EVENT_SYNC_TWS_VBAT_LEVEL:
|
||||
printf("update gfps bat");
|
||||
if (get_tws_sibling_bat_persent() != 0xFF) {
|
||||
google_tone_mute_ctl(0, get_tws_sibling_bat_persent() >> 7);
|
||||
}
|
||||
gfps_battery_update();
|
||||
break;
|
||||
#endif
|
||||
case POWER_EVENT_POWER_CHANGE:
|
||||
printf("update gfps bat");
|
||||
google_tone_mute_ctl(1, get_charge_online_flag());
|
||||
gfps_battery_update();
|
||||
break;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int gfps_sys_event_handler_specific(struct sys_event *event)
|
||||
{
|
||||
switch (event->type) {
|
||||
case SYS_DEVICE_EVENT:
|
||||
if ((u32)event->arg == DEVICE_EVENT_FROM_POWER) {
|
||||
gfps_app_power_event_handler(&event->u.dev);
|
||||
}
|
||||
break;
|
||||
case SYS_BT_EVENT:
|
||||
if ((u32)event->arg == SYS_BT_EVENT_TYPE_CON_STATUS) {
|
||||
gfps_bt_status_event_handler(&event->u.bt);
|
||||
} else if ((u32)event->arg == SYS_BT_EVENT_TYPE_HCI_STATUS) {
|
||||
gfps_hci_event_handler(&event->u.bt);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
struct app_protocol_private_handle_t gfps_private_handle = {
|
||||
.sys_event_handler = gfps_sys_event_handler_specific,
|
||||
};
|
||||
|
||||
#endif
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
557
apps/common/third_party_profile/interface/app_protocol_gma.c
Normal file
557
apps/common/third_party_profile/interface/app_protocol_gma.c
Normal file
@ -0,0 +1,557 @@
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "app_protocol_api.h"
|
||||
#include "system/includes.h"
|
||||
#include "vm.h"
|
||||
#include "audio_config.h"
|
||||
#include "app_power_manage.h"
|
||||
#include "user_cfg.h"
|
||||
|
||||
#if APP_PROTOCOL_GMA_CODE
|
||||
|
||||
#if 1
|
||||
#define APP_GMA_LOG printf
|
||||
#define APP_GMA_DUMP put_buf
|
||||
#else
|
||||
#define APP_GMA_LOG(...)
|
||||
#define APP_GMA_DUMP(...)
|
||||
#endif
|
||||
|
||||
//*********************************************************************************//
|
||||
// GMA认证信息 //
|
||||
//*********************************************************************************//
|
||||
|
||||
#define GMA_GMA_FROM_FLASH 0
|
||||
#define GMA_GMA_FROM_FILE 1
|
||||
|
||||
#define GMA_GMA_SOURCH GMA_GMA_FROM_FLASH
|
||||
|
||||
|
||||
extern int le_controller_set_mac(void *addr);
|
||||
extern void lmp_hci_write_local_address(const u8 *addr);
|
||||
extern void lmp_hci_read_local_address(u8 *addr);
|
||||
extern void bt_update_testbox_addr(u8 *addr);
|
||||
|
||||
typedef struct {
|
||||
uint8_t mac[6];
|
||||
uint32_t pid;
|
||||
uint8_t secret[16];
|
||||
} ali_para_s;
|
||||
|
||||
static ali_para_s ali_para;
|
||||
static ali_para_s *active_ali_para = NULL;
|
||||
|
||||
///mac reverse
|
||||
void gma_mac_addr_reverse_get(uint8_t *buf)
|
||||
{
|
||||
memcpy(buf, (const void *)active_ali_para->mac, 6);
|
||||
}
|
||||
|
||||
#define LEGAL_PID_NUM(cha) (cha>='0' && cha<='9')
|
||||
#define LEGAL_MAC_NUM(cha) ((cha>='0'&&cha<='9') || (cha>='a'&&cha<='f') || (cha>='A'&&cha<='F') || (cha==':'))
|
||||
#define LEGAL_SECRET_NUM(cha) ((cha>='0'&&cha<='9') || (cha>='a'&&cha<='f') || (cha>='A'&&cha<='F'))
|
||||
|
||||
#define USELESS_CHAR ':'
|
||||
#define GMA_ALI_PARA_END_CHAR ','
|
||||
#define GMA_ALI_PARA_MAC_CHAR_NUMS (sizeof(((ali_para_s *)0)->mac))
|
||||
#define GMA_ALI_PARA_PID_CHAR_NUMS 4//(sizeof(((ali_para_s *)0)->pid))
|
||||
#define GMA_ALI_PARA_SECRET_CHAR_NUMS (sizeof(((ali_para_s *)0)->secret))
|
||||
|
||||
static u8 gma_ali_para_char2num(u8 cha)
|
||||
{
|
||||
u8 num = 0;
|
||||
|
||||
if (cha >= '0' && cha <= '9') {
|
||||
num = cha - '0';
|
||||
} else if (cha >= 'a' && cha <= 'f') {
|
||||
num = cha - 'a' + 10;
|
||||
} else if (cha >= 'A' && cha <= 'F') {
|
||||
num = cha - 'A' + 10;
|
||||
}
|
||||
|
||||
return num;
|
||||
}
|
||||
|
||||
static int gma_license_set(ali_para_s *ali_para)
|
||||
{
|
||||
const u8 *gma_ptr = (u8 *)app_protocal_get_license_ptr();
|
||||
|
||||
if (gma_ptr == NULL) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
///license fill
|
||||
//pid
|
||||
memcpy((u8 *) & (ali_para->pid), gma_ptr, sizeof(ali_para->pid));
|
||||
gma_ptr += sizeof(ali_para->pid);
|
||||
APP_GMA_LOG("gma pid:%d \n", ali_para->pid);
|
||||
//secret
|
||||
memcpy((u8 *)(ali_para->secret), gma_ptr, sizeof(ali_para->secret));
|
||||
gma_ptr += sizeof(ali_para->secret);
|
||||
APP_GMA_LOG("gma secret:");
|
||||
APP_GMA_DUMP(ali_para->secret, sizeof(ali_para->secret));
|
||||
//mac
|
||||
memcpy((u8 *)(ali_para->mac), gma_ptr, sizeof(ali_para->mac));
|
||||
gma_ptr += sizeof(ali_para->mac);
|
||||
{
|
||||
//mac reverse
|
||||
u8 mac_backup_buf[6];
|
||||
memcpy(mac_backup_buf, ali_para->mac, 6);
|
||||
int i;
|
||||
for (i = 0; i < 6; i++) {
|
||||
ali_para->mac[i] = (mac_backup_buf)[5 - i];
|
||||
}
|
||||
}
|
||||
APP_GMA_LOG("gma mac:");
|
||||
APP_GMA_DUMP(ali_para->mac, sizeof(ali_para->mac));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#if GMA_GMA_SOURCH == GMA_GMA_FROM_FILE
|
||||
|
||||
#define ALI_PARA_ACTIVE_NUM 1
|
||||
|
||||
static const char *ali_para_string[] = {
|
||||
"jl_auif",
|
||||
//Product ID,Device Secret,Mac,Md5
|
||||
//此处可以用户自行填写从阿里申请的三元组信息
|
||||
" ",
|
||||
};
|
||||
|
||||
static bool gma_ali_para_info_fill(const u8 *para, ali_para_s *ali_para)
|
||||
{
|
||||
const u8 *para_string = para;
|
||||
u8 highbit_en = 0;
|
||||
uint32_t pid = 0;
|
||||
uint32_t char_nums = 0;
|
||||
uint8_t *secret = ali_para->secret;
|
||||
uint8_t *mac = ali_para->mac;
|
||||
|
||||
while (*para_string && *para_string != GMA_ALI_PARA_END_CHAR) {
|
||||
if (!LEGAL_PID_NUM(*para_string)) {
|
||||
/* APP_GMA_LOG("pid illegal character !!! \n"); */
|
||||
para_string++;
|
||||
continue;
|
||||
}
|
||||
|
||||
///check pid character numbers legal scope
|
||||
char_nums++;
|
||||
if (char_nums > GMA_ALI_PARA_PID_CHAR_NUMS) {
|
||||
APP_GMA_LOG("pid character numbers overflow !!! \n");
|
||||
return false;
|
||||
}
|
||||
|
||||
pid *= 10;
|
||||
pid += gma_ali_para_char2num(*para_string);
|
||||
para_string++;
|
||||
}
|
||||
|
||||
///check pid character numbers legal scope
|
||||
if (char_nums != GMA_ALI_PARA_PID_CHAR_NUMS) {
|
||||
APP_GMA_LOG("pid character numbers error:%d !!! \n", char_nums);
|
||||
return false;
|
||||
}
|
||||
|
||||
APP_GMA_LOG(">>pid:%d \n", pid);
|
||||
ali_para->pid = pid;
|
||||
|
||||
para_string++;
|
||||
char_nums = 0;
|
||||
memset(ali_para->secret, 0x00, sizeof(ali_para->secret));
|
||||
while (*para_string != GMA_ALI_PARA_END_CHAR) {
|
||||
if (!LEGAL_SECRET_NUM(*para_string)) {
|
||||
APP_GMA_LOG("secret illegal character !!! \n");
|
||||
para_string++;
|
||||
continue;
|
||||
}
|
||||
|
||||
///assignment secret
|
||||
if (!highbit_en) {
|
||||
*secret += gma_ali_para_char2num(*para_string);
|
||||
highbit_en ^= 1;
|
||||
} else {
|
||||
///check secret character numbers legal scope
|
||||
char_nums++;
|
||||
if (char_nums > GMA_ALI_PARA_SECRET_CHAR_NUMS) {
|
||||
APP_GMA_LOG("secret character number overflow !!! \n");
|
||||
return false;
|
||||
}
|
||||
|
||||
*secret <<= 4;
|
||||
*secret++ += gma_ali_para_char2num(*para_string);
|
||||
highbit_en ^= 1;
|
||||
}
|
||||
|
||||
para_string++;
|
||||
}
|
||||
|
||||
///check secret character numbers legal scope
|
||||
if (char_nums != GMA_ALI_PARA_SECRET_CHAR_NUMS) {
|
||||
APP_GMA_LOG("secret character number error !!! :%d \n", char_nums);
|
||||
return false;
|
||||
}
|
||||
|
||||
///print secret
|
||||
APP_GMA_LOG(">>ali_para secret: ");
|
||||
for (int i = 0; i < sizeof(ali_para->secret) / sizeof(ali_para->secret[0]); i++) {
|
||||
APP_GMA_LOG("%x ", ali_para->secret[i]);
|
||||
}
|
||||
|
||||
memset(ali_para->mac, 0x00, sizeof(ali_para->mac));
|
||||
para_string++;
|
||||
highbit_en = 0;
|
||||
char_nums = 0;
|
||||
while (*para_string != GMA_ALI_PARA_END_CHAR) {
|
||||
//if legal character
|
||||
if (!LEGAL_MAC_NUM(*para_string)) {
|
||||
APP_GMA_LOG("mac illegal character !!! \n");
|
||||
para_string++;
|
||||
continue;
|
||||
// return false;
|
||||
}
|
||||
|
||||
if (*para_string == USELESS_CHAR) {
|
||||
para_string++;
|
||||
continue;
|
||||
}
|
||||
|
||||
///assignment mac
|
||||
if (!highbit_en) {
|
||||
*mac += gma_ali_para_char2num(*para_string);
|
||||
highbit_en ^= 1;
|
||||
} else {
|
||||
//check mac character numbers legal scope
|
||||
char_nums++;
|
||||
if (char_nums > GMA_ALI_PARA_MAC_CHAR_NUMS) {
|
||||
APP_GMA_LOG("mac character numbers overflow !!! \n");
|
||||
return false;
|
||||
}
|
||||
|
||||
*mac <<= 4;
|
||||
*mac++ += gma_ali_para_char2num(*para_string);
|
||||
highbit_en ^= 1;
|
||||
}
|
||||
|
||||
para_string++;
|
||||
}
|
||||
|
||||
//check mac character numbers legal scope
|
||||
if (char_nums != GMA_ALI_PARA_MAC_CHAR_NUMS) {
|
||||
APP_GMA_LOG("mac character numbers error !!! \n");
|
||||
return false;
|
||||
}
|
||||
|
||||
///mac reverse
|
||||
for (int i = 0, tmp_mac = 0, array_size = (sizeof(ali_para->mac) / sizeof(ali_para->mac[0])); \
|
||||
i < (sizeof(ali_para->mac) / sizeof(ali_para->mac[0]) / 2); i++) {
|
||||
tmp_mac = ali_para->mac[i];
|
||||
ali_para->mac[i] = ali_para->mac[array_size - 1 - i];
|
||||
ali_para->mac[array_size - 1 - i] = tmp_mac;
|
||||
}
|
||||
|
||||
///print secret
|
||||
APP_GMA_LOG(">>ali_para mac: ");
|
||||
for (int i = 0; i < sizeof(ali_para->mac) / sizeof(ali_para->mac[0]); i++) {
|
||||
APP_GMA_LOG("%x ", ali_para->mac[i]);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
static int gma_license2flash(const ali_para_s *ali_para)
|
||||
{
|
||||
int i;
|
||||
u8 mac[6];
|
||||
u8 rdata[sizeof(ali_para_s)];
|
||||
|
||||
for (i = 0; i < sizeof(mac); i++) {
|
||||
mac[i] = ali_para->mac[5 - i];
|
||||
}
|
||||
memcpy(rdata, &ali_para->pid, sizeof(ali_para->pid));
|
||||
memcpy(rdata + sizeof(ali_para->pid), ali_para->secret, sizeof(ali_para->secret));
|
||||
memcpy(rdata + sizeof(ali_para->pid) + sizeof(ali_para->secret), mac, sizeof(mac));
|
||||
|
||||
return app_protocol_license2flash(rdata, sizeof(rdata));
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
#if TCFG_USER_TWS_ENABLE
|
||||
#include "bt_tws.h"
|
||||
static ali_para_s ali_para_remote; //对耳的三元组
|
||||
|
||||
//VM_GMA_MAC 对耳的地址
|
||||
//VM_GMA_ALI_PARA 对耳的三元组
|
||||
|
||||
static int gma_strcmp(const u8 *ptr1, const u8 *ptr2, u8 len)
|
||||
{
|
||||
while (len--) {
|
||||
if (*ptr1 != *ptr2) {
|
||||
return (*ptr1 - *ptr2);
|
||||
}
|
||||
|
||||
ptr1++;
|
||||
ptr2++;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
///mac reverse
|
||||
u8 *gma_sibling_mac_get() //获取地址较小的那个
|
||||
{
|
||||
ali_para_s *sibling_ali_para = NULL;//&ali_para;
|
||||
if (active_ali_para == &ali_para) {
|
||||
printf("ali_para active \n");
|
||||
sibling_ali_para = &ali_para_remote;
|
||||
}
|
||||
|
||||
if (active_ali_para == &ali_para_remote) {
|
||||
printf("ali_para active \n");
|
||||
sibling_ali_para = &ali_para;
|
||||
}
|
||||
|
||||
return (sibling_ali_para ? sibling_ali_para->mac : NULL);
|
||||
}
|
||||
|
||||
int gma_select_ali_para_by_common_mac()
|
||||
{
|
||||
u8 ret = 0;
|
||||
u8 mac[6];
|
||||
u8 mac_buf_tmp[6] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF};
|
||||
ret = syscfg_read(CFG_TWS_COMMON_ADDR, mac, 6);
|
||||
if (ret != 6 || !memcmp(mac, mac_buf_tmp, 6)) {
|
||||
printf("tws no conn\n");
|
||||
return -1;
|
||||
}
|
||||
APP_GMA_LOG("active mac:");
|
||||
APP_GMA_DUMP(mac, 6);
|
||||
///select para
|
||||
ali_para_s ali_para_temp;
|
||||
syscfg_read(VM_GMA_ALI_PARA, (u8 *) &ali_para_temp, sizeof(ali_para_s));
|
||||
if (ali_para_temp.pid == ali_para.pid) {
|
||||
memcpy(&ali_para_remote, &ali_para_temp, sizeof(ali_para_s));
|
||||
APP_GMA_LOG("remote mac:");
|
||||
APP_GMA_DUMP(ali_para_remote.mac, 6);
|
||||
APP_GMA_LOG("remote pid:%d \n", ali_para_remote.pid);
|
||||
APP_GMA_LOG("remote secret:");
|
||||
APP_GMA_DUMP(ali_para_remote.secret, sizeof(ali_para_remote.secret));
|
||||
if (gma_strcmp(mac, ali_para_remote.mac, 6) == 0) {
|
||||
APP_GMA_LOG("used remote para \n");
|
||||
active_ali_para = &ali_para_remote;
|
||||
return 0;
|
||||
} else if (gma_strcmp(mac, ali_para.mac, 6) == 0) {
|
||||
APP_GMA_LOG("used local para \n");
|
||||
active_ali_para = &ali_para;
|
||||
return 0;
|
||||
} else {
|
||||
APP_GMA_LOG("MAC ERROR !!!!!!!!!!!!!!!!\n");
|
||||
return -1;
|
||||
}
|
||||
} else {
|
||||
APP_GMA_LOG("no remote mac \n");
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
void gma_slave_sync_remote_addr(u8 *buf)
|
||||
{
|
||||
u8 common_addr[6];
|
||||
///remote ali_para fill
|
||||
memcpy(&ali_para_remote, buf, sizeof(ali_para_remote));
|
||||
syscfg_write(VM_GMA_MAC, ali_para_remote.mac, 6);
|
||||
|
||||
///write ali para to vm
|
||||
syscfg_write(VM_GMA_ALI_PARA, (u8 *)&ali_para_remote, sizeof(ali_para_remote));
|
||||
|
||||
tws_api_get_local_addr(common_addr);
|
||||
if (memcmp(active_ali_para->mac, common_addr, 6)) { //common地址发生变化
|
||||
APP_GMA_LOG("gma addr change");
|
||||
///used slave address
|
||||
active_ali_para = &ali_para_remote;
|
||||
app_protocol_set_tws_sibling_mac(ali_para.mac);
|
||||
app_protocol_set_info_group(GMA_HANDLER_ID, active_ali_para); //设置三元组
|
||||
//断开APP接口
|
||||
if (is_tws_master_role()) {
|
||||
APP_GMA_LOG("gma need reconn app");
|
||||
app_protocol_disconnect(NULL);
|
||||
app_protocol_ble_adv_switch(0);
|
||||
le_controller_set_mac(active_ali_para->mac);
|
||||
app_protocol_ble_adv_switch(1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef CONFIG_NEW_BREDR_ENABLE
|
||||
void tws_host_get_common_addr(u8 *remote_addr, u8 *common_addr, char channel)
|
||||
#else
|
||||
void tws_host_get_common_addr(u8 *local_addr, u8 *remote_addr, u8 *common_addr, char channel)
|
||||
#endif
|
||||
{
|
||||
APP_GMA_LOG(">>>>>>>>>tws_host_get_common_addr ch:%c \n", channel);
|
||||
|
||||
u8 mac_buf[6];
|
||||
gma_mac_addr_reverse_get(mac_buf);
|
||||
APP_GMA_LOG(">>>local mac: ");
|
||||
APP_GMA_DUMP(mac_buf, 6);
|
||||
///used the bigger one as host bt mac
|
||||
if (gma_strcmp(mac_buf, (const u8 *)remote_addr, 6) < 0) {
|
||||
///used slave mac addr;remote_addr from slave addr reverse
|
||||
memcpy(common_addr, remote_addr, 6);
|
||||
} else {
|
||||
///used master mac addr
|
||||
gma_mac_addr_reverse_get(common_addr);
|
||||
}
|
||||
APP_GMA_LOG("common_addr: ");
|
||||
APP_GMA_DUMP((const u8 *)common_addr, 6);
|
||||
APP_GMA_LOG("remote_addr: ");
|
||||
APP_GMA_DUMP((const u8 *)remote_addr, 6);
|
||||
}
|
||||
|
||||
void gma_kick_license_to_sibling(void)
|
||||
{
|
||||
APP_GMA_LOG("send license info to sibling\n");
|
||||
app_protocol_tws_send_to_sibling(GMA_TWS_CMD_SYNC_LIC, (u8 *) & (ali_para), sizeof(ali_para));;
|
||||
}
|
||||
|
||||
void gma_tws_remove_paired(void)
|
||||
{
|
||||
ali_para_s ali_para_temp;
|
||||
memset(&ali_para_temp, 0xff, sizeof(ali_para_s));
|
||||
syscfg_write(VM_GMA_ALI_PARA, (u8 *)&ali_para_temp, sizeof(ali_para_s));
|
||||
|
||||
active_ali_para = &ali_para;
|
||||
app_protocol_set_tws_sibling_mac(ali_para_temp.mac);
|
||||
app_protocol_set_info_group(GMA_HANDLER_ID, active_ali_para); //设置三元组
|
||||
|
||||
app_protocol_disconnect(NULL);
|
||||
app_protocol_ble_adv_switch(0);
|
||||
le_controller_set_mac(active_ali_para->mac);
|
||||
app_protocol_ble_adv_switch(1);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
__attribute__((weak))
|
||||
void bt_update_testbox_addr(u8 *addr)
|
||||
{
|
||||
|
||||
}
|
||||
int gma_prev_init(void)
|
||||
{
|
||||
int err = 0;
|
||||
/* ali_para_s ali_para; */
|
||||
#if GMA_GMA_SOURCH == GMA_GMA_FROM_FLASH
|
||||
err = gma_license_set(&ali_para);
|
||||
#elif GMA_GMA_SOURCH == GMA_GMA_FROM_FILE
|
||||
u8 *ali_str = ali_para_string[ALI_PARA_ACTIVE_NUM];
|
||||
u8 ali_license[128] = {0};
|
||||
|
||||
//check if exist flash file
|
||||
if (read_cfg_file(ali_license, sizeof(ali_license), SDFILE_RES_ROOT_PATH"license.txt") == TRUE) {
|
||||
ali_str = ali_license;
|
||||
}
|
||||
APP_GMA_LOG("ali_str:%s\n", ali_str);
|
||||
if (gma_ali_para_info_fill((const u8 *)ali_str, &ali_para) == false) {
|
||||
APP_GMA_LOG("array context not good \n");
|
||||
///read license from flash
|
||||
err = gma_license_set(&ali_para);
|
||||
}
|
||||
///write license to flash
|
||||
if (!err) {
|
||||
gma_license2flash(&ali_para);
|
||||
}
|
||||
#endif
|
||||
if (!err) {
|
||||
active_ali_para = &ali_para;
|
||||
#if TCFG_USER_TWS_ENABLE
|
||||
if (!gma_select_ali_para_by_common_mac()) {
|
||||
app_protocol_set_tws_sibling_mac(gma_sibling_mac_get());
|
||||
}
|
||||
#endif
|
||||
app_protocol_set_info_group(GMA_HANDLER_ID, active_ali_para); //设置三元组
|
||||
bt_update_mac_addr(active_ali_para->mac);
|
||||
lmp_hci_write_local_address(active_ali_para->mac);
|
||||
app_protocol_ble_adv_switch(0);
|
||||
le_controller_set_mac(active_ali_para->mac); //修改BLE地址
|
||||
bt_update_testbox_addr(ali_para.mac);
|
||||
}
|
||||
return err;
|
||||
}
|
||||
|
||||
|
||||
//*********************************************************************************//
|
||||
// GMA 提示音 //
|
||||
//*********************************************************************************//
|
||||
const char *gma_tone_tab[APP_RROTOCOL_TONE_MAX] = {
|
||||
[APP_RROTOCOL_TONE_SPEECH_KEY_START] = TONE_NORMAL,
|
||||
};
|
||||
|
||||
//*********************************************************************************//
|
||||
// DMA私有消息处理 //
|
||||
//*********************************************************************************//
|
||||
#if TCFG_USER_TWS_ENABLE
|
||||
void gma_rx_tws_data_deal(u16 opcode, u8 *data, u16 len)
|
||||
{
|
||||
switch (opcode) {
|
||||
case GMA_TWS_CMD_SYNC_LIC:
|
||||
printf(">>> TWS_AI_GMA_START_SYNC_LIC \n");
|
||||
gma_slave_sync_remote_addr(data);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void gma_bt_tws_event_handler(struct bt_event *bt)
|
||||
{
|
||||
int role = bt->args[0];
|
||||
int phone_link_connection = bt->args[1];
|
||||
int reason = bt->args[2];
|
||||
|
||||
switch (bt->event) {
|
||||
case TWS_EVENT_CONNECTED:
|
||||
gma_kick_license_to_sibling();
|
||||
break;
|
||||
case TWS_EVENT_REMOVE_PAIRS:
|
||||
gma_tws_remove_paired();
|
||||
break;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
static int gma_bt_status_event_handler(struct bt_event *bt)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
int gma_sys_event_deal(struct sys_event *event)
|
||||
{
|
||||
switch (event->type) {
|
||||
case SYS_BT_EVENT:
|
||||
if ((u32)event->arg == SYS_BT_EVENT_TYPE_CON_STATUS) {
|
||||
gma_bt_status_event_handler(&event->u.bt);
|
||||
}
|
||||
#if TCFG_USER_TWS_ENABLE
|
||||
else if (((u32)event->arg == SYS_BT_EVENT_FROM_TWS)) {
|
||||
gma_bt_tws_event_handler(&event->u.bt);
|
||||
}
|
||||
#endif
|
||||
break;
|
||||
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
}
|
||||
|
||||
struct app_protocol_private_handle_t gma_private_handle = {
|
||||
#if TCFG_USER_TWS_ENABLE
|
||||
.tws_rx_from_siblling = gma_rx_tws_data_deal,
|
||||
#endif
|
||||
/* .tws_sync_func = ; */
|
||||
.sys_event_handler = gma_sys_event_deal,
|
||||
};
|
||||
#endif
|
||||
|
||||
146
apps/common/third_party_profile/interface/app_protocol_mma.c
Normal file
146
apps/common/third_party_profile/interface/app_protocol_mma.c
Normal file
@ -0,0 +1,146 @@
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "app_protocol_api.h"
|
||||
#include "system/includes.h"
|
||||
#include "audio_config.h"
|
||||
#include "app_power_manage.h"
|
||||
#include "user_cfg.h"
|
||||
#include "bt_tws.h"
|
||||
#include "custom_cfg.h"
|
||||
|
||||
#if APP_PROTOCOL_MMA_CODE
|
||||
|
||||
#if 1
|
||||
#define APP_MMA_LOG printf
|
||||
#define APP_MMA_DUMP put_buf
|
||||
#else
|
||||
#define APP_MMA_LOG(...)
|
||||
#define APP_MMA_DUMP(...)
|
||||
#endif
|
||||
//*********************************************************************************//
|
||||
// MMA初始化 //
|
||||
//*********************************************************************************//
|
||||
|
||||
void mma_prev_init()
|
||||
{
|
||||
u16 pid = 0x210c;
|
||||
u16 vid = 0x05d6;
|
||||
u16 ver = 0x1100;
|
||||
#if APP_PROTOCOL_READ_CFG_EN
|
||||
vid = get_vid_pid_ver_from_cfg_file(GET_VID_FROM_EX_CFG);
|
||||
pid = get_vid_pid_ver_from_cfg_file(GET_PID_FROM_EX_CFG);
|
||||
ver = get_vid_pid_ver_from_cfg_file(GET_VER_FROM_EX_CFG);
|
||||
#endif
|
||||
APP_MMA_LOG("mma pid:%x, vid:%x, ver:%x\n", pid, vid, ver);
|
||||
app_protocol_set_vendor_id(MMA_HANDLER_ID, vid);
|
||||
app_protocol_set_product_id(MMA_HANDLER_ID, pid);
|
||||
app_protocol_set_local_version(MMA_HANDLER_ID, ver);
|
||||
}
|
||||
|
||||
//*********************************************************************************//
|
||||
// MMA提示音 //
|
||||
//*********************************************************************************//
|
||||
const char *mma_notice_tab[APP_RROTOCOL_TONE_MAX] = {
|
||||
[APP_RROTOCOL_TONE_SPEECH_KEY_START] = TONE_NORMAL,
|
||||
};
|
||||
|
||||
//*********************************************************************************//
|
||||
// MMA私有消息处理 //
|
||||
//*********************************************************************************//
|
||||
|
||||
#if 1
|
||||
extern int le_controller_get_mac(void *addr);
|
||||
|
||||
#ifdef CONFIG_NEW_BREDR_ENABLE
|
||||
void tws_host_get_common_addr(u8 *remote_addr, u8 *common_addr, char channel)
|
||||
#else
|
||||
void tws_host_get_common_addr(u8 *local_addr, u8 *remote_addr, u8 *common_addr, char channel)
|
||||
#endif
|
||||
{
|
||||
APP_MMA_LOG(">>>>>>>>>tws_host_get_common_addr ch:%c \n", channel);
|
||||
|
||||
if (channel == 'L') {
|
||||
memcpy(common_addr, bt_get_mac_addr(), 6);
|
||||
} else {
|
||||
memcpy(common_addr, remote_addr, 6);
|
||||
}
|
||||
APP_MMA_LOG(">>>local mac: ");
|
||||
APP_MMA_DUMP(bt_get_mac_addr(), 6);
|
||||
APP_MMA_LOG("remote_addr: ");
|
||||
APP_MMA_DUMP((const u8 *)remote_addr, 6);
|
||||
APP_MMA_LOG("common_addr: ");
|
||||
APP_MMA_DUMP((const u8 *)common_addr, 6);
|
||||
}
|
||||
|
||||
static void mma_tws_get_data_analysis(u16 cmd, u8 *data, u16 len)
|
||||
{
|
||||
}
|
||||
|
||||
static void mma_update_ble_addr()
|
||||
{
|
||||
u8 ble_old_addr[6];
|
||||
u8 ble_new_addr[6];
|
||||
u8 comm_addr[6];
|
||||
tws_api_get_local_addr(comm_addr);
|
||||
le_controller_get_mac(ble_old_addr);
|
||||
void ble_update_address_tws_paired(u8 * comm_addr);
|
||||
ble_update_address_tws_paired(comm_addr);
|
||||
le_controller_get_mac(ble_new_addr);
|
||||
if (is_tws_master_role() && memcmp(ble_old_addr, ble_new_addr, 6)) {
|
||||
app_protocol_disconnect(NULL);
|
||||
app_protocol_ble_adv_switch(0);
|
||||
app_protocol_ble_adv_switch(1);
|
||||
}
|
||||
}
|
||||
|
||||
static void mma_bt_tws_event_handler(struct bt_event *bt)
|
||||
{
|
||||
int role = bt->args[0];
|
||||
int phone_link_connection = bt->args[1];
|
||||
int reason = bt->args[2];
|
||||
|
||||
switch (bt->event) {
|
||||
case TWS_EVENT_CONNECTED:
|
||||
mma_update_ble_addr();
|
||||
break;
|
||||
case TWS_EVENT_REMOVE_PAIRS:
|
||||
mma_update_ble_addr();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static int mma_bt_status_event_handler(struct bt_event *bt)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
int mma_sys_event_deal(struct sys_event *event)
|
||||
{
|
||||
switch (event->type) {
|
||||
case SYS_BT_EVENT:
|
||||
if ((u32)event->arg == SYS_BT_EVENT_TYPE_CON_STATUS) {
|
||||
mma_bt_status_event_handler(&event->u.bt);
|
||||
}
|
||||
#if TCFG_USER_TWS_ENABLE
|
||||
else if (((u32)event->arg == SYS_BT_EVENT_FROM_TWS)) {
|
||||
mma_bt_tws_event_handler(&event->u.bt);
|
||||
}
|
||||
#endif
|
||||
break;
|
||||
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
}
|
||||
|
||||
struct app_protocol_private_handle_t mma_private_handle = {
|
||||
/* .tws_rx_from_siblling = mma_tws_get_data_analysis, */
|
||||
.sys_event_handler = mma_sys_event_deal,
|
||||
};
|
||||
#endif
|
||||
#endif
|
||||
|
||||
527
apps/common/third_party_profile/interface/app_protocol_ota.c
Normal file
527
apps/common/third_party_profile/interface/app_protocol_ota.c
Normal file
@ -0,0 +1,527 @@
|
||||
#include "app_config.h"
|
||||
|
||||
#if AI_APP_PROTOCOL
|
||||
#include "app_protocol_ota.h"
|
||||
#include "app_protocol_api.h"
|
||||
#include "fs.h"
|
||||
#include "os/os_error.h"
|
||||
#include "update_loader_download.h"
|
||||
#include "dual_bank_updata_api.h"
|
||||
#include "update.h"
|
||||
#include "timer.h"
|
||||
#include "debug.h"
|
||||
|
||||
#define LOG_TAG_CONST APP_OTA
|
||||
#define LOG_TAG "[APP_OTA]"
|
||||
|
||||
|
||||
int clk_set(const char *name, int clk);
|
||||
update_op_tws_api_t *get_tws_update_api(void);
|
||||
void tws_sync_update_crc_handler_register(void (*crc_init_hdl)(void), u32(*crc_calc_hdl)(u32 init_crc, u8 *data, u32 len));
|
||||
|
||||
#define APP_UPDATE_FAILED 0
|
||||
#define APP_UPDATE_SUCC 1
|
||||
|
||||
#define APP_CHECK_CRC_SUCC 0
|
||||
#define APP_CHECK_CRC_FAILED 1
|
||||
|
||||
typedef struct _app_protocol_ota_param_t {
|
||||
u32 state;
|
||||
u32 read_len;
|
||||
u32 need_rx_len;
|
||||
u8 *read_buf;
|
||||
void (*resume_hdl)(void *priv);
|
||||
int (*sleep_hdl)(void *priv);
|
||||
app_protocol_ota_api ota_api;
|
||||
u32 file_offset;
|
||||
u8 seek_type;
|
||||
u8 update_result;
|
||||
u8 sync_update_first_packet;
|
||||
u8 ota_cancle_flag;
|
||||
u8 wait_app_reboot;
|
||||
OS_SEM ota_sem;
|
||||
} app_protocol_ota_param_t;
|
||||
|
||||
static app_protocol_ota_param_t app_protocol_ota_param;
|
||||
static update_op_tws_api_t *app_protocol_update_tws_api = NULL;
|
||||
|
||||
#define __this (&app_protocol_ota_param)
|
||||
|
||||
enum {
|
||||
BT_SEEK_SET = 0x01,
|
||||
BT_SEEK_CUR = 0x02,
|
||||
BT_SEEK_TYPE_UPDATE_LEN = 0x10,
|
||||
};
|
||||
|
||||
typedef enum {
|
||||
UPDATA_START = 0x00,
|
||||
UPDATA_REV_DATA,
|
||||
UPDATA_STOP,
|
||||
} UPDATA_BIT_FLAG;
|
||||
|
||||
#define RETRY_TIMES 3
|
||||
|
||||
const app_protocol_ota_type_map ota_type_map[] = {
|
||||
{.protocol_id = GMA_HANDLER_ID, .ota_type = PASSIVE_OTA},
|
||||
{.protocol_id = MMA_HANDLER_ID, .ota_type = INITIATIVE_OTA},
|
||||
{.protocol_id = DMA_HANDLER_ID, .ota_type = NO_SUPPORT_OTA},
|
||||
{.protocol_id = TME_HANDLER_ID, .ota_type = INITIATIVE_OTA},
|
||||
{.protocol_id = AMA_HANDLER_ID, .ota_type = NO_SUPPORT_OTA},
|
||||
};
|
||||
|
||||
//根据protocol_id获取协议升级类型
|
||||
u8 check_ota_type_by_protocol_id(int id)
|
||||
{
|
||||
u8 i = 0;
|
||||
for (; i < sizeof(ota_type_map) / sizeof(app_protocol_ota_type_map); i++) {
|
||||
if (id == ota_type_map[i].protocol_id) {
|
||||
return ota_type_map[i].ota_type;
|
||||
}
|
||||
}
|
||||
return NO_SUPPORT_OTA;
|
||||
}
|
||||
|
||||
static void initiative_ota_resume_hdl_register(void (*resume_hdl)(void *priv), int (*sleep_hdl)(void *priv))
|
||||
{
|
||||
__this->resume_hdl = resume_hdl;
|
||||
__this->sleep_hdl = sleep_hdl;
|
||||
}
|
||||
|
||||
void app_protocol_ota_init(app_protocol_ota_api *api, u8 need_wait_app_reboot)
|
||||
{
|
||||
memcpy(&(__this->ota_api), api, sizeof(app_protocol_ota_api));
|
||||
__this->wait_app_reboot = need_wait_app_reboot;
|
||||
#if OTA_TWS_SAME_TIME_ENABLE
|
||||
tws_sync_update_crc_handler_register(__this->ota_api.ota_crc_init_hdl, __this->ota_api.ota_crc_calc_hdl);
|
||||
g_printf("crc_init_hdl:0x%x crc_calc_hdl:0x%x\n", __this->ota_api.ota_crc_init_hdl, __this->ota_api.ota_crc_calc_hdl);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
void initiative_ota_init(void (*resume_hdl)(void *priv), int (*sleep_hdl)(void *priv))
|
||||
{
|
||||
os_sem_create(&(__this->ota_sem), 0);
|
||||
initiative_ota_resume_hdl_register(resume_hdl, sleep_hdl);
|
||||
}
|
||||
|
||||
u16 initiative_ota_f_open(void)
|
||||
{
|
||||
log_info(">>>initiative_ota_f_open\n");
|
||||
__this->file_offset = 0;
|
||||
__this->seek_type = BT_SEEK_SET;
|
||||
return 1;
|
||||
}
|
||||
|
||||
void initiative_ota_handle(u8 state, void *buf, int len)
|
||||
{
|
||||
/* log_info("R"); */
|
||||
if (state != __this->state) {
|
||||
log_info(">>>initiative state err\n");
|
||||
return;
|
||||
}
|
||||
|
||||
switch (state) {
|
||||
case UPDATA_REV_DATA:
|
||||
if (__this->read_buf) {
|
||||
memcpy(__this->read_buf, buf, len);
|
||||
__this->read_len = len;
|
||||
__this->state = 0;
|
||||
}
|
||||
break;
|
||||
|
||||
case UPDATA_STOP:
|
||||
__this->state = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
if (__this->resume_hdl) {
|
||||
__this->resume_hdl(NULL);
|
||||
}
|
||||
}
|
||||
|
||||
u16 initiative_ota_f_read(void *fp, u8 *buff, u16 len)
|
||||
{
|
||||
u8 retry_cnt = 0;
|
||||
|
||||
__this->need_rx_len = len;
|
||||
__this->state = UPDATA_REV_DATA;
|
||||
__this->read_len = 0;
|
||||
__this->read_buf = buff;
|
||||
|
||||
__RETRY:
|
||||
if (app_protocol_get_cur_handle_id() == 0) { //如果已经断开连接直接返回-1 */
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (__this->ota_cancle_flag) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (__this->ota_api.ota_request_data == NULL) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
printf("initiative_ota_read\n");
|
||||
__this->ota_api.ota_request_data(fp, __this->file_offset, len);
|
||||
|
||||
while (!((0 == __this->state) && (__this->read_len == len))) {
|
||||
if (__this->sleep_hdl && app_protocol_get_cur_handle_id()) {
|
||||
__this->sleep_hdl(NULL);
|
||||
} else {
|
||||
len = -1;
|
||||
break;
|
||||
}
|
||||
|
||||
if (!((0 == __this->state) && (__this->read_len == len))) {
|
||||
if (retry_cnt++ > RETRY_TIMES) {
|
||||
len = (u16) - 1;
|
||||
break;
|
||||
} else {
|
||||
goto __RETRY;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ((u16) - 1 != len) {
|
||||
__this->file_offset += len;
|
||||
}
|
||||
|
||||
return len;
|
||||
}
|
||||
|
||||
int initiative_ota_f_seek(void *fp, u8 type, u32 offset)
|
||||
{
|
||||
if (type == SEEK_SET) {
|
||||
__this->file_offset = offset;
|
||||
__this->seek_type = BT_SEEK_SET;
|
||||
} else if (type == SEEK_CUR) {
|
||||
__this->file_offset += offset;
|
||||
__this->seek_type = BT_SEEK_CUR;
|
||||
}
|
||||
|
||||
return 0;//FR_OK;
|
||||
}
|
||||
|
||||
static u16 initiative_ota_f_stop(u8 err)
|
||||
{
|
||||
//err = update_result_handle(err);
|
||||
__this->state = UPDATA_STOP;
|
||||
log_info(">>>initiative_ota_stop:%x err:0x%x\n", __this->state, err);
|
||||
|
||||
if (__this->ota_cancle_flag) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (__this->ota_api.ota_request_data) {
|
||||
__this->ota_api.ota_request_data(NULL, 0, 0);
|
||||
}
|
||||
|
||||
while (!(0 == __this->state)) {
|
||||
if (__this->sleep_hdl) { // && get_rcsp_connect_status()) {
|
||||
if (__this->sleep_hdl(NULL) == OS_TIMEOUT) {
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (__this->ota_api.ota_report_result) {
|
||||
__this->ota_api.ota_report_result(err);
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int initiative_ota_notify_update_content_size(void *priv, u32 size)
|
||||
{
|
||||
int err;
|
||||
u8 data[4];
|
||||
/* WRITE_BIG_U32(data, size); */
|
||||
/* user_change_ble_conn_param(0); */
|
||||
log_info("send content_size:%x\n", size);
|
||||
if (__this->ota_api.ota_notify_file_size) {
|
||||
__this->ota_api.ota_notify_file_size(size);
|
||||
}
|
||||
/* err = JL_CMD_send(JL_OPCODE_NOTIFY_UPDATE_CONENT_SIZE, data, sizeof(data), JL_NEED_RESPOND); */
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
const update_op_api_t initiative_update_op = {
|
||||
.ch_init = initiative_ota_init,
|
||||
.f_open = initiative_ota_f_open,
|
||||
.f_read = initiative_ota_f_read,
|
||||
.f_seek = initiative_ota_f_seek,
|
||||
.f_stop = initiative_ota_f_stop,
|
||||
.notify_update_content_size = initiative_ota_notify_update_content_size,
|
||||
};
|
||||
|
||||
void app_protocol_ota_update_success_reset(void *priv)
|
||||
{
|
||||
cpu_reset();
|
||||
}
|
||||
|
||||
static void initiative_ota_state_cbk(int type, u32 state, void *priv)
|
||||
{
|
||||
update_ret_code_t *ret_code = (update_ret_code_t *)priv;
|
||||
if (ret_code) {
|
||||
log_info("state:%x err:%x\n", ret_code->stu, ret_code->err_code);
|
||||
}
|
||||
switch (state) {
|
||||
case UPDATE_CH_EXIT:
|
||||
if (UPDATE_DUAL_BANK_IS_SUPPORT()) {
|
||||
if ((0 == ret_code->stu) && (0 == ret_code->err_code)) {
|
||||
/* set_jl_update_flag(1); */
|
||||
log_info(">>>initiative update succ\n");
|
||||
update_result_set(UPDATA_SUCC);
|
||||
__this->update_result = APP_UPDATE_SUCC;
|
||||
#if !OTA_TWS_SAME_TIME_ENABLE
|
||||
sys_timeout_add(NULL, app_protocol_ota_update_success_reset, 2000); //延时一段时间再reset保证命令已经发送
|
||||
#endif
|
||||
} else {
|
||||
log_info(">>>initiative update failed\n");
|
||||
update_result_set(UPDATA_DEV_ERR);
|
||||
__this->update_result = APP_UPDATE_FAILED;
|
||||
}
|
||||
} else {
|
||||
if ((0 == ret_code->stu) && (0 == ret_code->err_code)) {
|
||||
__this->update_result = APP_UPDATE_SUCC;
|
||||
/* set_jl_update_flag(1); */
|
||||
}
|
||||
}
|
||||
os_sem_post(&(__this->ota_sem));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
//被动升级请求下一帧数据
|
||||
int passive_ota_write_callback(void *priv)
|
||||
{
|
||||
if (__this->ota_api.ota_request_data) {
|
||||
__this->ota_api.ota_request_data(NULL, 0, 0);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int passive_ota_set_boot_info_callback(int ret)
|
||||
{
|
||||
if (__this->ota_api.ota_report_result) {
|
||||
__this->ota_api.ota_report_result(ret);
|
||||
}
|
||||
|
||||
if (ret == 0) { //0表示boot info写成功
|
||||
#if OTA_TWS_SAME_TIME_ENABLE
|
||||
if (app_protocol_update_tws_api && app_protocol_update_tws_api->tws_ota_result_hdl && !__this->wait_app_reboot) {
|
||||
app_protocol_update_tws_api->tws_ota_result_hdl(0);
|
||||
}
|
||||
#else
|
||||
sys_timeout_add(NULL, app_protocol_ota_update_success_reset, 2000); //延时一段时间再reset保证命令已经发送
|
||||
#endif
|
||||
__this->update_result = APP_UPDATE_SUCC;
|
||||
} else {
|
||||
dual_bank_passive_update_exit(NULL);
|
||||
#if OTA_TWS_SAME_TIME_ENABLE
|
||||
if (app_protocol_update_tws_api && app_protocol_update_tws_api->tws_ota_err) {
|
||||
app_protocol_update_tws_api->tws_ota_err(0);
|
||||
}
|
||||
__this->update_result = APP_UPDATE_FAILED;
|
||||
#endif
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int passive_ota_crc_result_call_back(int crc_res)
|
||||
{
|
||||
if (crc_res) { //校验成功
|
||||
log_info("crc check succ, write boot_info\n");
|
||||
u8 update_boot_info_flag, verify_err;
|
||||
#if OTA_TWS_SAME_TIME_ENABLE
|
||||
if (app_protocol_update_tws_api && app_protocol_update_tws_api->exit_verify_hdl) {
|
||||
if (app_protocol_update_tws_api->exit_verify_hdl(&verify_err, &update_boot_info_flag)) {
|
||||
dual_bank_update_burn_boot_info((int (*)(int))passive_ota_set_boot_info_callback);
|
||||
} else { //从机写boot_info失败
|
||||
if (__this->ota_api.ota_report_result) {
|
||||
__this->ota_api.ota_report_result(APP_CHECK_CRC_FAILED);
|
||||
}
|
||||
if (app_protocol_update_tws_api && app_protocol_update_tws_api->tws_ota_err) { //通知从机升级失败
|
||||
app_protocol_update_tws_api->tws_ota_err(0);
|
||||
}
|
||||
__this->update_result = APP_UPDATE_FAILED;
|
||||
}
|
||||
} else
|
||||
#endif
|
||||
{
|
||||
dual_bank_update_burn_boot_info((int (*)(int))passive_ota_set_boot_info_callback);
|
||||
}
|
||||
} else { //校验失败
|
||||
if (__this->ota_api.ota_report_result) {
|
||||
__this->ota_api.ota_report_result(APP_CHECK_CRC_FAILED);
|
||||
}
|
||||
#if OTA_TWS_SAME_TIME_ENABLE
|
||||
if (app_protocol_update_tws_api && app_protocol_update_tws_api->tws_ota_err) { //通知从机升级失败
|
||||
app_protocol_update_tws_api->tws_ota_err(0);
|
||||
}
|
||||
#endif
|
||||
__this->update_result = APP_UPDATE_FAILED;
|
||||
//app_protocol_reply_frame_check_result(crc_res);
|
||||
dual_bank_passive_update_exit(NULL);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int app_protocol_ota_interrupt_by_disconnect(int id)
|
||||
{
|
||||
if (check_ota_type_by_protocol_id(id) == INITIATIVE_OTA) {
|
||||
|
||||
} else {
|
||||
#if OTA_TWS_SAME_TIME_ENABLE
|
||||
if (app_protocol_update_tws_api && app_protocol_update_tws_api->tws_ota_err) {
|
||||
app_protocol_update_tws_api->tws_ota_err(0);
|
||||
}
|
||||
#endif
|
||||
dual_bank_passive_update_exit(NULL);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int app_protocol_update_success_flag(void)
|
||||
{
|
||||
return __this->update_result;
|
||||
}
|
||||
|
||||
int app_protocol_ota_message_handler(int id, int opcode, u8 *data, u32 len)
|
||||
{
|
||||
int err_code = UPDATE_RESULT_ERR_NONE;
|
||||
int ret = 0;
|
||||
switch (opcode) {
|
||||
case APP_PROTOCOL_OTA_CHECK:
|
||||
log_info("APP_PROTOCOL_OTA_CHECK\n");
|
||||
ota_frame_info *frame_info = data;
|
||||
dual_bank_passive_update_init(frame_info->frame_crc, frame_info->frame_size, frame_info->max_pkt_len, NULL);
|
||||
ret = dual_bank_update_allow_check(frame_info->frame_size);
|
||||
if (ret) {
|
||||
err_code = UPDATE_RESULT_RESOURCE_LIMIT;
|
||||
dual_bank_passive_update_exit(NULL);
|
||||
} else { //for tws sync update init
|
||||
#if OTA_TWS_SAME_TIME_ENABLE
|
||||
app_protocol_update_tws_api = get_tws_update_api();
|
||||
struct __tws_ota_para tws_update_para;
|
||||
tws_update_para.fm_size = frame_info->frame_size;
|
||||
tws_update_para.fm_crc16 = frame_info->frame_crc;
|
||||
tws_update_para.max_pkt_len = frame_info->max_pkt_len;
|
||||
if (app_protocol_update_tws_api && app_protocol_update_tws_api->tws_ota_start) {
|
||||
if (app_protocol_update_tws_api->tws_ota_start(&tws_update_para)) {
|
||||
err_code = UPDATE_RESULT_OTA_TWS_START_ERR;
|
||||
dual_bank_passive_update_exit(NULL);
|
||||
}
|
||||
}
|
||||
__this->sync_update_first_packet = 1;
|
||||
#endif
|
||||
}
|
||||
break;
|
||||
|
||||
case APP_PROTOCOL_OTA_BEGIN:
|
||||
update_mode_info_t info = {
|
||||
.type = BLE_APP_UPDATA,
|
||||
.state_cbk = initiative_ota_state_cbk,
|
||||
.p_op_api = &initiative_update_op,
|
||||
.task_en = 1,
|
||||
};
|
||||
__this->ota_cancle_flag = 0;
|
||||
app_active_update_task_init(&info);
|
||||
break;
|
||||
|
||||
case APP_PROTOCOL_OTA_TRANS_DATA:
|
||||
log_info("APP_PROTOCOL_OTA_TRANS_DATA\n");
|
||||
if (check_ota_type_by_protocol_id(id) == INITIATIVE_OTA) {
|
||||
initiative_ota_handle(UPDATA_REV_DATA, data, len);
|
||||
} else {
|
||||
#if OTA_TWS_SAME_TIME_ENABLE
|
||||
if (!__this->sync_update_first_packet) { //第一次传输不需要pend
|
||||
if (app_protocol_update_tws_api && app_protocol_update_tws_api->tws_ota_data_send_pend) {
|
||||
if (app_protocol_update_tws_api->tws_ota_data_send_pend()) {
|
||||
log_info(" UPDATE_ERR_WAIT_TWS_RESPONSE_TIMEOUT\n");
|
||||
err_code = UPDATE_RESULT_OTA_TWS_NO_RSP;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
__this->sync_update_first_packet = 0;
|
||||
#endif
|
||||
dual_bank_update_write(data, len, passive_ota_write_callback);
|
||||
#if OTA_TWS_SAME_TIME_ENABLE
|
||||
if (app_protocol_update_tws_api && app_protocol_update_tws_api->tws_ota_data_send) {
|
||||
app_protocol_update_tws_api->tws_ota_data_send(data, len);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
break;
|
||||
|
||||
case APP_PROTOCOL_OTA_GET_APP_VERSION:
|
||||
u32 fm_version = app_protocol_get_version_by_id(id);
|
||||
break;
|
||||
|
||||
case APP_PROTOCOL_OTA_CHECK_CRC:
|
||||
if (check_ota_type_by_protocol_id(id) == INITIATIVE_OTA) {
|
||||
os_sem_pend(&(__this->ota_sem), 0);
|
||||
err_code = __this->update_result;
|
||||
} else {
|
||||
clk_set("sys", 120 * 1000000L); //提升主频加快CRC校验速度
|
||||
#if OTA_TWS_SAME_TIME_ENABLE
|
||||
if (app_protocol_update_tws_api && app_protocol_update_tws_api->tws_ota_data_send_pend) { //pend 最后一包数据
|
||||
if (app_protocol_update_tws_api->tws_ota_data_send_pend()) {
|
||||
log_info(" UPDATE_ERR_WAIT_TWS_RESPONSE_TIMEOUT\n");
|
||||
err_code = UPDATE_RESULT_OTA_TWS_NO_RSP;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (app_protocol_update_tws_api && app_protocol_update_tws_api->enter_verfiy_hdl) {
|
||||
if (app_protocol_update_tws_api->enter_verfiy_hdl(NULL)) { //从机校验CRC
|
||||
log_info("update enter verify err\n");
|
||||
if (__this->ota_api.ota_report_result) {
|
||||
__this->ota_api.ota_report_result(APP_CHECK_CRC_FAILED);
|
||||
}
|
||||
} else {
|
||||
log_info("update enter verify succ\n");
|
||||
dual_bank_update_verify(__this->ota_api.ota_crc_init_hdl, __this->ota_api.ota_crc_calc_hdl, passive_ota_crc_result_call_back);
|
||||
}
|
||||
} else
|
||||
#endif
|
||||
{
|
||||
dual_bank_update_verify(__this->ota_api.ota_crc_init_hdl, __this->ota_api.ota_crc_calc_hdl, passive_ota_crc_result_call_back);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case APP_PROTOCOL_OTA_CANCLE:
|
||||
__this->ota_cancle_flag = 1;
|
||||
break;
|
||||
|
||||
case APP_PROTOCOL_OTA_REBOOT:
|
||||
__this->state = 0;
|
||||
/* #if OTA_TWS_SAME_TIME_ENABLE //同步升级在update lib里进行重启 */
|
||||
/* g_printf("APP_PROTOCOL_OTA_REBOOT!!!\n"); */
|
||||
/* #else */
|
||||
/* cpu_reset(); */
|
||||
/* #endif */
|
||||
break;
|
||||
|
||||
case APP_PROTOCOL_OTA_PERCENT:
|
||||
|
||||
break;
|
||||
case APP_PROTOCOL_OTA_END:
|
||||
|
||||
break;
|
||||
case APP_PROTOCOL_OTA_SUCCESS:
|
||||
|
||||
break;
|
||||
case APP_PROTOCOL_OTA_FAIL:
|
||||
|
||||
break;
|
||||
}
|
||||
return err_code;
|
||||
}
|
||||
#endif
|
||||
28
apps/common/third_party_profile/interface/app_protocol_ota.h
Normal file
28
apps/common/third_party_profile/interface/app_protocol_ota.h
Normal file
@ -0,0 +1,28 @@
|
||||
#ifndef __APP_PROTOCOL_OTA_H__
|
||||
#define __APP_PROTOCOL_OTA_H__
|
||||
|
||||
#include "typedef.h"
|
||||
|
||||
#define NO_SUPPORT_OTA 0xff
|
||||
#define INITIATIVE_OTA 0x01
|
||||
#define PASSIVE_OTA 0x02
|
||||
|
||||
typedef struct app_protocol_ota_type_map_t {
|
||||
u32 protocol_id;
|
||||
u8 ota_type;
|
||||
} app_protocol_ota_type_map;
|
||||
|
||||
typedef struct app_protocol_ota_api_t {
|
||||
u32(*ota_request_data)(void *priv, u32 offset, u16 len);
|
||||
u32(*ota_report_result)(u8 result);
|
||||
void (*ota_notify_file_size)(u32 file_size);
|
||||
void (*ota_crc_init_hdl)(void);
|
||||
u16(*ota_crc_calc_hdl)(u16 init_crc, u8 *data, u32 len);
|
||||
} app_protocol_ota_api;
|
||||
|
||||
int app_protocol_ota_message_handler(int id, int opcode, u8 *data, u32 len);
|
||||
void app_protocol_ota_init(app_protocol_ota_api *api, u8 need_wait_app_reboot);
|
||||
int app_protocol_ota_interrupt_by_disconnect(int id);
|
||||
int app_protocol_update_success_flag(void);
|
||||
|
||||
#endif //__APP_PROTOCOL_OTA_H__
|
||||
126
apps/common/third_party_profile/interface/app_protocol_tme.c
Normal file
126
apps/common/third_party_profile/interface/app_protocol_tme.c
Normal file
@ -0,0 +1,126 @@
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "app_protocol_api.h"
|
||||
#include "system/includes.h"
|
||||
#include "audio_config.h"
|
||||
#include "app_power_manage.h"
|
||||
#include "user_cfg.h"
|
||||
#include "btstack/avctp_user.h"
|
||||
#include "bt_tws.h"
|
||||
|
||||
#if APP_PROTOCOL_TME_CODE
|
||||
|
||||
extern void TME_set_edr_connected(u8 flag);
|
||||
|
||||
//*********************************************************************************//
|
||||
// TME认证信息 //
|
||||
//*********************************************************************************//
|
||||
|
||||
//*********************************************************************************//
|
||||
// TME提示音 //
|
||||
//*********************************************************************************//
|
||||
const char *tme_notice_tab[APP_RROTOCOL_TONE_MAX] = {
|
||||
[APP_RROTOCOL_TONE_SPEECH_KEY_START] = TONE_NORMAL,
|
||||
};
|
||||
|
||||
//*********************************************************************************//
|
||||
// TME弱函数实现 //
|
||||
//*********************************************************************************//
|
||||
|
||||
//*********************************************************************************//
|
||||
// TME私有消息处理 //
|
||||
//*********************************************************************************//
|
||||
#if 1
|
||||
extern int le_controller_set_mac(void *addr);
|
||||
extern int le_controller_get_mac(void *addr);
|
||||
|
||||
#if TCFG_USER_TWS_ENABLE
|
||||
static void tme_tws_rx_from_sibling(u16 cmd, u8 *data, u16 len)
|
||||
{
|
||||
#if TCFG_USER_TWS_ENABLE
|
||||
switch (cmd) {
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
static void tme_update_ble_addr()
|
||||
{
|
||||
u8 ble_old_addr[6];
|
||||
u8 ble_new_addr[6];
|
||||
u8 comm_addr[6];
|
||||
|
||||
printf("%s\n", __func__);
|
||||
|
||||
tws_api_get_local_addr(comm_addr);
|
||||
le_controller_get_mac(ble_old_addr);
|
||||
lib_make_ble_address(ble_new_addr, comm_addr);
|
||||
le_controller_set_mac(ble_new_addr); //地址发生变化,更新地址
|
||||
if (is_tws_master_role() && memcmp(ble_old_addr, ble_new_addr, 6)) {
|
||||
app_protocol_disconnect(NULL);
|
||||
app_protocol_ble_adv_switch(0);
|
||||
app_protocol_ble_adv_switch(1);
|
||||
}
|
||||
}
|
||||
|
||||
static void tme_bt_tws_event_handler(struct bt_event *bt)
|
||||
{
|
||||
int role = bt->args[0];
|
||||
int phone_link_connection = bt->args[1];
|
||||
int reason = bt->args[2];
|
||||
|
||||
switch (bt->event) {
|
||||
case TWS_EVENT_CONNECTED:
|
||||
tme_update_ble_addr();
|
||||
if (BT_STATUS_WAITINT_CONN != get_bt_connect_status()) {
|
||||
TME_set_edr_connected(1);
|
||||
}
|
||||
break;
|
||||
case TWS_EVENT_REMOVE_PAIRS:
|
||||
tme_update_ble_addr();
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
#endif
|
||||
|
||||
static int tme_bt_status_event_handler(struct bt_event *bt)
|
||||
{
|
||||
switch (bt->event) {
|
||||
case BT_STATUS_SECOND_CONNECTED:
|
||||
case BT_STATUS_FIRST_CONNECTED:
|
||||
TME_set_edr_connected(1); //连接过经典蓝牙标志
|
||||
break;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int tme_sys_event_deal(struct sys_event *event)
|
||||
{
|
||||
switch (event->type) {
|
||||
case SYS_BT_EVENT:
|
||||
if ((u32)event->arg == SYS_BT_EVENT_TYPE_CON_STATUS) {
|
||||
tme_bt_status_event_handler(&event->u.bt);
|
||||
}
|
||||
#if TCFG_USER_TWS_ENABLE
|
||||
else if (((u32)event->arg == SYS_BT_EVENT_FROM_TWS)) {
|
||||
tme_bt_tws_event_handler(&event->u.bt);
|
||||
}
|
||||
#endif
|
||||
break;
|
||||
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
}
|
||||
|
||||
struct app_protocol_private_handle_t tme_private_handle = {
|
||||
/* .tws_rx_from_siblling = tme_tws_rx_from_sibling, */
|
||||
.sys_event_handler = tme_sys_event_deal,
|
||||
};
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
@ -0,0 +1,89 @@
|
||||
#include "adv_adaptive_noise_reduction.h"
|
||||
#include "syscfg_id.h"
|
||||
#include "user_cfg_id.h"
|
||||
#include "rcsp_adv_bluetooth.h"
|
||||
|
||||
#if (RCSP_ADV_EN && RCSP_ADV_ANC_VOICE && RCSP_ADV_ADAPTIVE_NOISE_REDUCTION)
|
||||
|
||||
#include "audio_anc.h"
|
||||
|
||||
|
||||
/**
|
||||
* @brief 获取自适应降噪信息开关
|
||||
*
|
||||
* @result 1:自适应降噪开 0:自适应降噪关
|
||||
*/
|
||||
int get_adaptive_noise_reduction_switch()
|
||||
{
|
||||
int sw_result = audio_anc_coeff_mode_get();
|
||||
return sw_result;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 开启自适应降噪
|
||||
*/
|
||||
void set_adaptive_noise_reduction_on()
|
||||
{
|
||||
audio_anc_coeff_adaptive_set(1, 1, 1);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 关闭自适应降噪
|
||||
*/
|
||||
void set_adaptive_noise_reduction_off()
|
||||
{
|
||||
audio_anc_coeff_adaptive_set(0, 1, 1);
|
||||
}
|
||||
|
||||
static u8 adaptive_noise_reduction_reseting = 0; // 重新检测状态,1:进行中 0:结束
|
||||
static u8 adaptive_noise_reduction_reset_result = 0; // 重新检测结果,1:失败 0:成功
|
||||
/**
|
||||
* @brief 自适应降噪重新检测
|
||||
*/
|
||||
void set_adaptive_noise_reduction_reset()
|
||||
{
|
||||
audio_anc_mode_ear_adaptive();
|
||||
adaptive_noise_reduction_reseting = 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 获取自适应降噪重新检测状态
|
||||
*
|
||||
* @result 1:进行中 0:结束
|
||||
*/
|
||||
u8 get_adaptive_noise_reduction_reset_status()
|
||||
{
|
||||
return adaptive_noise_reduction_reseting;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 获取自适应降噪重新检测结果
|
||||
*
|
||||
* @result 1:失败 0:成功
|
||||
*/
|
||||
u8 get_adaptive_noise_reduction_reset_result()
|
||||
{
|
||||
return adaptive_noise_reduction_reset_result;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 自适应降噪重新检测结果回调
|
||||
*/
|
||||
void set_adaptive_noise_reduction_reset_callback(u8 result)
|
||||
{
|
||||
adaptive_noise_reduction_reseting = 0;
|
||||
if (result != 0) {
|
||||
// 成功
|
||||
adaptive_noise_reduction_reset_result = 0;
|
||||
} else {
|
||||
// 失败
|
||||
adaptive_noise_reduction_reset_result = 1;
|
||||
}
|
||||
// 通知手机APP
|
||||
/* JL_rcsp_event_to_user(DEVICE_EVENT_FROM_RCSP, MSG_JL_UPDATE_ANC_VOICE, NULL, 0); */
|
||||
JL_rcsp_event_to_user(DEVICE_EVENT_FROM_RCSP, MSG_JL_UPDATE_ADAPTIVE_NOISE_REDUCTION, NULL, 0);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
@ -0,0 +1,48 @@
|
||||
#ifndef __ADV_ADAPTIVE_NOISE_REDUCTION_H__
|
||||
#define __ADV_ADAPTIVE_NOISE_REDUCTION_H__
|
||||
|
||||
#include "le_rcsp_adv_module.h"
|
||||
|
||||
/**
|
||||
* @brief 获取自适应降噪信息开关
|
||||
*
|
||||
* @result 1:自适应降噪开 0:自适应降噪关
|
||||
*/
|
||||
int get_adaptive_noise_reduction_switch();
|
||||
|
||||
/**
|
||||
* @brief 开启自适应降噪
|
||||
*/
|
||||
void set_adaptive_noise_reduction_on();
|
||||
|
||||
/**
|
||||
* @brief 关闭自适应降噪
|
||||
*/
|
||||
void set_adaptive_noise_reduction_off();
|
||||
|
||||
/**
|
||||
* @brief 自适应降噪重新检测
|
||||
*/
|
||||
void set_adaptive_noise_reduction_reset();
|
||||
|
||||
/**
|
||||
* @brief 获取自适应降噪重新检测状态
|
||||
*
|
||||
* @result 1:进行中 0:结束
|
||||
*/
|
||||
u8 get_adaptive_noise_reduction_reset_status();
|
||||
|
||||
/**
|
||||
* @brief 获取自适应降噪重新检测结果
|
||||
*
|
||||
* @result 1:失败 0:成功
|
||||
*/
|
||||
u8 get_adaptive_noise_reduction_reset_result();
|
||||
|
||||
/**
|
||||
* @brief 自适应降噪重新检测结果回调
|
||||
*/
|
||||
void set_adaptive_noise_reduction_reset_callback(u8 result);
|
||||
|
||||
#endif
|
||||
|
||||
@ -0,0 +1,54 @@
|
||||
#ifndef __ADV_AI_NO_PICK_H__
|
||||
#define __ADV_AI_NO_PICK_H__
|
||||
|
||||
#include "system/includes.h"
|
||||
|
||||
typedef enum {
|
||||
RCSP_AI_NO_PICK_SENSITIVITY_HIGH = 0x00,
|
||||
RCSP_AI_NO_PICK_SENSITIVITY_LOW = 0x01,
|
||||
} RCSP_AI_NO_PICK_SENSITIVITY;
|
||||
|
||||
typedef enum {
|
||||
RCSP_AI_NO_PICK_AUTO_CLOSE_TIME_NONE = 0x00, // 不自动关闭
|
||||
RCSP_AI_NO_PICK_AUTO_CLOSE_TIME_5s = 0x01,
|
||||
RCSP_AI_NO_PICK_AUTO_CLOSE_TIME_15s = 0x02,
|
||||
RCSP_AI_NO_PICK_AUTO_CLOSE_TIME_30s = 0x03,
|
||||
} RCSP_AI_NO_PICK_AUTO_CLOSE_TIME;
|
||||
|
||||
/**
|
||||
* @brief 获取智能免摘开关
|
||||
*
|
||||
* @result bool
|
||||
*/
|
||||
bool get_ai_no_pick_switch();
|
||||
|
||||
/**
|
||||
* @brief 开启智能免摘
|
||||
*/
|
||||
void set_ai_no_pick_switch(bool p_switch);
|
||||
|
||||
/**
|
||||
* @brief 获取智能免摘敏感度
|
||||
*
|
||||
* @result RCSP_AI_NO_PICK_SENSITIVITY
|
||||
*/
|
||||
RCSP_AI_NO_PICK_SENSITIVITY get_ai_no_pick_sensitivity();
|
||||
|
||||
/**
|
||||
* @brief 设置智能免摘敏感度
|
||||
*/
|
||||
void set_ai_no_pick_sensitivity(RCSP_AI_NO_PICK_SENSITIVITY sensitivity);
|
||||
|
||||
/**
|
||||
* @brief 获取智能免摘自动关闭时间
|
||||
*
|
||||
* @result RCSP_AI_NO_PICK_AUTO_CLOSE_TIME
|
||||
*/
|
||||
RCSP_AI_NO_PICK_AUTO_CLOSE_TIME get_ai_no_pick_auto_close_time();
|
||||
|
||||
/**
|
||||
* @brief 设置智能免摘自动关闭时间
|
||||
*/
|
||||
void set_ai_no_pick_auto_close_time(RCSP_AI_NO_PICK_AUTO_CLOSE_TIME time_type);
|
||||
|
||||
#endif // __ADV_AI_NO_PICK_H__
|
||||
@ -0,0 +1,335 @@
|
||||
#include "app_config.h"
|
||||
#include "syscfg_id.h"
|
||||
#include "user_cfg_id.h"
|
||||
#include "le_rcsp_adv_module.h"
|
||||
|
||||
#include "adv_anc_voice.h"
|
||||
#include "adv_setting_common.h"
|
||||
#include "rcsp_adv_tws_sync.h"
|
||||
#include "rcsp_adv_opt.h"
|
||||
|
||||
#include "rcsp_adv_bluetooth.h"
|
||||
|
||||
#if (RCSP_ADV_EN && RCSP_ADV_ANC_VOICE)
|
||||
|
||||
#include "audio_anc.h"
|
||||
|
||||
// anc信息:mode(1byte/0/1/2) + ( left_max(2byte) + right_max(2byte) + left_cur_val(2byte) + right_cur_val(2byte) ) * 3
|
||||
static u8 g_anc_info[25] = {0};
|
||||
|
||||
extern int get_bt_tws_connect_status();
|
||||
extern u8 JL_get_cur_bt_channel_sel(void);
|
||||
|
||||
static bool check_pos_neg(u8 mode)
|
||||
{
|
||||
bool ret = false;
|
||||
u8 offset = 1 + mode * 8;
|
||||
#if TCFG_USER_TWS_ENABLE
|
||||
if ('R' == tws_api_get_local_channel()) {
|
||||
offset += 2;
|
||||
}
|
||||
#endif
|
||||
s16 val = g_anc_info[offset] << 8 | g_anc_info[offset + 1];
|
||||
if (val < 0) {
|
||||
ret = true;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
void get_anc_voice_info(u8 *anc_info)
|
||||
{
|
||||
memcpy(anc_info, g_anc_info, sizeof(g_anc_info));
|
||||
}
|
||||
|
||||
void set_anc_voice_info(u8 *anc_info)
|
||||
{
|
||||
memcpy(g_anc_info, anc_info, sizeof(g_anc_info));
|
||||
}
|
||||
|
||||
static void update_anc_voice_vm_value(u8 *anc_info)
|
||||
{
|
||||
u8 anc_vm_info[25] = {-1};
|
||||
int ret = syscfg_read(CFG_RCSP_ADV_ANC_VOICE_MODE, anc_vm_info, 1);
|
||||
if (0 != memcmp(anc_vm_info, anc_info, 1)) {
|
||||
ret = syscfg_write(CFG_RCSP_ADV_ANC_VOICE_MODE, anc_info, 1);
|
||||
}
|
||||
|
||||
ret = syscfg_read(CFG_RCSP_ADV_ANC_VOICE, anc_vm_info + 1, sizeof(anc_vm_info) - 1);
|
||||
if (0 != memcmp(anc_vm_info + 1, anc_info + 1, sizeof(anc_vm_info) - 1)) {
|
||||
ret = syscfg_write(CFG_RCSP_ADV_ANC_VOICE, anc_info + 1, sizeof(anc_vm_info) - 1);
|
||||
}
|
||||
}
|
||||
|
||||
static void anc_voice_sync(u8 *anc_info)
|
||||
{
|
||||
#if TCFG_USER_TWS_ENABLE
|
||||
if (get_bt_tws_connect_status()) {
|
||||
update_adv_setting(BIT(ATTR_TYPE_ANC_VOICE));
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
static void anc_voice_effect_set(u8 mode, s16 value)
|
||||
{
|
||||
static s16 value_old = -1;
|
||||
#if TCFG_AUDIO_ANC_ENABLE
|
||||
extern void anc_gain_app_value_set(int app_value);
|
||||
if (value != value_old) {
|
||||
/* audio_anc_gain(value, value); */
|
||||
anc_gain_app_value_set(value);
|
||||
}
|
||||
anc_mode_switch(mode + 1, 1);
|
||||
#endif
|
||||
value_old = value;
|
||||
}
|
||||
|
||||
static void anc_voice_state_update(void)
|
||||
{
|
||||
u8 offset = 0;
|
||||
u8 mode = g_anc_info[offset++];
|
||||
offset += mode * 8;
|
||||
s16 left_max = g_anc_info[offset++] << 8 | g_anc_info[offset++];
|
||||
s16 right_max = g_anc_info[offset++] << 8 | g_anc_info[offset++];
|
||||
s16 left_val = g_anc_info[offset++] << 8 | g_anc_info[offset++];
|
||||
s16 right_val = g_anc_info[offset++] << 8 | g_anc_info[offset++];
|
||||
|
||||
#if TCFG_USER_TWS_ENABLE
|
||||
if ('R' == tws_api_get_local_channel()) {
|
||||
if (check_pos_neg(mode) && right_val >= right_max) {
|
||||
anc_voice_effect_set(mode, right_val);
|
||||
} else if (right_max >= right_val) {
|
||||
anc_voice_effect_set(mode, right_val);
|
||||
}
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (check_pos_neg(mode) && left_val >= left_max) {
|
||||
anc_voice_effect_set(mode, left_val);
|
||||
} else if (left_max >= left_val) {
|
||||
anc_voice_effect_set(mode, left_val);
|
||||
}
|
||||
}
|
||||
|
||||
void deal_anc_voice(u8 *anc_setting, u8 write_vm, u8 tws_sync)
|
||||
{
|
||||
u8 anc_info[25] = {0};
|
||||
if (!anc_setting) {
|
||||
get_anc_voice_info(anc_info);
|
||||
} else {
|
||||
u8 mode = anc_setting[0];
|
||||
g_anc_info[0] = mode;
|
||||
memcpy(g_anc_info + 1 + mode * 8, anc_setting + 1, 8);
|
||||
memcpy(anc_info, g_anc_info, sizeof(anc_info));
|
||||
}
|
||||
if (write_vm) {
|
||||
update_anc_voice_vm_value(anc_info);
|
||||
}
|
||||
|
||||
if (tws_sync) {
|
||||
anc_voice_sync(anc_info);
|
||||
}
|
||||
|
||||
anc_voice_state_update();
|
||||
}
|
||||
|
||||
#if TCFG_USER_TWS_ENABLE
|
||||
#define TWS_FUNC_ID_ANC_VOICE_SYNC \
|
||||
(((u8)('R' + 'C' + 'S' + 'P') << (3 * 8)) | \
|
||||
((u8)('A' + 'N' + 'C' + 'S') << (2 * 8)) | \
|
||||
((u8)('V' + 'O' + 'I' + 'C' + 'E') << (1 * 8)) | \
|
||||
((u8)('S' + 'Y' + 'N' + 'C') << (0 * 8)))
|
||||
|
||||
void anc_voice_max_val_swap_sync(u8 *data, u16 len)
|
||||
{
|
||||
update_anc_voice_vm_value(g_anc_info);
|
||||
}
|
||||
|
||||
static void anc_voice_state_sync(u8 *data, u16 len)
|
||||
{
|
||||
if (NULL == data || 0 == len) {
|
||||
JL_rcsp_event_to_user(DEVICE_EVENT_FROM_RCSP, MSG_JL_UPDATE_ANC_VOICE, NULL, 0);
|
||||
return;
|
||||
}
|
||||
u8 offset = 9;
|
||||
// 假如当前是右耳,应该填写左值
|
||||
// 假如当前是左耳,应该填写右值
|
||||
if ('L' == tws_api_get_local_channel()) {
|
||||
offset += 2;
|
||||
}
|
||||
// 根据左右耳填充对应的最大值信息
|
||||
// 降噪(2byte) + 通透(2byte)
|
||||
memcpy(g_anc_info + offset, data, 2);
|
||||
memcpy(g_anc_info + offset + 4, data + 4, 2);
|
||||
offset += 8;
|
||||
memcpy(g_anc_info + offset, data + 2, 2);
|
||||
memcpy(g_anc_info + offset + 4, data + 6, 2);
|
||||
JL_rcsp_event_to_user(DEVICE_EVENT_FROM_RCSP, MSG_JL_UPDATE_ANC_VOICE_MAX_SYNC, NULL, 0);
|
||||
}
|
||||
|
||||
static void adv_anc_voice_tws_func_t(void *data, u16 len, bool rx)
|
||||
{
|
||||
if (rx) {
|
||||
anc_voice_state_sync((u8 *)data, len);
|
||||
}
|
||||
}
|
||||
|
||||
REGISTER_TWS_FUNC_STUB(adv_tws_sync) = {
|
||||
.func_id = TWS_FUNC_ID_ANC_VOICE_SYNC,
|
||||
.func = adv_anc_voice_tws_func_t,
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
void rcsp_adv_voice_mode_update(u8 mode)
|
||||
{
|
||||
u8 anc_info[25] = {0};
|
||||
get_anc_voice_info(anc_info);
|
||||
anc_info[0] = mode;
|
||||
if (mode) {
|
||||
memcpy(anc_info + 1, anc_info + 1 + mode * 8, 8);
|
||||
}
|
||||
deal_anc_voice(anc_info, 1, 0);
|
||||
#if TCFG_USER_TWS_ENABLE
|
||||
if (get_bt_tws_connect_status() && TWS_ROLE_SLAVE == tws_api_get_role()) {
|
||||
tws_api_send_data_to_sibling(NULL, 0, TWS_FUNC_ID_ANC_VOICE_SYNC);
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
JL_rcsp_event_to_user(DEVICE_EVENT_FROM_RCSP, MSG_JL_UPDATE_ANC_VOICE, NULL, 0);
|
||||
}
|
||||
|
||||
int anc_voice_setting_sync()
|
||||
{
|
||||
int ret = 0;
|
||||
u8 anc_info[8] = {0};
|
||||
#if (TCFG_AUDIO_ANC_ENABLE)
|
||||
/* extern int anc_gain_tab[3]; */
|
||||
/* u16 noise_reduction = (u16)(16384 & (u16) - 1); // 调用接口获取降噪最大值 */
|
||||
/* u16 transparent = (u16)(16384 & (u16) - 1); // 调用接口获取通透最大值 */
|
||||
|
||||
u16 noise_reduction = 16384; // 调用接口获取降噪最大值
|
||||
u16 transparent = 16384; // 调用接口获取通透最大值
|
||||
#else
|
||||
u16 noise_reduction = 0;
|
||||
u16 transparent = 0;
|
||||
#endif
|
||||
|
||||
anc_info[0] = ((u8 *)&noise_reduction)[1];
|
||||
anc_info[1] = ((u8 *)&noise_reduction)[0];
|
||||
anc_info[2] = ((u8 *)&transparent)[1];
|
||||
anc_info[3] = ((u8 *)&transparent)[0];
|
||||
|
||||
u8 offset = 9;
|
||||
#if TCFG_USER_TWS_ENABLE
|
||||
if ('R' == tws_api_get_local_channel()) {
|
||||
offset += 2;
|
||||
}
|
||||
#endif
|
||||
|
||||
// 初始值最大和当前值都是同一个值
|
||||
// 默认是左值
|
||||
u8 tmp_value = -1;
|
||||
int result = 0;
|
||||
if ((result = syscfg_read(CFG_RCSP_ADV_ANC_VOICE_MODE, &tmp_value, sizeof(tmp_value))) != sizeof(tmp_value)) {
|
||||
tmp_value = offset;
|
||||
memcpy(g_anc_info + tmp_value, anc_info, 2);
|
||||
tmp_value += 4;
|
||||
memcpy(g_anc_info + tmp_value, anc_info, 2);
|
||||
tmp_value += 4;
|
||||
memcpy(g_anc_info + tmp_value, anc_info + 2, 2);
|
||||
tmp_value += 4;
|
||||
memcpy(g_anc_info + tmp_value, anc_info + 2, 2);
|
||||
}
|
||||
|
||||
#if TCFG_USER_TWS_ENABLE
|
||||
// 填写当前降噪/通透当前值
|
||||
memcpy(anc_info + 4, g_anc_info + offset + 4, 2);
|
||||
memcpy(anc_info + 6, g_anc_info + offset + 8 + 4, 2);
|
||||
// 把自己的最大值发送给对端
|
||||
if (get_bt_tws_connect_status()) {
|
||||
tws_api_send_data_to_sibling(anc_info, sizeof(anc_info), TWS_FUNC_ID_ANC_VOICE_SYNC);
|
||||
}
|
||||
#endif
|
||||
return ret;
|
||||
}
|
||||
|
||||
int anc_voice_setting_init(void)
|
||||
{
|
||||
int ret = 1;
|
||||
u8 anc_mode = -1;
|
||||
if (syscfg_read(CFG_RCSP_ADV_ANC_VOICE_MODE, &anc_mode, sizeof(anc_mode)) != sizeof(anc_mode)) {
|
||||
anc_voice_setting_sync();
|
||||
ret = 0;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
// ====================================================
|
||||
enum {
|
||||
anc_VOICE_GET_PREP_MSG,
|
||||
anc_VOICE_SET_CUR_MODE,
|
||||
anc_VOICE_NOTICE_MSG,
|
||||
anc_VOICE_GET_CUR_MODE,
|
||||
};
|
||||
|
||||
static void s16_pos_neg_conversion(u8 *data)
|
||||
{
|
||||
s16 tmp_val = data[0] << 8 | data[1];
|
||||
tmp_val = -tmp_val;
|
||||
data[1] = ((u8 *)&tmp_val)[0];
|
||||
data[0] = ((u8 *)&tmp_val)[1];
|
||||
}
|
||||
|
||||
u8 anc_voice_info_get(u8 *data, u16 len)
|
||||
{
|
||||
u8 offset = 0;
|
||||
u8 anc_info[25] = {0};
|
||||
get_anc_voice_info(anc_info);
|
||||
u8 mode = anc_info[0];
|
||||
data[offset++] = mode;
|
||||
memcpy(data + offset, anc_info + 1 + mode * 8, 8);
|
||||
if (check_pos_neg(mode)) {
|
||||
for (u8 i = 0; i < 8; i += 2) {
|
||||
s16_pos_neg_conversion(data + 1 + i);
|
||||
}
|
||||
}
|
||||
offset += 8;
|
||||
return offset;
|
||||
}
|
||||
|
||||
u8 anc_voice_info_fetch_all_get(u8 *data, u16 len)
|
||||
{
|
||||
u8 mode = 0;
|
||||
u8 offset = 1;
|
||||
u8 anc_info[25] = {0};
|
||||
get_anc_voice_info(anc_info);
|
||||
for (u8 resp_offset = 1; offset < sizeof(anc_info); offset += 8) {
|
||||
data[resp_offset++] = mode;
|
||||
memcpy(data + resp_offset, anc_info + offset, 8);
|
||||
if (check_pos_neg(mode)) {
|
||||
for (u8 i = 0; i < 8; i += 2) {
|
||||
s16_pos_neg_conversion(data + 2 + mode * 9 + i);
|
||||
}
|
||||
}
|
||||
resp_offset += 8;
|
||||
mode++;
|
||||
}
|
||||
data[0] = mode;
|
||||
return len;
|
||||
}
|
||||
|
||||
int anc_voice_info_set(u8 *data, u16 len)
|
||||
{
|
||||
int ret = 0;
|
||||
if (check_pos_neg(data[0])) {
|
||||
for (u8 i = 0; i < 8; i += 2) {
|
||||
s16_pos_neg_conversion(data + 1 + i);
|
||||
}
|
||||
}
|
||||
deal_anc_voice(data, 1, 1);
|
||||
JL_rcsp_event_to_user(DEVICE_EVENT_FROM_RCSP, MSG_JL_UPDATE_ANC_VOICE, NULL, 0);
|
||||
return ret;
|
||||
}
|
||||
|
||||
#endif
|
||||
@ -0,0 +1,19 @@
|
||||
#ifndef __ADV_ANS_VOICE_H__
|
||||
#define __ADV_ANS_VOICE_H__
|
||||
|
||||
#include "le_rcsp_adv_module.h"
|
||||
|
||||
int anc_voice_setting_init(void);
|
||||
int anc_voice_setting_sync(void);
|
||||
|
||||
void deal_anc_voice(u8 *anc_setting, u8 write_vm, u8 tws_sync);
|
||||
void set_anc_voice_info(u8 *anc_info);
|
||||
void get_anc_voice_info(u8 *anc_info);
|
||||
|
||||
u8 anc_voice_info_get(u8 *data, u16 len);
|
||||
u8 anc_voice_info_fetch_all_get(u8 *data, u16 len);
|
||||
int anc_voice_info_set(u8 *data, u16 len);
|
||||
int update_anc_voice_key_opt(void);
|
||||
void rcsp_adv_voice_mode_update(u8 mode);
|
||||
|
||||
#endif
|
||||
@ -0,0 +1,94 @@
|
||||
#include "app_config.h"
|
||||
#include "syscfg_id.h"
|
||||
#include "user_cfg_id.h"
|
||||
#include "key_event_deal.h"
|
||||
#include "le_rcsp_adv_module.h"
|
||||
|
||||
#include "adv_anc_voice_key.h"
|
||||
#include "adv_setting_common.h"
|
||||
#include "rcsp_adv_tws_sync.h"
|
||||
#include "rcsp_adv_opt.h"
|
||||
|
||||
#include "adv_anc_voice.h"
|
||||
|
||||
#if (RCSP_ADV_EN)
|
||||
/* #if (RCSP_ADV_KEY_SET_ENABLE && TCFG_AUDIO_ANC_ENABLE) */
|
||||
#if (RCSP_ADV_KEY_SET_ENABLE)
|
||||
|
||||
#include "audio_anc.h"
|
||||
|
||||
#define COMMON_FUNCTION 0xFF
|
||||
#define ANC_VOICE_TYPE_MAX 3
|
||||
|
||||
static u8 g_anc_voice_key_mode[4] = {0, 0, 0, BIT(ANC_VOICE_TYPE_MAX) - 1};
|
||||
|
||||
extern int get_bt_tws_connect_status();
|
||||
|
||||
void set_anc_voice_key_mode(u8 *anc_voice_mode)
|
||||
{
|
||||
memcpy(g_anc_voice_key_mode, anc_voice_mode, sizeof(g_anc_voice_key_mode));
|
||||
}
|
||||
|
||||
void get_anc_voice_key_mode(u8 *anc_voice_mode)
|
||||
{
|
||||
memcpy(anc_voice_mode, g_anc_voice_key_mode, sizeof(g_anc_voice_key_mode));
|
||||
}
|
||||
|
||||
static void update_anc_voice_key_vm_value(u8 *anc_voice_mode)
|
||||
{
|
||||
syscfg_write(CFG_RCSP_ADV_ANC_VOICE_KEY, anc_voice_mode, 4);
|
||||
}
|
||||
|
||||
static void anc_voice_key_sync(u8 *key_setting_info)
|
||||
{
|
||||
#if TCFG_USER_TWS_ENABLE
|
||||
if (get_bt_tws_connect_status()) {
|
||||
update_adv_setting(BIT(ATTR_TYPE_ANC_VOICE_KEY));
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void deal_anc_voice_key_setting(u8 *anc_key_setting, u8 write_vm, u8 tws_sync)
|
||||
{
|
||||
u8 anc_voice_key_mode[4] = {0};
|
||||
if (!anc_key_setting) {
|
||||
get_anc_voice_key_mode(anc_voice_key_mode);
|
||||
} else {
|
||||
set_anc_voice_key_mode(anc_key_setting);
|
||||
memcpy(anc_voice_key_mode, g_anc_voice_key_mode, sizeof(g_anc_voice_key_mode));
|
||||
}
|
||||
if (write_vm) {
|
||||
update_anc_voice_key_vm_value(anc_voice_key_mode);
|
||||
}
|
||||
if (tws_sync) {
|
||||
anc_voice_key_sync(anc_voice_key_mode);
|
||||
}
|
||||
}
|
||||
|
||||
int update_anc_voice_key_opt(void)
|
||||
{
|
||||
int ret = 0;
|
||||
#if (RCSP_ADV_ANC_VOICE)
|
||||
u32 mask = g_anc_voice_key_mode[0] << 24 | g_anc_voice_key_mode[1] << 16 | g_anc_voice_key_mode[2] << 8 | g_anc_voice_key_mode[3];
|
||||
// 获取当前处于什么模式
|
||||
#if TCFG_AUDIO_ANC_ENABLE
|
||||
u8 cur_mode = anc_mode_get();
|
||||
#else
|
||||
u8 cur_mode = ANC_OFF;
|
||||
#endif
|
||||
u8 next_mode = cur_mode % ANC_VOICE_TYPE_MAX;
|
||||
for (; next_mode < ANC_VOICE_TYPE_MAX; next_mode++) {
|
||||
if (mask & BIT(next_mode)) {
|
||||
rcsp_adv_voice_mode_update(next_mode % ANC_VOICE_TYPE_MAX);
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
if (mask & BIT(next_mode % ANC_VOICE_TYPE_MAX)) {
|
||||
rcsp_adv_voice_mode_update(next_mode % ANC_VOICE_TYPE_MAX);
|
||||
}
|
||||
#endif
|
||||
return ret;
|
||||
}
|
||||
|
||||
#endif
|
||||
#endif
|
||||
@ -0,0 +1,12 @@
|
||||
#ifndef __ADV_ANC_VOICE_KEY_H__
|
||||
#define __ADV_ANC_VOICE_KEY_H__
|
||||
|
||||
#include "le_rcsp_adv_module.h"
|
||||
|
||||
void deal_anc_voice_key_setting(u8 *anc_key_setting, u8 write_vm, u8 tws_sync);
|
||||
void get_anc_voice_key_mode(u8 *anc_voice_mode);
|
||||
void set_anc_voice_key_mode(u8 *anc_voice_mode);
|
||||
|
||||
int update_anc_voice_key_opt(void);
|
||||
|
||||
#endif
|
||||
@ -0,0 +1,67 @@
|
||||
#include "app_config.h"
|
||||
#include "user_cfg.h"
|
||||
#include "syscfg_id.h"
|
||||
#include "user_cfg_id.h"
|
||||
#include "le_rcsp_adv_module.h"
|
||||
|
||||
#include "adv_bt_name_setting.h"
|
||||
#include "adv_setting_common.h"
|
||||
#include "rcsp_adv_tws_sync.h"
|
||||
#include "rcsp_adv_opt.h"
|
||||
|
||||
#if (RCSP_ADV_EN)
|
||||
#if RCSP_ADV_NAME_SET_ENABLE
|
||||
extern int get_bt_tws_connect_status();
|
||||
|
||||
void adv_edr_name_change_now(void)
|
||||
{
|
||||
extern BT_CONFIG bt_cfg;
|
||||
extern const char *bt_get_local_name();
|
||||
extern void lmp_hci_write_local_name(const char *name);
|
||||
memcpy(bt_cfg.edr_name, _s_info.edr_name, LOCAL_NAME_LEN);
|
||||
lmp_hci_write_local_name(bt_get_local_name());
|
||||
}
|
||||
|
||||
void set_bt_name_setting(u8 *bt_name_setting)
|
||||
{
|
||||
memcpy(_s_info.edr_name, bt_name_setting, 32);
|
||||
}
|
||||
|
||||
void get_bt_name_setting(u8 *bt_name_setting)
|
||||
{
|
||||
memcpy(bt_name_setting, _s_info.edr_name, 32);
|
||||
}
|
||||
|
||||
// 1、写入VM
|
||||
static void update_bt_name_vm_value(u8 *bt_name_setting)
|
||||
{
|
||||
syscfg_write(CFG_BT_NAME, bt_name_setting, 32);
|
||||
}
|
||||
// 2、同步对端
|
||||
static void bt_name_sync(u8 *bt_name_setting)
|
||||
{
|
||||
#if TCFG_USER_TWS_ENABLE
|
||||
if (get_bt_tws_connect_status()) {
|
||||
update_adv_setting(BIT(ATTR_TYPE_EDR_NAME));
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void deal_bt_name_setting(u8 *bt_name_setting, u8 write_vm, u8 tws_sync)
|
||||
{
|
||||
u8 bt_name[32] = {0};
|
||||
if (!bt_name_setting) {
|
||||
get_bt_name_setting(bt_name);
|
||||
} else {
|
||||
memcpy(bt_name, bt_name_setting, 32);
|
||||
}
|
||||
if (write_vm) {
|
||||
update_bt_name_vm_value(bt_name);
|
||||
}
|
||||
if (tws_sync) {
|
||||
bt_name_sync(bt_name);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
@ -0,0 +1,12 @@
|
||||
#ifndef __ADV_BT_NAME_SETTING_H__
|
||||
#define __ADV_BT_NAME_SETTING_H__
|
||||
|
||||
#include "le_rcsp_adv_module.h"
|
||||
|
||||
#if RCSP_ADV_NAME_SET_ENABLE
|
||||
|
||||
void set_bt_name_setting(u8 *bt_name_setting);
|
||||
void get_bt_name_setting(u8 *bt_name_setting);
|
||||
|
||||
#endif
|
||||
#endif
|
||||
@ -0,0 +1,218 @@
|
||||
#include "app_config.h"
|
||||
#include "syscfg_id.h"
|
||||
#include "user_cfg_id.h"
|
||||
#include "le_rcsp_adv_module.h"
|
||||
|
||||
#include "adv_eq_setting.h"
|
||||
#include "adv_setting_common.h"
|
||||
#include "rcsp_adv_tws_sync.h"
|
||||
#include "rcsp_adv_opt.h"
|
||||
#include "application/audio_eq.h"
|
||||
|
||||
#if (RCSP_ADV_EN)
|
||||
#if RCSP_ADV_EQ_SET_ENABLE
|
||||
extern int get_bt_tws_connect_status();
|
||||
extern int eq_mode_get_freq(u8 mode, u16 index);
|
||||
extern s8 eq_mode_get_gain(u8 mode, u16 index);
|
||||
extern int eq_mode_set_custom_param(u16 index, int gain);
|
||||
extern int eq_mode_set(u8 mode);
|
||||
extern int eq_mode_get_cur(void);
|
||||
|
||||
static void eq_setting_info_deal(u8 *eq_info_data)
|
||||
{
|
||||
u8 data;
|
||||
u8 status;
|
||||
u8 mode;
|
||||
if (eq_info_data[0] >> 7) {
|
||||
status = eq_info_data[2];
|
||||
} else {
|
||||
status = *(((u8 *)eq_info_data) + 1);
|
||||
}
|
||||
mode = eq_info_data[0] & 0x7F;
|
||||
if (mode < EQ_MODE_CUSTOM) {
|
||||
eq_mode_set(mode);
|
||||
} else {
|
||||
// 自定义修改EQ参数
|
||||
if (EQ_MODE_CUSTOM == mode) {
|
||||
if (status != 0x7F) {
|
||||
u8 i;
|
||||
for (i = 0; i < EQ_SECTION_MAX; i++) {
|
||||
if (eq_info_data[0] >> 7) {
|
||||
data = eq_info_data[i + 2];
|
||||
} else {
|
||||
data = eq_info_data[i + 1];
|
||||
}
|
||||
eq_mode_set_custom_param(i, (s8)data);
|
||||
}
|
||||
}
|
||||
eq_mode_set(mode);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void set_eq_setting(u8 *eq_setting)
|
||||
{
|
||||
u8 i;
|
||||
u8 eq_setting_mode = eq_setting[0];
|
||||
if (eq_setting_mode >> 7) {
|
||||
// 多段eq
|
||||
for (i = 2; i < eq_setting[1] + 2; i++) {
|
||||
if ((eq_setting[i] > 12) && (eq_setting[i] < -12)) {
|
||||
eq_setting[i] = 0;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// 10段eq
|
||||
for (i = 1; i < 11; i++) {
|
||||
if ((eq_setting[i] > 12) && (eq_setting[i] < -12)) {
|
||||
eq_setting[i] = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
memcpy(_s_info.eq_mode_info, eq_setting, 11);
|
||||
}
|
||||
|
||||
void get_eq_setting(u8 *eq_setting)
|
||||
{
|
||||
memcpy(eq_setting, _s_info.eq_mode_info, 11);
|
||||
}
|
||||
|
||||
// 1、写入VM
|
||||
static void update_eq_vm_value(u8 *eq_setting)
|
||||
{
|
||||
u8 status = *(((u8 *)eq_setting) + 1);
|
||||
|
||||
syscfg_write(CFG_RCSP_ADV_EQ_MODE_SETTING, eq_setting, 1);
|
||||
|
||||
/*自定义修改EQ参数*/
|
||||
if (EQ_MODE_CUSTOM == (eq_setting[0] & 0x7F)) {
|
||||
if (eq_setting[0] >> 7) {
|
||||
// 多段eq
|
||||
status = eq_setting[2];
|
||||
}
|
||||
if (status != 0x7F) {
|
||||
syscfg_write(CFG_RCSP_ADV_EQ_DATA_SETTING, &eq_setting[1], 10);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
// 2、同步对端
|
||||
static void eq_sync(u8 *eq_setting)
|
||||
{
|
||||
#if TCFG_USER_TWS_ENABLE
|
||||
if (get_bt_tws_connect_status()) {
|
||||
update_adv_setting(BIT(ATTR_TYPE_EQ_SETTING));
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void deal_eq_setting(u8 *eq_setting, u8 write_vm, u8 tws_sync)
|
||||
{
|
||||
u8 eq_info[11] = {0};
|
||||
if (!eq_setting) {
|
||||
get_eq_setting(eq_info);
|
||||
} else {
|
||||
u8 status = *(((u8 *)eq_setting) + 1);
|
||||
|
||||
/*自定义修改EQ参数*/
|
||||
if (EQ_MODE_CUSTOM == (eq_setting[0] & 0x7F)) {
|
||||
if (eq_setting[0] >> 7) {
|
||||
status = eq_setting[2];
|
||||
}
|
||||
|
||||
if (status != 0x7F) {
|
||||
memcpy(eq_info, eq_setting, 11);
|
||||
set_eq_setting(eq_info);
|
||||
} else {
|
||||
_s_info.eq_mode_info[0] = eq_setting[0];
|
||||
get_eq_setting(eq_info);
|
||||
}
|
||||
} else {
|
||||
memcpy(eq_info, eq_setting, 11);
|
||||
_s_info.eq_mode_info[0] = eq_setting[0];
|
||||
}
|
||||
|
||||
}
|
||||
if (write_vm) {
|
||||
update_eq_vm_value(eq_info);
|
||||
}
|
||||
if (tws_sync) {
|
||||
eq_sync(eq_info);
|
||||
}
|
||||
eq_setting_info_deal(eq_info);
|
||||
}
|
||||
|
||||
|
||||
u8 app_get_eq_info(u8 *get_eq_info)
|
||||
{
|
||||
u16 i;
|
||||
get_eq_info[0] = eq_mode_get_cur();
|
||||
u8 data_len = 1;
|
||||
|
||||
if (10 == EQ_SECTION_MAX) {
|
||||
// 10段eq : mode + gain[10byte]
|
||||
for (i = 0; i < 10; i++) {
|
||||
get_eq_info[data_len] = eq_mode_get_gain(get_eq_info[0], i);
|
||||
data_len++;
|
||||
}
|
||||
} else {
|
||||
// 多段eq : mode + num + value(freq[2byte] + gain[1byte])
|
||||
get_eq_info[1] = EQ_SECTION_MAX;
|
||||
data_len++;
|
||||
for (i = 0; i < EQ_SECTION_MAX; i++) {
|
||||
get_eq_info[data_len] = eq_mode_get_gain(get_eq_info[0], i);
|
||||
data_len++;
|
||||
}
|
||||
get_eq_info[0] |= (1 << 7);
|
||||
}
|
||||
return data_len;
|
||||
}
|
||||
|
||||
u8 app_get_eq_all_info(u8 *get_eq_info)
|
||||
{
|
||||
u16 i;
|
||||
u8 mode = EQ_MODE_NORMAL;
|
||||
get_eq_info[0] = EQ_SECTION_MAX;
|
||||
u8 data_len = 1;
|
||||
// get freq
|
||||
for (i = 0; i < EQ_SECTION_MAX; i++) {
|
||||
u16 eq_freq = (u16)(eq_mode_get_freq(mode, i) & ((u16) - 1));
|
||||
eq_freq = ((((u8 *)&eq_freq)[0] << 8) + ((u8 *)&eq_freq)[1]);
|
||||
memcpy(get_eq_info + data_len, &eq_freq, sizeof(eq_freq));
|
||||
data_len += 2;
|
||||
}
|
||||
// get gain
|
||||
for (; mode < EQ_MODE_CUSTOM; mode++) {
|
||||
get_eq_info[data_len] = mode;
|
||||
if (10 != EQ_SECTION_MAX) {
|
||||
get_eq_info[data_len] |= (1 << 7);
|
||||
}
|
||||
data_len++;
|
||||
for (i = 0; i < EQ_SECTION_MAX; i++) {
|
||||
u8 eq_gain = eq_mode_get_gain(mode, i);
|
||||
get_eq_info[data_len] = eq_gain;
|
||||
data_len++;
|
||||
}
|
||||
}
|
||||
// get custom
|
||||
get_eq_info[data_len] = EQ_MODE_CUSTOM;
|
||||
if (10 != EQ_SECTION_MAX) {
|
||||
get_eq_info[data_len] |= (1 << 7);
|
||||
}
|
||||
data_len++;
|
||||
for (i = 0; i < EQ_SECTION_MAX; i++) {
|
||||
if (10 == EQ_SECTION_MAX) {
|
||||
get_eq_info[data_len] = _s_info.eq_mode_info[i + 1];
|
||||
} else {
|
||||
get_eq_info[data_len] = _s_info.eq_mode_info[i + 2];
|
||||
}
|
||||
data_len++;
|
||||
}
|
||||
|
||||
return data_len;
|
||||
}
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
#endif
|
||||
@ -0,0 +1,20 @@
|
||||
#ifndef __ADV_EQ_SETTING_H__
|
||||
#define __ADV_EQ_SETTING_H__
|
||||
|
||||
#include "le_rcsp_adv_module.h"
|
||||
|
||||
#if defined(RCSP_ADV_EQ_SET_ENABLE) && RCSP_ADV_EQ_SET_ENABLE
|
||||
|
||||
struct _EQ_INFO {
|
||||
u8 mode;
|
||||
s8 gain_val[10];
|
||||
};
|
||||
|
||||
void set_eq_setting(u8 *eq_setting);
|
||||
void get_eq_setting(u8 *eq_setting);
|
||||
void deal_eq_setting(u8 *eq_setting, u8 write_vm, u8 tws_sync);
|
||||
u8 app_get_eq_info(u8 *get_eq_info);
|
||||
u8 app_get_eq_all_info(u8 *get_eq_info);
|
||||
|
||||
#endif
|
||||
#endif
|
||||
@ -0,0 +1,318 @@
|
||||
#include "app_config.h"
|
||||
#include "syscfg_id.h"
|
||||
#include "le_rcsp_adv_module.h"
|
||||
|
||||
#include "adv_hearing_aid_setting.h"
|
||||
#include "rcsp_adv_tws_sync.h"
|
||||
#include "JL_rcsp_protocol.h"
|
||||
#include "rcsp_adv_bluetooth.h"
|
||||
#include "spp_user.h"
|
||||
|
||||
#if (RCSP_ADV_EN && RCSP_ADV_ASSISTED_HEARING)
|
||||
|
||||
static u8 g_dha_fitting_data[3 + 2 * 4 * DHA_FITTING_CHANNEL_MAX] = {0};
|
||||
static u8 g_dha_fitting_info[3 + 2 + 2 * DHA_FITTING_CHANNEL_MAX + 1] = {0};
|
||||
static bool g_aidIsOperating = false;
|
||||
static u8 g_aidOpCode = -1;
|
||||
static u8 g_aidOpCode_SN = -1;
|
||||
|
||||
extern int tws_api_get_role(void);
|
||||
extern u8 deal_adv_setting_string_item(u8 *des, u8 *src, u8 src_len, u8 type);
|
||||
extern u16 get_adv_sync_tws_len(void);
|
||||
static u16 adv_hearing_aid_convert(u8 *data);
|
||||
|
||||
static void hearing_aid_update_handle(u8 *data, u16 data_len)
|
||||
{
|
||||
#if (TCFG_AUDIO_HEARING_AID_ENABLE && TCFG_AUDIO_DHA_FITTING_ENABLE)
|
||||
hearing_aid_fitting_parse(g_dha_fitting_data, data_len);
|
||||
#endif /*TCFG_AUDIO_HEARING_AID_ENABLE && TCFG_AUDIO_DHA_FITTING_ENABLE*/
|
||||
}
|
||||
|
||||
static void hearing_aid_update(void)
|
||||
{
|
||||
// 跟进不同命令类型调用设置函数
|
||||
printf("%s\n", __func__);
|
||||
/* u16 data_len = get_adv_sync_tws_len(); */
|
||||
/* if (sizeof(g_dha_fitting_data) == data_len) { */
|
||||
/* data_len = adv_hearing_aid_convert(g_dha_fitting_data); */
|
||||
/* put_buf(g_dha_fitting_data, data_len); */
|
||||
/* } */
|
||||
#if ASSISTED_HEARING_CUSTOM_TRASNDATA
|
||||
// 从机才触发
|
||||
u16 data_len = get_adv_sync_tws_len();
|
||||
#else
|
||||
u16 data_len = adv_hearing_aid_convert(g_dha_fitting_data);
|
||||
#endif
|
||||
put_buf(g_dha_fitting_data, data_len);
|
||||
hearing_aid_update_handle(g_dha_fitting_data, data_len);
|
||||
}
|
||||
|
||||
#pragma pack(1)
|
||||
struct hearing_aid_playload {
|
||||
u8 cmd;
|
||||
u16 data_len;
|
||||
dha_fitting_info_t data_info;
|
||||
};
|
||||
#pragma pack()
|
||||
|
||||
void get_dha_fitting_info(u8 *dha_fitting_info)
|
||||
{
|
||||
printf("%s\n", __func__);
|
||||
struct hearing_aid_playload playload;
|
||||
playload.cmd = DHA_FITTING_CMD_INFO;
|
||||
// 如果当前是主动拿,就把所有信息返回
|
||||
|
||||
// 获取0x50对应的数据
|
||||
/* u8 tmp_data[] = {0, DHA_FITTING_CHANNEL_MAX, 0x12, 0x21, 0x23, 0x32, 0x34, 0x43, 0x45, 0x54, 0x56, 0x65, 0x67, 0x76}; // 例子 */
|
||||
/* playload.data_len = sizeof(tmp_data); */
|
||||
/* memcpy(&playload.data_info, tmp_data, sizeof(tmp_data)); */
|
||||
|
||||
// 获取0x50对应的数据
|
||||
dha_fitting_info_t dha_info;
|
||||
#if (TCFG_AUDIO_HEARING_AID_ENABLE && TCFG_AUDIO_DHA_FITTING_ENABLE)
|
||||
playload.data_len = get_hearing_aid_fitting_info(&dha_info);
|
||||
#endif /*TCFG_AUDIO_HEARING_AID_ENABLE && TCFG_AUDIO_DHA_FITTING_ENABLE*/
|
||||
|
||||
memcpy(&playload.data_info, &dha_info, sizeof(dha_info));
|
||||
|
||||
memcpy(g_dha_fitting_info, &playload, sizeof(playload));
|
||||
|
||||
// 如果当前是从机通知,就直接memcpy过去,不需要填充前三个头
|
||||
u16 data_len = adv_hearing_aid_convert(g_dha_fitting_info);
|
||||
put_buf(g_dha_fitting_info, data_len);
|
||||
|
||||
memcpy(dha_fitting_info, g_dha_fitting_info, sizeof(g_dha_fitting_info) - 1);
|
||||
}
|
||||
|
||||
static void hearing_aid_sync(void)
|
||||
{
|
||||
#if TCFG_USER_TWS_ENABLE
|
||||
if (get_bt_tws_connect_status()) {
|
||||
update_adv_setting(BIT(ATTR_TYPE_ASSISTED_HEARING));
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
static void big_to_little(u8 *data, u8 data_len)
|
||||
{
|
||||
u8 tmp_data = 0;
|
||||
for (u8 i = 0; i < (data_len / 2); i++) {
|
||||
tmp_data = data[i];
|
||||
data[i] = data[data_len - i - 1];
|
||||
data[data_len - i - 1] = tmp_data;
|
||||
}
|
||||
}
|
||||
|
||||
static u16 adv_hearing_aid_convert(u8 *data)
|
||||
{
|
||||
u16 offset = 0;
|
||||
u16 data_len = 0;
|
||||
u8 cmd = data[offset++];
|
||||
|
||||
dha_fitting_adjust_t *dha_data; // 0x51
|
||||
dha_fitting_info_t *dha_info; // 0x50
|
||||
switch (cmd) {
|
||||
case DHA_FITTING_CMD_INFO:
|
||||
big_to_little(data + offset, 2);
|
||||
data_len = data[offset++] << 8 | data[offset++];
|
||||
dha_info = (dha_fitting_adjust_t *)(data + offset);
|
||||
offset += 2;
|
||||
for (; offset < data_len + 3; offset += 2) {
|
||||
big_to_little(data + offset, 2);
|
||||
}
|
||||
break;
|
||||
case DHA_FITTING_CMD_ADJUST:
|
||||
data_len = data[offset] << 8 | data[offset + 1];
|
||||
big_to_little(data + offset, 2);
|
||||
offset += 2;
|
||||
dha_data = (dha_fitting_adjust_t *)(data + offset);
|
||||
offset += 2;
|
||||
big_to_little((u8 *)&dha_data->freq, sizeof(dha_data->freq));
|
||||
offset += 2;
|
||||
big_to_little((u8 *)&dha_data->gain, sizeof(dha_data->gain));
|
||||
offset += 4;
|
||||
break;
|
||||
case DHA_FITTING_CMD_UPDATE:
|
||||
data_len = data[offset] << 8 | data[offset + 1];
|
||||
big_to_little(data + offset, 2);
|
||||
offset += 3;
|
||||
for (; offset < data_len + 3; offset += 4) {
|
||||
big_to_little(g_dha_fitting_data + offset, 4);
|
||||
}
|
||||
break;
|
||||
case DHA_FITTING_CMD_STATE:
|
||||
big_to_little(data + offset, 2);
|
||||
data_len = data[offset++] << 8 | data[offset++];
|
||||
offset += 1;
|
||||
break;
|
||||
}
|
||||
if (data_len + 3 == offset) {
|
||||
return offset;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void set_hearing_aid_setting(u8 *hear_aid_setting)
|
||||
{
|
||||
memcpy(g_dha_fitting_data, hear_aid_setting, sizeof(g_dha_fitting_data));
|
||||
}
|
||||
|
||||
void get_hearing_aid_setting(u8 *hear_aid_setting)
|
||||
{
|
||||
memcpy(hear_aid_setting, g_dha_fitting_data, sizeof(g_dha_fitting_data));
|
||||
}
|
||||
|
||||
u32 hearing_aid_rcsp_notify(u8 *data, u16 data_len)
|
||||
{
|
||||
u32 ret = 0;
|
||||
u8 *buf = NULL;
|
||||
|
||||
if (0 == adv_hearing_aid_convert(data)) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
buf = zalloc(data_len + 3);
|
||||
if (NULL == buf) {
|
||||
return -1;
|
||||
}
|
||||
buf[0] = 0xFF;
|
||||
data_len = add_one_attr(buf + 1, data_len + 2, 0, COMMON_INFO_ATTR_ASSISTED_HEARING, data, data_len);
|
||||
|
||||
ret = JL_CMD_send(JL_OPCODE_SYS_INFO_AUTO_UPDATE, buf, data_len + 1, JL_NOT_NEED_RESPOND);
|
||||
|
||||
if (buf) {
|
||||
free(buf);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
u32 hearing_aid_rcsp_response(u8 *data, u16 data_len)
|
||||
{
|
||||
/*不开辅听功能时,不回复app信息*/
|
||||
#if (TCFG_AUDIO_HEARING_AID_ENABLE && TCFG_AUDIO_DHA_FITTING_ENABLE)
|
||||
if (get_hearing_aid_state() == 0)
|
||||
#endif /*(TCFG_AUDIO_HEARING_AID_ENABLE && TCFG_AUDIO_DHA_FITTING_ENABLE)*/
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
if ((TWS_ROLE_MASTER == tws_api_get_role()) && (g_aidOpCode >= 0) && (g_aidOpCode_SN >= 0)) {
|
||||
u32 ret = 0;
|
||||
ret = JL_CMD_response_send(g_aidOpCode, JL_PRO_STATUS_SUCCESS, g_aidOpCode_SN, data, data_len);
|
||||
g_aidIsOperating = false;
|
||||
g_aidOpCode = -1;
|
||||
g_aidOpCode_SN = -1;
|
||||
|
||||
return ret;
|
||||
} else {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
void deal_hearing_aid_setting(u8 opCode, u8 opCode_SN, u8 *hear_aid_setting, u8 write_en, u8 type_sync)
|
||||
{
|
||||
if (TWS_ROLE_MASTER == tws_api_get_role()) {
|
||||
set_hearing_aid_operating_flag();
|
||||
}
|
||||
if (g_aidIsOperating) {
|
||||
return;
|
||||
}
|
||||
if (TWS_ROLE_MASTER == tws_api_get_role()) {
|
||||
g_aidIsOperating = true;
|
||||
g_aidOpCode = opCode;
|
||||
g_aidOpCode_SN = opCode_SN;
|
||||
}
|
||||
if (hear_aid_setting) {
|
||||
u16 len = hear_aid_setting[1] << 8 | hear_aid_setting[2];
|
||||
memcpy(g_dha_fitting_data, hear_aid_setting, len + 2);
|
||||
}
|
||||
|
||||
if (type_sync) {
|
||||
hearing_aid_sync();
|
||||
}
|
||||
|
||||
#if TCFG_USER_TWS_ENABLE
|
||||
if (get_bt_tws_connect_status()) {
|
||||
if (TWS_ROLE_MASTER == tws_api_get_role()) {
|
||||
hearing_aid_update();
|
||||
} else if (0 == type_sync) {
|
||||
hearing_aid_update();
|
||||
}
|
||||
} else
|
||||
#endif
|
||||
{
|
||||
hearing_aid_update();
|
||||
}
|
||||
}
|
||||
|
||||
#if ASSISTED_HEARING_CUSTOM_TRASNDATA
|
||||
static struct spp_operation_t *spp_opt = NULL;
|
||||
static void app_third_party_spp_rx_cbk(void *priv, u8 *buf, u16 len)
|
||||
{
|
||||
app_third_party_hearing_aid_handle(buf, len);
|
||||
}
|
||||
|
||||
void adv_hearing_aid_init(void)
|
||||
{
|
||||
spp_get_operation_table(&spp_opt);
|
||||
if (spp_opt && spp_opt->regist_recieve_cbk) {
|
||||
spp_opt->regist_recieve_cbk(NULL, app_third_party_spp_rx_cbk);
|
||||
}
|
||||
}
|
||||
|
||||
int app_third_party_hearing_aid_handle(u8 *data, u16 len)
|
||||
{
|
||||
#if TCFG_USER_TWS_ENABLE
|
||||
u8 *tmp_buf = NULL;
|
||||
u16 offset = 1;
|
||||
if (len < sizeof(g_dha_fitting_data)) {
|
||||
return -1;
|
||||
}
|
||||
tmp_buf = zalloc(1 + 1 + len);
|
||||
if (NULL == tmp_buf) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
offset += deal_adv_setting_string_item(tmp_buf + offset, data, len, ATTR_TYPE_ASSISTED_HEARING);
|
||||
tmp_buf[0] = offset;
|
||||
|
||||
if (tws_api_get_role() == TWS_ROLE_MASTER) {
|
||||
tws_api_send_data_to_sibling(tmp_buf, offset, TWS_FUNC_ID_ADV_SETTING_SYNC);
|
||||
}
|
||||
|
||||
if (tmp_buf) {
|
||||
free(tmp_buf);
|
||||
}
|
||||
#endif
|
||||
// 处理函数
|
||||
hearing_aid_update_handle(data, len);
|
||||
return 0;
|
||||
}
|
||||
|
||||
extern int custom_app_send_user_data(u8 *data, u16 len);
|
||||
int app_third_party_hearing_aid_resp(u8 *data, u16 len)
|
||||
{
|
||||
if (custom_app_send_user_data(data, len)) {
|
||||
if (spp_opt && spp_opt->send_data) {
|
||||
return spp_opt->send_data(NULL, data, (u32)len);
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
#else
|
||||
int app_third_party_hearing_aid_handle(u8 *data, u16 len)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
int app_third_party_hearing_aid_resp(u8 *data, u16 len)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
void adv_hearing_aid_init(void)
|
||||
{
|
||||
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
@ -0,0 +1,26 @@
|
||||
#ifndef __ADV_HEARING_AID_SETTING_H__
|
||||
#define __ADV_HEARING_AID_SETTING_H__
|
||||
|
||||
#include "le_rcsp_adv_module.h"
|
||||
#include "audio_hearing_aid.h"
|
||||
|
||||
// 是否使用三方的ble/edr数据传输
|
||||
#define ASSISTED_HEARING_CUSTOM_TRASNDATA 0
|
||||
|
||||
void adv_hearing_aid_init(void);
|
||||
|
||||
void set_hearing_aid_setting(u8 *hear_aid_setting);
|
||||
void get_hearing_aid_setting(u8 *hear_aid_setting);
|
||||
void deal_hearing_aid_setting(u8 opCode, u8 opCode_SN, u8 *hear_aid_setting, u8 write_en, u8 type_sync);
|
||||
void get_dha_fitting_info(u8 *dha_fitting_info);
|
||||
|
||||
// 主动推数给app
|
||||
u32 hearing_aid_rcsp_notify(u8 *data, u16 data_len);
|
||||
// app回复函数
|
||||
u32 hearing_aid_rcsp_response(u8 *data, u16 data_len);
|
||||
|
||||
// 第三方调用函数
|
||||
int app_third_party_hearing_aid_handle(u8 *data, u16 len);
|
||||
int app_third_party_hearing_aid_resp(u8 *data, u16 len);
|
||||
|
||||
#endif
|
||||
@ -0,0 +1,18 @@
|
||||
#ifndef __ADV_HIGH_LOW_VOL__
|
||||
#define __ADV_HIGH_LOW_VOL__
|
||||
|
||||
#include "le_rcsp_adv_module.h"
|
||||
|
||||
#if RCSP_ADV_HIGH_LOW_SET
|
||||
|
||||
struct _HIGL_LOW_VOL {
|
||||
int low_vol;
|
||||
int high_vol;
|
||||
};
|
||||
|
||||
void get_high_low_vol_info(u8 *vol_gain_param);
|
||||
void set_high_low_vol_info(u8 *vol_gain_param);
|
||||
void deal_high_low_vol(u8 *vol_gain_data, u8 write_vm, u8 tws_sync);
|
||||
|
||||
#endif
|
||||
#endif
|
||||
@ -0,0 +1,81 @@
|
||||
#include "app_config.h"
|
||||
#include "syscfg_id.h"
|
||||
#include "user_cfg_id.h"
|
||||
#include "adv_high_low_vol.h"
|
||||
|
||||
#include "adv_setting_common.h"
|
||||
#include "rcsp_adv_tws_sync.h"
|
||||
#include "rcsp_adv_opt.h"
|
||||
|
||||
#if (RCSP_ADV_EN)
|
||||
#if RCSP_ADV_HIGH_LOW_SET
|
||||
|
||||
static struct _HIGL_LOW_VOL high_low_vol = {
|
||||
.low_vol = 12,
|
||||
.high_vol = 12,
|
||||
};
|
||||
|
||||
extern int get_bt_tws_connect_status();
|
||||
extern int audio_out_eq_spec_set_gain(u8 idx, int gain);
|
||||
|
||||
void get_high_low_vol_info(u8 *vol_gain_param)
|
||||
{
|
||||
memcpy(vol_gain_param, &high_low_vol, sizeof(struct _HIGL_LOW_VOL));
|
||||
}
|
||||
|
||||
void set_high_low_vol_info(u8 *vol_gain_param)
|
||||
{
|
||||
memcpy(&high_low_vol, vol_gain_param, sizeof(struct _HIGL_LOW_VOL));
|
||||
}
|
||||
|
||||
static void update_high_low_vol_vm_value(u8 *vol_gain_param)
|
||||
{
|
||||
syscfg_write(CFG_RCSP_ADV_HIGH_LOW_VOL, vol_gain_param, sizeof(struct _HIGL_LOW_VOL));
|
||||
}
|
||||
|
||||
static void high_low_vol_setting_sync(u8 *vol_gain_param)
|
||||
{
|
||||
#if TCFG_USER_TWS_ENABLE
|
||||
if (get_bt_tws_connect_status()) {
|
||||
update_adv_setting(BIT(ATTR_TYPE_HIGH_LOW_VOL));
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
static void high_low_vol_state_update(void)
|
||||
{
|
||||
#if (TCFG_AUDIO_OUT_EQ_ENABLE != 0)
|
||||
static int low_vol = 0;
|
||||
static int high_vol = 0;
|
||||
if (low_vol != high_low_vol.low_vol) {
|
||||
audio_out_eq_spec_set_gain(0, high_low_vol.low_vol - 12);
|
||||
low_vol = high_low_vol.low_vol;
|
||||
}
|
||||
if (high_vol != high_low_vol.high_vol) {
|
||||
audio_out_eq_spec_set_gain(1, high_low_vol.high_vol - 12);
|
||||
high_vol = high_low_vol.high_vol;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void deal_high_low_vol(u8 *vol_gain_data, u8 write_vm, u8 tws_sync)
|
||||
{
|
||||
int vol_gain_param[2] = {0};
|
||||
if (!vol_gain_data) {
|
||||
get_high_low_vol_info((u8 *)vol_gain_param);
|
||||
} else {
|
||||
memcpy((u8 *)&vol_gain_param, vol_gain_data, sizeof(vol_gain_param));
|
||||
set_high_low_vol_info(vol_gain_data);
|
||||
printf("low %d, high %d\n", vol_gain_param[0], vol_gain_param[1]);
|
||||
}
|
||||
if (write_vm) {
|
||||
update_high_low_vol_vm_value((u8 *)vol_gain_param);
|
||||
}
|
||||
if (tws_sync) {
|
||||
high_low_vol_setting_sync((u8 *)vol_gain_param);
|
||||
}
|
||||
high_low_vol_state_update();
|
||||
}
|
||||
|
||||
#endif
|
||||
#endif
|
||||
@ -0,0 +1,219 @@
|
||||
#include "app_config.h"
|
||||
#include "syscfg_id.h"
|
||||
#include "user_cfg_id.h"
|
||||
#include "key_event_deal.h"
|
||||
#include "le_rcsp_adv_module.h"
|
||||
|
||||
#include "adv_key_setting.h"
|
||||
#include "adv_setting_common.h"
|
||||
#include "rcsp_adv_tws_sync.h"
|
||||
#include "rcsp_adv_opt.h"
|
||||
|
||||
#include "adv_anc_voice_key.h"
|
||||
|
||||
#if (RCSP_ADV_EN)
|
||||
#if RCSP_ADV_KEY_SET_ENABLE
|
||||
|
||||
extern int get_bt_tws_connect_status();
|
||||
static u8 rcsp_adv_key_event_flag = 0x0;
|
||||
static void enable_adv_key_event(void)
|
||||
{
|
||||
rcsp_adv_key_event_flag = 1;
|
||||
}
|
||||
|
||||
static u8 get_adv_key_event_status(void)
|
||||
{
|
||||
return rcsp_adv_key_event_flag;
|
||||
}
|
||||
|
||||
static void disable_adv_key_event(void)
|
||||
{
|
||||
rcsp_adv_key_event_flag = 0;
|
||||
}
|
||||
|
||||
void set_key_setting(u8 *key_setting_info)
|
||||
{
|
||||
_s_info.key_setting[3 * 0 + 2] = key_setting_info[0];
|
||||
_s_info.key_setting[3 * 2 + 2] = key_setting_info[1];
|
||||
_s_info.key_setting[3 * 1 + 2] = key_setting_info[2];
|
||||
_s_info.key_setting[3 * 3 + 2] = key_setting_info[3];
|
||||
}
|
||||
|
||||
void get_key_setting(u8 *key_setting_info)
|
||||
{
|
||||
key_setting_info[0] = _s_info.key_setting[3 * 0 + 2];
|
||||
key_setting_info[1] = _s_info.key_setting[3 * 2 + 2];
|
||||
key_setting_info[2] = _s_info.key_setting[3 * 1 + 2];
|
||||
key_setting_info[3] = _s_info.key_setting[3 * 3 + 2];
|
||||
}
|
||||
|
||||
static void update_key_setting_vm_value(u8 *key_setting_info)
|
||||
{
|
||||
syscfg_write(CFG_RCSP_ADV_KEY_SETTING, key_setting_info, 4);
|
||||
}
|
||||
|
||||
static void key_setting_sync(u8 *key_setting_info)
|
||||
{
|
||||
#if TCFG_USER_TWS_ENABLE
|
||||
if (get_bt_tws_connect_status()) {
|
||||
update_adv_setting(BIT(ATTR_TYPE_KEY_SETTING));
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void deal_key_setting(u8 *key_setting_info, u8 write_vm, u8 tws_sync)
|
||||
{
|
||||
u8 key_setting[4];
|
||||
if (!key_setting_info) {
|
||||
get_key_setting(key_setting);
|
||||
} else {
|
||||
memcpy(key_setting, key_setting_info, 4);
|
||||
}
|
||||
// 1、写入VM
|
||||
if (write_vm) {
|
||||
update_key_setting_vm_value(key_setting);
|
||||
}
|
||||
// 2、同步对端
|
||||
if (tws_sync) {
|
||||
key_setting_sync(key_setting);
|
||||
}
|
||||
// 3、更新状态
|
||||
enable_adv_key_event();
|
||||
}
|
||||
|
||||
#define ADV_POWER_ON_OFF 0
|
||||
enum ADV_KEY_TYPE {
|
||||
ADV_KEY_TYPE_NULL = 0x0,
|
||||
#if ADV_POWER_ON_OFF
|
||||
ADV_KEY_TYPE_POWER_ON,
|
||||
ADV_KEY_TYPE_POWER_OFF,
|
||||
#endif
|
||||
ADV_KEY_TYPE_PREV = 0x3,
|
||||
ADV_KEY_TYPE_NEXT,
|
||||
ADV_KEY_TYPE_PP,
|
||||
ADV_KEY_TYPE_ANSWER_CALL,
|
||||
ADV_KEY_TYPE_HANG_UP,
|
||||
ADV_KEY_TYPE_CALL_BACK,
|
||||
ADV_KEY_TYPE_INC_VOICE,
|
||||
ADV_KEY_TYPE_DESC_VOICE,
|
||||
ADV_KEY_TYPE_TAKE_PHOTO,
|
||||
ADV_KEY_TYPE_ANC_VOICE = 0xFF,
|
||||
};
|
||||
|
||||
static u8 get_adv_key_opt(u8 key_action, u8 channel)
|
||||
{
|
||||
u8 opt;
|
||||
for (opt = 0; opt < sizeof(_s_info.key_setting); opt += 3) {
|
||||
if (_s_info.key_setting[opt] == channel &&
|
||||
_s_info.key_setting[opt + 1] == key_action) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (sizeof(_s_info.key_setting) == opt) {
|
||||
return -1;
|
||||
}
|
||||
switch (_s_info.key_setting[opt + 2]) {
|
||||
case ADV_KEY_TYPE_NULL:
|
||||
//opt = KEY_NULL;
|
||||
opt = ADV_KEY_TYPE_NULL;
|
||||
break;
|
||||
#if ADV_POWER_ON_OFF
|
||||
case ADV_KEY_TYPE_POWER_ON:
|
||||
opt = KEY_POWER_ON;
|
||||
break;
|
||||
case ADV_KEY_TYPE_POWER_OFF:
|
||||
opt = KEY_RCSP_POWEROFF;
|
||||
break;
|
||||
#endif
|
||||
case ADV_KEY_TYPE_PREV:
|
||||
opt = KEY_MUSIC_PREV;
|
||||
break;
|
||||
case ADV_KEY_TYPE_NEXT:
|
||||
opt = KEY_MUSIC_NEXT;
|
||||
break;
|
||||
case ADV_KEY_TYPE_PP:
|
||||
opt = KEY_MUSIC_PP;
|
||||
break;
|
||||
case ADV_KEY_TYPE_ANSWER_CALL:
|
||||
opt = KEY_CALL_ANSWER;
|
||||
break;
|
||||
case ADV_KEY_TYPE_HANG_UP:
|
||||
opt = KEY_CALL_HANG_UP;
|
||||
break;
|
||||
case ADV_KEY_TYPE_CALL_BACK:
|
||||
opt = KEY_CALL_LAST_NO;
|
||||
break;
|
||||
case ADV_KEY_TYPE_INC_VOICE:
|
||||
opt = KEY_VOL_UP;
|
||||
break;
|
||||
case ADV_KEY_TYPE_DESC_VOICE:
|
||||
opt = KEY_VOL_DOWN;
|
||||
break;
|
||||
case ADV_KEY_TYPE_TAKE_PHOTO:
|
||||
opt = KEY_HID_CONTROL;
|
||||
break;
|
||||
case ADV_KEY_TYPE_ANC_VOICE:
|
||||
update_anc_voice_key_opt();
|
||||
opt = KEY_NULL;
|
||||
break;
|
||||
}
|
||||
return opt;
|
||||
}
|
||||
|
||||
void set_key_event_by_rcsp_info(struct sys_event *event, u8 *key_event)
|
||||
{
|
||||
if (0 == get_adv_key_event_status()) {
|
||||
return;
|
||||
}
|
||||
u8 key_action = 0;
|
||||
struct key_event *key = &event->u.key;
|
||||
switch (key->event) {
|
||||
case 0:
|
||||
// 单击
|
||||
key_action = 0x1;
|
||||
break;
|
||||
case 4:
|
||||
// 双击
|
||||
key_action = 0x2;
|
||||
break;
|
||||
default:
|
||||
return;
|
||||
}
|
||||
|
||||
#if (TCFG_CHARGESTORE_ENABLE && TCFG_USER_TWS_ENABLE)
|
||||
u8 channel = tws_api_get_local_channel();
|
||||
|
||||
if (get_bt_tws_connect_status()) {
|
||||
channel = tws_api_get_local_channel();
|
||||
}
|
||||
#else
|
||||
u8 channel = 'U';
|
||||
#endif
|
||||
|
||||
switch (channel) {
|
||||
case 'U':
|
||||
case 'L':
|
||||
channel = (u32) event->arg == KEY_EVENT_FROM_TWS ? 2 : 1;
|
||||
break;
|
||||
case 'R':
|
||||
channel = (u32) event->arg == KEY_EVENT_FROM_TWS ? 1 : 2;
|
||||
break;
|
||||
default:
|
||||
return;
|
||||
}
|
||||
|
||||
key_action = get_adv_key_opt(key_action, channel);
|
||||
if ((u8) - 1 != key_action) {
|
||||
*key_event = key_action ? key_action : KEY_NULL;
|
||||
}
|
||||
}
|
||||
#else
|
||||
|
||||
|
||||
void set_key_event_by_rcsp_info(struct sys_event *event, u8 *key_event)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
#endif
|
||||
#endif
|
||||
@ -0,0 +1,13 @@
|
||||
#ifndef __ADV_KEY_SETTING_H__
|
||||
#define __ADV_KEY_SETTING_H__
|
||||
|
||||
|
||||
#include "le_rcsp_adv_module.h"
|
||||
|
||||
#if RCSP_ADV_KEY_SET_ENABLE
|
||||
|
||||
void set_key_setting(u8 *key_setting_info);
|
||||
void get_key_setting(u8 *key_setting_info);
|
||||
|
||||
#endif
|
||||
#endif
|
||||
@ -0,0 +1,145 @@
|
||||
#include "app_config.h"
|
||||
#include "syscfg_id.h"
|
||||
#include "user_cfg_id.h"
|
||||
#include "asm/pwm_led.h"
|
||||
#include "user_cfg.h"
|
||||
#include "ui_manage.h"
|
||||
#include "le_rcsp_adv_module.h"
|
||||
|
||||
#include "adv_led_setting.h"
|
||||
#include "adv_setting_common.h"
|
||||
#include "rcsp_adv_tws_sync.h"
|
||||
#include "rcsp_adv_opt.h"
|
||||
|
||||
#if (RCSP_ADV_EN)
|
||||
#if RCSP_ADV_LED_SET_ENABLE
|
||||
|
||||
enum ADV_LED_TYPE {
|
||||
ADV_LED_TYPE_ALL_OFF = 0x0,
|
||||
ADV_LED_TYPE_RED_ON,
|
||||
ADV_LED_TYPE_BLUE_ON,
|
||||
ADV_LED_TYPE_RAD_BREATHE,
|
||||
ADV_LED_TYPE_BLUE_BREATHE,
|
||||
ADV_LED_TYPE_FAST_FLASH,
|
||||
ADV_LED_TYPE_SLOW_FLASH,
|
||||
};
|
||||
|
||||
extern STATUS *get_led_config(void);
|
||||
extern int get_bt_tws_connect_status();
|
||||
|
||||
|
||||
__attribute__((weak))
|
||||
u8 adv_get_led_status(void)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
static u8 adv_led_value_conversion(u8 adv_led_opt)
|
||||
{
|
||||
u8 conversion_value = adv_led_opt;
|
||||
switch (adv_led_opt) {
|
||||
case ADV_LED_TYPE_ALL_OFF:
|
||||
conversion_value = PWM_LED_ALL_OFF;
|
||||
break;
|
||||
case ADV_LED_TYPE_RED_ON:
|
||||
conversion_value = PWM_LED1_ON;
|
||||
break;
|
||||
case ADV_LED_TYPE_BLUE_ON:
|
||||
conversion_value = PWM_LED0_ON;
|
||||
break;
|
||||
case ADV_LED_TYPE_RAD_BREATHE:
|
||||
conversion_value = PWM_LED1_BREATHE;
|
||||
break;
|
||||
case ADV_LED_TYPE_BLUE_BREATHE:
|
||||
conversion_value = PWM_LED0_BREATHE;
|
||||
break;
|
||||
case ADV_LED_TYPE_FAST_FLASH:
|
||||
conversion_value = PWM_LED0_LED1_FAST_FLASH;
|
||||
break;
|
||||
case ADV_LED_TYPE_SLOW_FLASH:
|
||||
conversion_value = PWM_LED0_LED1_SLOW_FLASH;
|
||||
break;
|
||||
}
|
||||
return conversion_value;
|
||||
}
|
||||
|
||||
void set_led_setting(u8 *led_setting_info)
|
||||
{
|
||||
_s_info.led_status[2 * 0 + 1] = led_setting_info[0];
|
||||
_s_info.led_status[2 * 1 + 1] = led_setting_info[1];
|
||||
_s_info.led_status[2 * 2 + 1] = led_setting_info[2];
|
||||
}
|
||||
|
||||
void get_led_setting(u8 *led_setting_info)
|
||||
{
|
||||
led_setting_info[0] = _s_info.led_status[2 * 0 + 1];
|
||||
led_setting_info[1] = _s_info.led_status[2 * 1 + 1];
|
||||
led_setting_info[2] = _s_info.led_status[2 * 2 + 1];
|
||||
}
|
||||
|
||||
// 1、写入VM
|
||||
static void update_led_setting_vm_value(u8 *led_setting_info)
|
||||
{
|
||||
syscfg_write(CFG_RCSP_ADV_LED_SETTING, led_setting_info, 3);
|
||||
}
|
||||
// 2、同步对端
|
||||
static void led_setting_sync(u8 *led_setting_info)
|
||||
{
|
||||
#if TCFG_USER_TWS_ENABLE
|
||||
if (get_bt_tws_connect_status()) {
|
||||
update_adv_setting(BIT(ATTR_TYPE_LED_SETTING));
|
||||
}
|
||||
#endif
|
||||
}
|
||||
// 3、更新状态
|
||||
void update_led_setting_state(void)
|
||||
{
|
||||
u8 led_setting_info[3];
|
||||
get_led_setting(led_setting_info);
|
||||
|
||||
// 直接修改led表
|
||||
STATUS *p_led = get_led_config();
|
||||
// 未配对
|
||||
p_led->bt_init_ok = adv_led_value_conversion(led_setting_info[0]);
|
||||
p_led->bt_disconnect = adv_led_value_conversion(led_setting_info[0]);
|
||||
// 未连接
|
||||
p_led->tws_connect_ok = adv_led_value_conversion(led_setting_info[1]);
|
||||
// 连接
|
||||
p_led->bt_connect_ok = adv_led_value_conversion(led_setting_info[2]);
|
||||
|
||||
switch (adv_get_led_status()) {
|
||||
case STATUS_BT_INIT_OK:
|
||||
case STATUS_BT_DISCONN:
|
||||
ui_update_status(STATUS_BT_INIT_OK);
|
||||
break;
|
||||
case STATUS_BT_TWS_CONN:
|
||||
ui_update_status(STATUS_BT_TWS_CONN);
|
||||
break;
|
||||
case STATUS_PHONE_ACTIV:
|
||||
case STATUS_PHONE_OUT:
|
||||
case STATUS_PHONE_INCOME:
|
||||
case STATUS_BT_CONN:
|
||||
ui_update_status(STATUS_BT_CONN);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void deal_led_setting(u8 *led_setting_info, u8 write_vm, u8 tws_sync)
|
||||
{
|
||||
u8 led_setting[3];
|
||||
if (!led_setting_info) {
|
||||
get_led_setting(led_setting);
|
||||
} else {
|
||||
memcpy(led_setting, led_setting_info, 3);
|
||||
}
|
||||
if (write_vm) {
|
||||
update_led_setting_vm_value(led_setting);
|
||||
}
|
||||
if (tws_sync) {
|
||||
led_setting_sync(led_setting);
|
||||
}
|
||||
update_led_setting_state();
|
||||
}
|
||||
|
||||
#endif
|
||||
#endif
|
||||
@ -0,0 +1,13 @@
|
||||
#ifndef __ADV_LED_SETTING_H__
|
||||
#define __ADV_LED_SETTING_H__
|
||||
|
||||
|
||||
#include "le_rcsp_adv_module.h"
|
||||
|
||||
#if RCSP_ADV_LED_SET_ENABLE
|
||||
|
||||
void set_led_setting(u8 *led_setting_info);
|
||||
void get_led_setting(u8 *led_setting_info);
|
||||
|
||||
#endif
|
||||
#endif
|
||||
@ -0,0 +1,155 @@
|
||||
#include "app_config.h"
|
||||
#include "syscfg_id.h"
|
||||
#include "user_cfg_id.h"
|
||||
#include "le_rcsp_adv_module.h"
|
||||
|
||||
#include "adv_mic_setting.h"
|
||||
#include "adv_setting_common.h"
|
||||
#include "rcsp_adv_tws_sync.h"
|
||||
#include "rcsp_adv_opt.h"
|
||||
|
||||
#if (RCSP_ADV_EN)
|
||||
#if RCSP_ADV_MIC_SET_ENABLE
|
||||
|
||||
extern void test_esco_role_switch(u8 flag);
|
||||
extern void tws_conn_switch_role();
|
||||
extern int get_bt_tws_connect_status();
|
||||
static void mic_setting_info_deal(u8 mic_info_data)
|
||||
{
|
||||
#if TCFG_USER_TWS_ENABLE
|
||||
u8 channel = tws_api_get_local_channel();
|
||||
printf("%s, %d\n", __FUNCTION__, channel);
|
||||
|
||||
if (tws_api_get_role() == TWS_ROLE_MASTER) {
|
||||
printf("-----master-----\n");
|
||||
} else {
|
||||
printf("-----role-----\n");
|
||||
}
|
||||
switch (mic_info_data) {
|
||||
case 0x01:
|
||||
if (get_bt_tws_connect_status()) {
|
||||
printf("-------auto--------\n");
|
||||
tws_api_auto_role_switch_enable();
|
||||
}
|
||||
break;
|
||||
case 0x02:
|
||||
if (get_bt_tws_connect_status()) {
|
||||
if (channel != 'L') {
|
||||
printf("-------!L--------\n");
|
||||
tws_api_auto_role_switch_disable();
|
||||
tws_conn_switch_role();
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 0x03:
|
||||
if (get_bt_tws_connect_status()) {
|
||||
if (channel != 'R') {
|
||||
printf("-------!R--------\n");
|
||||
tws_api_auto_role_switch_disable();
|
||||
tws_conn_switch_role();
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void set_mic_setting(u8 mic_setting_info)
|
||||
{
|
||||
_s_info.mic_mode = mic_setting_info;
|
||||
}
|
||||
|
||||
u8 get_mic_setting(void)
|
||||
{
|
||||
return _s_info.mic_mode;
|
||||
}
|
||||
|
||||
static void update_mic_setting_vm_value(u8 mic_setting_info)
|
||||
{
|
||||
syscfg_write(CFG_RCSP_ADV_MIC_SETTING, &mic_setting_info, 1);
|
||||
}
|
||||
|
||||
static void adv_mic_setting_sync(u8 mic_setting_info)
|
||||
{
|
||||
#if TCFG_USER_TWS_ENABLE
|
||||
if (get_bt_tws_connect_status()) {
|
||||
update_adv_setting(BIT(ATTR_TYPE_MIC_SETTING));
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void deal_mic_setting(u8 mic_setting_info, u8 write_vm, u8 tws_sync)
|
||||
{
|
||||
if (!mic_setting_info) {
|
||||
mic_setting_info = get_mic_setting();
|
||||
} else {
|
||||
set_mic_setting(mic_setting_info);
|
||||
}
|
||||
if (write_vm) {
|
||||
update_mic_setting_vm_value(mic_setting_info);
|
||||
}
|
||||
if (tws_sync) {
|
||||
adv_mic_setting_sync(mic_setting_info);
|
||||
}
|
||||
mic_setting_info_deal(mic_setting_info);
|
||||
}
|
||||
|
||||
|
||||
//通话时,固定mic的位置,mode--esco state
|
||||
void rcsp_user_mic_fixed_deal(u8 mode)
|
||||
{
|
||||
u8 channel = tws_api_get_local_channel();
|
||||
|
||||
if (!get_bt_tws_connect_status()) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (mode == 0) {
|
||||
test_esco_role_switch(0);
|
||||
return;
|
||||
}
|
||||
|
||||
if ((tws_api_get_role() == TWS_ROLE_MASTER)
|
||||
&& (tws_api_get_tws_state() | TWS_STA_ESCO_OPEN)) {
|
||||
|
||||
switch (get_mic_setting()) {
|
||||
case 0x02:
|
||||
if (get_bt_tws_connect_status()) {
|
||||
if (channel != 'L') {
|
||||
printf("mic_sw_l\n");
|
||||
test_esco_role_switch(1);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case 0x03:
|
||||
if (get_bt_tws_connect_status()) {
|
||||
if (channel != 'R') {
|
||||
printf("mic_sw_r\n");
|
||||
test_esco_role_switch(1);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
default:
|
||||
printf("mic_sw_auto\n");
|
||||
test_esco_role_switch(0);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
void rcsp_user_mic_fixed_deal(u8 mode)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#endif
|
||||
@ -0,0 +1,15 @@
|
||||
#ifndef __ADV_MIC_SETTING_H__
|
||||
#define __ADV_MIC_SETTING_H__
|
||||
|
||||
|
||||
#include "le_rcsp_adv_module.h"
|
||||
|
||||
#if RCSP_ADV_MIC_SET_ENABLE
|
||||
|
||||
void set_mic_setting(u8 mic_setting_info);
|
||||
u8 get_mic_setting(void);
|
||||
#endif
|
||||
|
||||
void rcsp_user_mic_fixed_deal(u8 mode);
|
||||
|
||||
#endif
|
||||
@ -0,0 +1,447 @@
|
||||
#include "app_config.h"
|
||||
#include "syscfg_id.h"
|
||||
#include "user_cfg_id.h"
|
||||
#include "le_rcsp_adv_module.h"
|
||||
|
||||
#include "adv_setting_common.h"
|
||||
#include "rcsp_adv_tws_sync.h"
|
||||
#include "rcsp_adv_opt.h"
|
||||
#include "adv_music_info_setting.h"
|
||||
#include "btstack/avctp_user.h"
|
||||
#include "rcsp_adv_bluetooth.h"
|
||||
#include "bt_tws.h"
|
||||
|
||||
#if (RCSP_ADV_EN)
|
||||
#if RCSP_ADV_MUSIC_INFO_ENABLE
|
||||
|
||||
|
||||
struct music_info_t {
|
||||
u8 title_len;
|
||||
char title[64];
|
||||
u8 artist_len;
|
||||
char artist[64];
|
||||
u8 album_len;
|
||||
char album[64];
|
||||
u8 num_len;
|
||||
char number;
|
||||
u8 total_len;
|
||||
char total[2];
|
||||
u8 genre_len;
|
||||
char genre[16];
|
||||
char time[8];
|
||||
u8 player_state;
|
||||
u8 player_time_min;
|
||||
u8 player_time_sec;
|
||||
u32 curr_player_time;
|
||||
u8 player_time_en;
|
||||
u32 total_time;
|
||||
volatile int get_music_player_timer;
|
||||
};
|
||||
|
||||
struct music_info_t music_info;
|
||||
void JL_rcsp_event_to_user(u32 type, u8 event, u8 *msg, u8 size);
|
||||
|
||||
|
||||
u8 get_player_time_en(void)
|
||||
{
|
||||
return music_info.player_time_en;
|
||||
}
|
||||
|
||||
void set_player_time_en(u8 en)
|
||||
{
|
||||
music_info.player_time_en = en;
|
||||
}
|
||||
|
||||
void reset_player_time_en(void)
|
||||
{
|
||||
music_player_time_timer_deal(music_info.player_time_en);
|
||||
}
|
||||
|
||||
void music_player_time_deal(void *priv)
|
||||
{
|
||||
if (BT_STATUS_PLAYING_MUSIC == get_bt_connect_status()) {
|
||||
user_send_cmd_prepare(USER_CTRL_AVCTP_OPID_GET_PLAY_TIME, 0, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
void get_music_info(void)
|
||||
{
|
||||
//printf("\nsend music info\n");
|
||||
user_send_cmd_prepare(USER_CTRL_AVCTP_OPID_GET_MUSIC_INFO, 0, NULL);
|
||||
}
|
||||
|
||||
void btstack_avrcp_ch_creat_ok(void)
|
||||
{
|
||||
if (tws_api_get_role() == TWS_ROLE_SLAVE) {
|
||||
//printf("\n\n\n\nrcsp ge music info\n");
|
||||
tws_api_sync_call_by_uuid('T', SYNC_CMD_MUSIC_INFO, 300);
|
||||
} else {
|
||||
if ((tws_api_get_tws_state() & TWS_STA_SIBLING_CONNECTED) == 0) {
|
||||
//printf("\n\n\nno tws rcsp ge music info\n\n");
|
||||
get_music_info();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
char *get_music_title(void)
|
||||
{
|
||||
return music_info.title;
|
||||
}
|
||||
|
||||
u8 get_music_title_len(void)
|
||||
{
|
||||
return music_info.title_len;
|
||||
}
|
||||
|
||||
char *get_music_artist(void)
|
||||
{
|
||||
return music_info.artist;
|
||||
}
|
||||
|
||||
u8 get_music_artist_len(void)
|
||||
{
|
||||
return music_info.artist_len;
|
||||
}
|
||||
|
||||
char *get_music_album(void)
|
||||
{
|
||||
return music_info.album;
|
||||
}
|
||||
|
||||
u8 get_music_album_len(void)
|
||||
{
|
||||
return music_info.album_len;
|
||||
}
|
||||
|
||||
char *get_music_number(void)
|
||||
{
|
||||
return &music_info.number;
|
||||
}
|
||||
|
||||
u8 get_music_number_len(void)
|
||||
{
|
||||
return music_info.num_len;
|
||||
}
|
||||
|
||||
char *get_music_total(void)
|
||||
{
|
||||
return music_info.total;
|
||||
}
|
||||
|
||||
u8 get_music_total_len(void)
|
||||
{
|
||||
return music_info.total_len;
|
||||
}
|
||||
|
||||
char *get_music_genre(void)
|
||||
{
|
||||
return music_info.genre;
|
||||
}
|
||||
|
||||
u8 get_music_genre_len(void)
|
||||
{
|
||||
return music_info.genre_len;
|
||||
}
|
||||
|
||||
u16 get_music_total_time(void)
|
||||
{
|
||||
return (music_info.total_time / 1000);
|
||||
}
|
||||
|
||||
u32 get_music_curr_time(void)
|
||||
{
|
||||
return music_info.curr_player_time;
|
||||
/* return (music_info.player_time_min * 60 + music_info.player_time_sec); */
|
||||
}
|
||||
|
||||
u8 bt_music_total_time(u32 time)
|
||||
{
|
||||
music_info.total_time = time;
|
||||
/* printf("get music time %d\n", music_info.total_time); */
|
||||
return 0;
|
||||
}
|
||||
|
||||
u8 get_music_player_state(void)
|
||||
{
|
||||
return music_info.player_state;
|
||||
}
|
||||
|
||||
void rcsp_update_player_state(void)
|
||||
{
|
||||
JL_rcsp_event_to_user(DEVICE_EVENT_FROM_RCSP, MSG_JL_UPDATE_PLAYER_STATE, NULL, 0);
|
||||
}
|
||||
|
||||
|
||||
void bt_status_change(u8 state)
|
||||
{
|
||||
if (BT_STATUS_PLAYING_MUSIC == state) {
|
||||
music_info.player_state = 1;
|
||||
} else {
|
||||
music_info.player_state = 0;
|
||||
}
|
||||
|
||||
if ((tws_api_get_tws_state() & TWS_STA_SIBLING_CONNECTED) == 0) {
|
||||
rcsp_update_player_state();
|
||||
} else {
|
||||
if (tws_api_get_role() == TWS_ROLE_MASTER) {
|
||||
tws_api_sync_call_by_uuid('T', SYNC_CMD_MUSIC_PLAYER_STATE, 300);
|
||||
} else {
|
||||
tws_api_sync_call_by_uuid('T', SYNC_CMD_MUSIC_PLAYER_TIEM_EN, 300);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void stop_get_music_timer(u8 en)
|
||||
{
|
||||
if (en) {
|
||||
music_info.player_time_en = 0;
|
||||
}
|
||||
|
||||
if (music_info.get_music_player_timer) {
|
||||
sys_timeout_del(music_info.get_music_player_timer);
|
||||
music_info.get_music_player_timer = 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void music_player_time_timer_deal(u8 en)
|
||||
{
|
||||
if (en) {
|
||||
if (music_info.get_music_player_timer == 0) {
|
||||
music_info.get_music_player_timer = sys_timer_add(NULL, music_player_time_deal, 800);
|
||||
}
|
||||
} else {
|
||||
if (music_info.get_music_player_timer) {
|
||||
sys_timer_del(music_info.get_music_player_timer);
|
||||
music_info.get_music_player_timer = 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
void music_info_cmd_handle(u8 *p, u16 len)
|
||||
{
|
||||
u8 cmd = *p;
|
||||
u8 *data = p + 1;
|
||||
|
||||
switch (cmd) {
|
||||
case 0x01:
|
||||
user_send_cmd_prepare(USER_CTRL_AVCTP_OPID_PLAY, 0, NULL);
|
||||
break;
|
||||
|
||||
case 0x02:
|
||||
user_send_cmd_prepare(USER_CTRL_AVCTP_OPID_PREV, 0, NULL);
|
||||
break;
|
||||
|
||||
case 0x03:
|
||||
user_send_cmd_prepare(USER_CTRL_AVCTP_OPID_NEXT, 0, NULL);
|
||||
break;
|
||||
|
||||
case 0x04:
|
||||
|
||||
music_info.player_time_en = *data;
|
||||
|
||||
if (*data) {
|
||||
JL_rcsp_event_to_user(DEVICE_EVENT_FROM_RCSP, MSG_JL_UPDATE_MUSIC_PLAYER_TIME_TEMER, data, 1);
|
||||
} else {
|
||||
JL_rcsp_event_to_user(DEVICE_EVENT_FROM_RCSP, MSG_JL_UPDATE_MUSIC_PLAYER_TIME_TEMER, data, 1);
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
u32 char_to_hex(char num, u8 ten_num)
|
||||
{
|
||||
u32 char_num;
|
||||
switch (num) {
|
||||
case '0':
|
||||
char_num = 0;
|
||||
break;
|
||||
case '1':
|
||||
char_num = 1;
|
||||
break;
|
||||
case '2':
|
||||
char_num = 2;
|
||||
break;
|
||||
case '3':
|
||||
char_num = 3;
|
||||
break;
|
||||
case '4':
|
||||
char_num = 4;
|
||||
break;
|
||||
case '5':
|
||||
char_num = 5;
|
||||
break;
|
||||
|
||||
case '6':
|
||||
char_num = 6;
|
||||
break;
|
||||
|
||||
case '7':
|
||||
char_num = 7;
|
||||
break;
|
||||
|
||||
case '8':
|
||||
char_num = 8;
|
||||
break;
|
||||
case '9':
|
||||
char_num = 9;
|
||||
break;
|
||||
default:
|
||||
char_num = 0;
|
||||
|
||||
}
|
||||
|
||||
switch (ten_num) {
|
||||
case 0:
|
||||
char_num = char_num;
|
||||
break;
|
||||
case 1:
|
||||
char_num = char_num * 10;
|
||||
break;
|
||||
case 2:
|
||||
char_num = char_num * 100;
|
||||
break;
|
||||
case 3:
|
||||
char_num = char_num * 1000;
|
||||
break;
|
||||
case 4:
|
||||
char_num = char_num * 10000;
|
||||
break;
|
||||
case 5:
|
||||
char_num = char_num * 100000;
|
||||
break;
|
||||
|
||||
case 6:
|
||||
char_num = char_num * 1000000;
|
||||
break;
|
||||
|
||||
case 7:
|
||||
char_num = char_num * 10000000;
|
||||
break;
|
||||
|
||||
default:
|
||||
char_num = char_num;
|
||||
}
|
||||
|
||||
return char_num;
|
||||
}
|
||||
|
||||
u32 num_char_to_hex(char *c, len)
|
||||
{
|
||||
u32 total_num = 0;
|
||||
u8 i;
|
||||
for (i = 0; i < len; i++) {
|
||||
total_num += char_to_hex(*(c + i), len - i - 1);
|
||||
}
|
||||
return total_num;
|
||||
|
||||
}
|
||||
|
||||
|
||||
void rcsp_adv_music_info_deal(u8 type, u32 time, u8 *info, u16 len)
|
||||
{
|
||||
|
||||
//printf("info len \n");
|
||||
//put_buf(info,len);
|
||||
#if RCSP_ADV_FIND_DEVICE_ENABLE
|
||||
extern u8 find_device_key_flag_get(void);
|
||||
if (find_device_key_flag_get()) {
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
switch (type) {
|
||||
case 0:
|
||||
if (time != music_info.total_time) {
|
||||
/* if(music_info.player_time_en) */
|
||||
{
|
||||
music_info.curr_player_time = time;
|
||||
music_info.player_time_min = time / 1000 / 60;
|
||||
music_info.player_time_sec = time / 1000 - (music_info.player_time_min * 60);
|
||||
|
||||
/* printf("total time %d %d->", music_info.total_time, time); */
|
||||
/* printf("muisc time %d %d->", music_info.player_time_min, music_info.player_time_sec); */
|
||||
JL_rcsp_event_to_user(DEVICE_EVENT_FROM_RCSP, MSG_JL_UPDATE_PLAYER_TIME, NULL, 0);
|
||||
}
|
||||
}
|
||||
return;
|
||||
case 1:
|
||||
if ((info) && (len)) {
|
||||
if (len > 64) {
|
||||
len = 64;
|
||||
}
|
||||
music_info.title_len = len;
|
||||
memcpy(music_info.title, info, len);
|
||||
}
|
||||
break;
|
||||
case 2:
|
||||
if ((info) && (len)) {
|
||||
if (len > 64) {
|
||||
len = 64;
|
||||
}
|
||||
music_info.artist_len = len;
|
||||
memcpy(music_info.artist, info, len);
|
||||
}
|
||||
break;
|
||||
case 3:
|
||||
if ((info) && (len)) {
|
||||
if (len > 64) {
|
||||
len = 64;
|
||||
}
|
||||
music_info.album_len = len;
|
||||
memcpy(music_info.album, info, len);
|
||||
}
|
||||
break;
|
||||
case 4:
|
||||
if ((info) && (len)) {
|
||||
len = 1;
|
||||
music_info.num_len = len;
|
||||
memcpy(&music_info.number, info, len);
|
||||
}
|
||||
break;
|
||||
case 5:
|
||||
if ((info) && (len)) {
|
||||
len = 2;
|
||||
music_info.total_len = len;
|
||||
memcpy(music_info.total, info, len);
|
||||
}
|
||||
break;
|
||||
case 6:
|
||||
if ((info) && (len)) {
|
||||
if (len > 16) {
|
||||
len = 16;
|
||||
}
|
||||
music_info.genre_len = len;
|
||||
memcpy(music_info.genre, info, len);
|
||||
}
|
||||
break;
|
||||
case 7:
|
||||
if ((info) && (len)) {
|
||||
if (len > 8) {
|
||||
len = 8;
|
||||
}
|
||||
memcpy(music_info.time, info, len);
|
||||
|
||||
/* printf("get time %s\n", info); */
|
||||
/* put_buf(music_info.time, len); */
|
||||
music_info.total_time = num_char_to_hex(music_info.time, len);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
if (music_info.player_time_en) {
|
||||
JL_rcsp_event_to_user(DEVICE_EVENT_FROM_RCSP, MSG_JL_UPDATE_MUSIC_INFO, &type, 1);
|
||||
}
|
||||
/* os_time_dly(2); */
|
||||
}
|
||||
|
||||
|
||||
#endif
|
||||
#endif
|
||||
@ -0,0 +1,31 @@
|
||||
#ifndef __ADV_MUSIC_INFO_SETTING_H__
|
||||
#define __ADV_MUSIC_INFO_SETTING_H__
|
||||
|
||||
|
||||
#include "le_rcsp_adv_module.h"
|
||||
|
||||
#if RCSP_ADV_MUSIC_INFO_ENABLE
|
||||
|
||||
char *get_music_title(void);
|
||||
u8 get_music_title_len(void);
|
||||
char *get_music_artist(void);
|
||||
u8 get_music_artist_len(void);
|
||||
char *get_music_album(void);
|
||||
u8 get_music_album_len(void);
|
||||
char *get_music_number(void);
|
||||
u8 get_music_number_len(void);
|
||||
char *get_music_total(void);
|
||||
u8 get_music_total_len(void);
|
||||
char *get_music_genre(void);
|
||||
u8 get_music_genre_len(void);
|
||||
u16 get_music_total_time(void);
|
||||
u32 get_music_curr_time(void);
|
||||
u8 get_music_player_state(void);
|
||||
void music_info_cmd_handle(u8 *p, u16 len);
|
||||
void stop_get_music_timer(u8 en);
|
||||
extern void music_player_time_timer_deal(u8 en);
|
||||
u8 get_player_time_en(void);
|
||||
void set_player_time_en(u8 en);
|
||||
void rcsp_adv_music_info_deal(u8 type, u32 time, u8 *info, u16 len);
|
||||
#endif
|
||||
#endif
|
||||
@ -0,0 +1,27 @@
|
||||
#ifndef __ADV_SCENE_NOISE_REDUCTION_H__
|
||||
#define __ADV_SCENE_NOISE_REDUCTION_H__
|
||||
|
||||
#include "system/includes.h"
|
||||
|
||||
typedef enum {
|
||||
RCSP_SCENE_NOISE_REDUCTION_TYPE_INTELLIGENT = 0x00,
|
||||
RCSP_SCENE_NOISE_REDUCTION_TYPE_MILD = 0x01,
|
||||
RCSP_SCENE_NOISE_REDUCTION_TYPE_BALANCE = 0x02,
|
||||
RCSP_SCENE_NOISE_REDUCTION_TYPE_DEEPNESS = 0x03,
|
||||
} RCSP_SCENE_NOISE_REDUCTION_TYPE;
|
||||
|
||||
/**
|
||||
* @brief 获取场景降噪类型
|
||||
*
|
||||
* @result RCSP_SCENE_NOISE_REDUCTION_TYPE
|
||||
*/
|
||||
RCSP_SCENE_NOISE_REDUCTION_TYPE get_scene_noise_reduction_type();
|
||||
|
||||
/**
|
||||
* @brief 设置场景降噪类型
|
||||
*/
|
||||
void set_scene_noise_reduction_type(RCSP_SCENE_NOISE_REDUCTION_TYPE type);
|
||||
|
||||
|
||||
|
||||
#endif // __ADV_SCENE_NOISE_REDUCTION_H__
|
||||
@ -0,0 +1,31 @@
|
||||
#ifndef __ADV_SETTING_COMMON_H__
|
||||
#define __ADV_SETTING_COMMON_H__
|
||||
|
||||
#include "typedef.h"
|
||||
#include "event.h"
|
||||
|
||||
#if RCSP_ADV_EN
|
||||
struct t_s_info {
|
||||
u8 edr_name[32];
|
||||
u8 key_setting[12];
|
||||
u8 key_extra_setting[4];
|
||||
u8 led_status[6];
|
||||
u8 mic_mode;
|
||||
u8 work_mode;
|
||||
u8 eq_mode_info[11];
|
||||
};
|
||||
extern struct t_s_info _s_info;
|
||||
|
||||
void deal_time_stamp_setting(u32 time_stamp, u8 write_vm, u8 tws_sync);
|
||||
void deal_bt_name_setting(u8 *bt_name_setting, u8 write_vm, u8 tws_sync);
|
||||
void deal_key_setting(u8 *key_setting_info, u8 write_vm, u8 tws_sync);
|
||||
void deal_led_setting(u8 *led_setting_info, u8 write_vm, u8 tws_sync);
|
||||
void deal_mic_setting(u8 mic_setting_info, u8 write_vm, u8 tws_sync);
|
||||
void deal_work_setting(u8 work_setting_info, u8 write_vm, u8 tws_sync, u8 poweron);
|
||||
|
||||
void adv_setting_init(void);
|
||||
void update_adv_setting(u16 type);
|
||||
void update_info_from_adv_vm_info(void);
|
||||
void modify_bt_name_and_reset(u32 msec);
|
||||
#endif
|
||||
#endif
|
||||
@ -0,0 +1,87 @@
|
||||
#include "app_config.h"
|
||||
#include "syscfg_id.h"
|
||||
#include "user_cfg_id.h"
|
||||
#include "rcsp_adv_bluetooth.h"
|
||||
#include "JL_rcsp_protocol.h"
|
||||
#include "le_rcsp_adv_module.h"
|
||||
|
||||
#include "adv_time_stamp_setting.h"
|
||||
#include "adv_setting_common.h"
|
||||
#include "rcsp_adv_tws_sync.h"
|
||||
#include "rcsp_adv_opt.h"
|
||||
|
||||
#if (RCSP_ADV_EN)
|
||||
extern int get_bt_tws_connect_status();
|
||||
static u32 adv_time_stamp = 0;
|
||||
u32 get_adv_time_stamp(void)
|
||||
{
|
||||
return adv_time_stamp;
|
||||
}
|
||||
|
||||
void set_adv_time_stamp(u32 time_stamp)
|
||||
{
|
||||
adv_time_stamp = time_stamp;
|
||||
}
|
||||
|
||||
void sync_setting_by_time_stamp(void)
|
||||
{
|
||||
tws_api_send_data_to_sibling((u8 *)&adv_time_stamp, sizeof(adv_time_stamp), TWS_FUNC_ID_TIME_STAMP_SYNC);
|
||||
}
|
||||
|
||||
void deal_sibling_time_stamp_setting_switch(void *data, u16 len)
|
||||
{
|
||||
u32 time_stamp = *((u32 *)data);
|
||||
if (adv_time_stamp > time_stamp) {
|
||||
JL_rcsp_event_to_user(DEVICE_EVENT_FROM_RCSP, MSG_JL_ADV_SETTING_SYNC, NULL, 0);
|
||||
}
|
||||
}
|
||||
|
||||
void deal_adv_setting_gain_time_stamp(void)
|
||||
{
|
||||
#if TCFG_USER_TWS_ENABLE
|
||||
extern u8 adv_info_device_request(u8 * buf, u16 len);
|
||||
static u8 tws_pair = 0;
|
||||
u8 buf = 2;
|
||||
u8 ret = 0;
|
||||
if (get_bt_tws_connect_status()) {
|
||||
tws_pair = 1;
|
||||
} else {
|
||||
if (tws_pair) {
|
||||
tws_pair = 0;
|
||||
ret = adv_info_device_request(&buf, sizeof(buf));
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
// 1、写入VM
|
||||
static void update_time_stamp_vm_value(u32 time_stamp)
|
||||
{
|
||||
syscfg_write(CFG_RCSP_ADV_TIME_STAMP, (u8 *)&time_stamp, 4);
|
||||
}
|
||||
// 2、同步对端
|
||||
static void adv_time_stamp_sync(u32 time_stamp)
|
||||
{
|
||||
#if TCFG_USER_TWS_ENABLE
|
||||
if (get_bt_tws_connect_status()) {
|
||||
update_adv_setting(BIT(ATTR_TYPE_TIME_STAMP));
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void deal_time_stamp_setting(u32 time_stamp, u8 write_vm, u8 tws_sync)
|
||||
{
|
||||
if (!time_stamp) {
|
||||
time_stamp = get_adv_time_stamp();
|
||||
} else {
|
||||
set_adv_time_stamp(time_stamp);
|
||||
}
|
||||
if (write_vm) {
|
||||
update_time_stamp_vm_value(time_stamp);
|
||||
}
|
||||
if (tws_sync) {
|
||||
adv_time_stamp_sync(time_stamp);
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
@ -0,0 +1,10 @@
|
||||
#ifndef __ADV_TIME_STAMP_SETTING_H__
|
||||
#define __ADV_TIME_STAMP_SETTING_H__
|
||||
|
||||
void set_adv_time_stamp(u32 time_stamp);
|
||||
u32 get_adv_time_stamp(void);
|
||||
void deal_sibling_time_stamp_setting_switch(void *data, u16 len);
|
||||
extern void sync_setting_by_time_stamp(void);
|
||||
void deal_adv_setting_gain_time_stamp(void);
|
||||
|
||||
#endif
|
||||
@ -0,0 +1,18 @@
|
||||
#ifndef __ADV_VOICE_ENHANCEMENT_MODE_H__
|
||||
#define __ADV_VOICE_ENHANCEMENT_MODE_H__
|
||||
|
||||
#include "system/includes.h"
|
||||
|
||||
/**
|
||||
* @brief 获取人声增强模式开关
|
||||
*
|
||||
* @result bool
|
||||
*/
|
||||
bool get_voice_enhancement_mode_switch();
|
||||
|
||||
/**
|
||||
* @brief 设置人声增强模式开关
|
||||
*/
|
||||
void set_voice_enhancement_mode_switch(bool mode_switch);
|
||||
|
||||
#endif // __ADV_VOICE_ENHANCEMENT_MODE_H__
|
||||
@ -0,0 +1,18 @@
|
||||
#ifndef __ADV_WIND_NOISE_DETECTION_H__
|
||||
#define __ADV_WIND_NOISE_DETECTION_H__
|
||||
|
||||
#include "system/includes.h"
|
||||
|
||||
/**
|
||||
* @brief 获取风噪检测开关
|
||||
*
|
||||
* @result bool
|
||||
*/
|
||||
bool get_wind_noise_detection_switch();
|
||||
|
||||
/**
|
||||
* @brief 设置风噪检测开关
|
||||
*/
|
||||
void set_wind_noise_detection_switch(bool detection_switch);
|
||||
|
||||
#endif // __ADV_WIND_NOISE_DETECTION_H__
|
||||
@ -0,0 +1,104 @@
|
||||
#include "app_config.h"
|
||||
#include "syscfg_id.h"
|
||||
#include "user_cfg_id.h"
|
||||
#include "le_rcsp_adv_module.h"
|
||||
|
||||
#include "adv_work_setting.h"
|
||||
#include "adv_setting_common.h"
|
||||
#include "rcsp_adv_tws_sync.h"
|
||||
#include "rcsp_adv_opt.h"
|
||||
#include "os/os_api.h"
|
||||
#include "btstack/avctp_user.h"
|
||||
|
||||
#if (RCSP_ADV_EN)
|
||||
#if RCSP_ADV_WORK_SET_ENABLE
|
||||
|
||||
extern int get_bt_tws_connect_status();
|
||||
extern void bt_set_low_latency_mode(int enable);
|
||||
void set_work_setting(u8 work_setting_info)
|
||||
{
|
||||
_s_info.work_mode = work_setting_info;
|
||||
}
|
||||
|
||||
u8 get_work_setting(void)
|
||||
{
|
||||
return _s_info.work_mode;
|
||||
}
|
||||
|
||||
static void adv_work_setting_vm_value(u8 work_setting_info)
|
||||
{
|
||||
/* syscfg_write(CFG_RCSP_ADV_WORK_SETTING, &work_setting_info, 1); */
|
||||
}
|
||||
|
||||
static void adv_work_setting_sync(u8 work_setting_info)
|
||||
{
|
||||
#if TCFG_USER_TWS_ENABLE
|
||||
if (get_bt_tws_connect_status()) {
|
||||
update_adv_setting(BIT(ATTR_TYPE_WORK_MODE));
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
static void __rcsp_work_set_call(void)
|
||||
{
|
||||
//r_f_printf("__rcsp_work_set_call\n");
|
||||
if (1 == _s_info.work_mode) {
|
||||
bt_set_low_latency_mode(0);
|
||||
} else if (2 == _s_info.work_mode) {
|
||||
bt_set_low_latency_mode(1);
|
||||
}
|
||||
}
|
||||
|
||||
static void rcsp_work_set_deal(void)
|
||||
{
|
||||
int err;
|
||||
int msg[3];
|
||||
msg[0] = (int) __rcsp_work_set_call;
|
||||
msg[1] = 1;
|
||||
msg[2] = 0;
|
||||
|
||||
err = os_taskq_post_type("app_core", Q_CALLBACK, 3, msg);
|
||||
//r_printf("err %x\n",err);
|
||||
|
||||
|
||||
}
|
||||
|
||||
static void update_work_setting_state(void)
|
||||
{
|
||||
//r_f_printf("set deal\n");
|
||||
rcsp_work_set_deal();
|
||||
}
|
||||
|
||||
void deal_work_setting(u8 work_setting_info, u8 write_vm, u8 tws_sync, u8 poweron)
|
||||
{
|
||||
if (poweron) {
|
||||
__rcsp_work_set_call();
|
||||
} else {
|
||||
if (0 == work_setting_info) {
|
||||
work_setting_info = get_work_setting();
|
||||
} else {
|
||||
set_work_setting(work_setting_info);
|
||||
}
|
||||
if (write_vm) {
|
||||
adv_work_setting_vm_value(work_setting_info);
|
||||
}
|
||||
if (tws_sync) {
|
||||
adv_work_setting_sync(work_setting_info);
|
||||
}
|
||||
update_work_setting_state();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
int ble_vendor_is_slow_state(void)
|
||||
{
|
||||
if ((BT_STATUS_PLAYING_MUSIC == get_bt_connect_status()) && (2 == _s_info.work_mode)) {
|
||||
return 1;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#endif
|
||||
#endif
|
||||
@ -0,0 +1,13 @@
|
||||
#ifndef __ADV_WORK_SETTING_H__
|
||||
#define __ADV_WORK_SETTING_H__
|
||||
|
||||
|
||||
#include "le_rcsp_adv_module.h"
|
||||
|
||||
#if RCSP_ADV_WORK_SET_ENABLE
|
||||
|
||||
void set_work_setting(u8 work_setting_info);
|
||||
u8 get_work_setting(void);
|
||||
|
||||
#endif
|
||||
#endif
|
||||
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,131 @@
|
||||
#ifndef __JL_BLUETOOTH_ADV_H__
|
||||
#define __JL_BLUETOOTH_ADV_H__
|
||||
|
||||
#include "app_config.h"
|
||||
#include "typedef.h"
|
||||
#include "system/event.h"
|
||||
|
||||
#include "le_common.h"
|
||||
#include "ble_user.h"
|
||||
#include "spp_user.h"
|
||||
#if (RCSP_ADV_EN)
|
||||
void rcsp_init();
|
||||
void rcsp_dev_select(u8 type);
|
||||
void function_change_inform(void);
|
||||
|
||||
bool common_msg_deal(u32 param, void *priv);
|
||||
bool ble_msg_deal(u32 param);
|
||||
bool music_msg_deal(u32 param, void *priv);
|
||||
bool linein_msg_deal(u32 param);
|
||||
bool rtc_msg_deal(u32 param);
|
||||
|
||||
#if (RCSP_ADV_ASSISTED_HEARING)
|
||||
void set_hearing_aid_operating_flag();
|
||||
#endif
|
||||
|
||||
void rcsp_exit(void);
|
||||
u8 rcsp_get_asr_status(void);
|
||||
u8 get_rcsp_support_new_reconn_flag(void);
|
||||
|
||||
enum {
|
||||
RCSP_BLE,
|
||||
RCSP_SPP,
|
||||
};
|
||||
|
||||
|
||||
enum {
|
||||
ANDROID,
|
||||
APPLE_IOS,
|
||||
};
|
||||
|
||||
struct JL_AI_VAR {
|
||||
ble_state_e JL_ble_status;
|
||||
struct ble_server_operation_t *rcsp_ble;
|
||||
u8 JL_spp_status;
|
||||
struct spp_operation_t *rcsp_spp;
|
||||
volatile u8 speech_state;
|
||||
u32 feature_mask;
|
||||
u8 device_type;
|
||||
u8 phone_platform;
|
||||
void (*start_speech)(void);
|
||||
void (*stop_speech)(void);
|
||||
u8 err_report;
|
||||
volatile u8 file_browse_lock_flag;
|
||||
u32 return_msg;
|
||||
u8 spec_mode;
|
||||
struct __rcsp_user_var *rcsp_user;
|
||||
volatile u8 rcsp_run_flag;
|
||||
u8 ffr_mode;
|
||||
u16 ffr_time;
|
||||
volatile u8 wait_asr_end;
|
||||
u8 new_reconn_flag; //是否支持新的回连方式(进行地址修改)
|
||||
};
|
||||
|
||||
struct _SPEECH_OVER_DEAL {
|
||||
u8 last_task;
|
||||
u8 status;
|
||||
};
|
||||
|
||||
extern struct JL_AI_VAR jl_ai_var;
|
||||
extern struct _SPEECH_OVER_DEAL speech_deal_val;
|
||||
|
||||
|
||||
#define DEVICE_EVENT_FROM_RCSP (('R' << 24) | ('C' << 16) | ('S' << 8) | 'P')
|
||||
|
||||
enum RCSP_MSG_T {
|
||||
MSG_JL_GET_DEV_UPDATE_FILE_INFO_OFFSET,
|
||||
MSG_JL_INQUIRE_DEVEICE_IF_CAN_UPDATE,
|
||||
MSG_JL_LOADER_DOWNLOAD_START,
|
||||
MSG_JL_UPDATE_START,
|
||||
MSG_JL_ENTER_UPDATE_MODE,
|
||||
MSG_JL_DEV_DISCONNECT,
|
||||
MSG_JL_BLE_UPDATE_START,
|
||||
MSG_JL_SPP_UPDATE_START,
|
||||
MSG_JL_ADV_SETTING_SYNC,
|
||||
MSG_JL_ADV_SETTING_UPDATE,
|
||||
MSG_JL_UPDATE_EQ,
|
||||
MSG_JL_UPDATE_SEQ,
|
||||
MSG_JL_SWITCH_DEVICE,
|
||||
MSG_JL_UPDATE_PLAYER_TIME,
|
||||
MSG_JL_UPDATE_PLAYER_STATE,
|
||||
MSG_JL_UPDATE_MUSIC_INFO,
|
||||
MSG_JL_UPDATE_MUSIC_PLAYER_TIME_TEMER,
|
||||
MSG_JL_UPDAET_ADV_STATE_INFO,
|
||||
MSG_JL_REBOOT_DEV,
|
||||
MSG_JL_FIND_DEVICE_RESUME,
|
||||
MSG_JL_FIND_DEVICE_STOP,
|
||||
MSG_JL_UPDATE_ANC_VOICE,
|
||||
MSG_JL_UPDATE_ANC_VOICE_MAX_SYNC,
|
||||
MSG_JL_UPDATE_ADAPTIVE_NOISE_REDUCTION,
|
||||
MSG_JL_UPDATE_AI_NO_PICK,
|
||||
MSG_JL_UPDATE_SCENE_NOISE_REDUCTION,
|
||||
MSG_JL_UPDATE_WIND_NOISE_DETECTION,
|
||||
MSG_JL_UPDATE_VOICE_ENHANCEMENT_MODE,
|
||||
MSG_JL_TWS_NEED_UPDATE,
|
||||
};
|
||||
|
||||
void JL_rcsp_event_to_user(u32 type, u8 event, u8 *msg, u8 size);
|
||||
int JL_rcsp_event_handler(struct rcsp_event *rcsp);
|
||||
void rcsp_tws_auth_sync_deal(void);
|
||||
extern u8 JL_get_cur_bt_channel_sel(void);
|
||||
|
||||
#define SDK_TYPE_AC690X 0x0
|
||||
#define SDK_TYPE_AC692X 0x1
|
||||
#define SDK_TYPE_AC693X 0x2
|
||||
#define SDK_TYPE_AC695X 0x3
|
||||
#define SDK_TYPE_AC697X 0x4
|
||||
|
||||
#if (defined CONFIG_CPU_BR21)
|
||||
#define RCSP_SDK_TYPE SDK_TYPE_AC692X
|
||||
#elif (defined CONFIG_CPU_BR22)
|
||||
#define RCSP_SDK_TYPE SDK_TYPE_AC693X
|
||||
#elif (defined CONFIG_CPU_BR23)
|
||||
#define RCSP_SDK_TYPE SDK_TYPE_AC695X
|
||||
#elif (defined CONFIG_CPU_BR30)
|
||||
#define RCSP_SDK_TYPE SDK_TYPE_AC697X
|
||||
#else
|
||||
#define RCSP_SDK_TYPE SDK_TYPE_AC693X
|
||||
#endif
|
||||
|
||||
#endif
|
||||
#endif
|
||||
@ -0,0 +1,70 @@
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include "string.h"
|
||||
#include "JL_rcsp_api.h"
|
||||
#include "JL_rcsp_protocol.h"
|
||||
#include "JL_rcsp_packet.h"
|
||||
#include "spp_user.h"
|
||||
#include "btstack/avctp_user.h"
|
||||
#include "system/timer.h"
|
||||
#include "app_core.h"
|
||||
#include "user_cfg.h"
|
||||
#include "asm/pwm_led.h"
|
||||
#include "ui_manage.h"
|
||||
#include "key_event_deal.h"
|
||||
#include "syscfg_id.h"
|
||||
#include "user_cfg_id.h"
|
||||
#include "classic/tws_api.h"
|
||||
#include "event.h"
|
||||
#include "bt_tws.h"
|
||||
#include "custom_cfg.h"
|
||||
#include "app_config.h"
|
||||
|
||||
|
||||
#if (RCSP_ADV_EN)
|
||||
|
||||
/* #define RCSP_USER_DEBUG_EN */
|
||||
#ifdef RCSP_USER_DEBUG_EN
|
||||
#define rcsp_user_putchar(x) putchar(x)
|
||||
#define rcsp_user_printf printf
|
||||
#define rcsp_user_printf_buf(x,len) put_buf(x,len)
|
||||
#else
|
||||
#define rcsp_user_putchar(...)
|
||||
#define rcsp_user_printf(...)
|
||||
#define rcsp_user_printf_buf(...)
|
||||
#endif
|
||||
|
||||
/// 发送需要回复的自定义命令
|
||||
u32 rcsp_user_send_resp_cmd(u8 *data, u16 len)
|
||||
{
|
||||
u32 ret = 0;
|
||||
rcsp_user_printf("send resp cmd\n");
|
||||
rcsp_user_printf_buf(data, len);
|
||||
ret = JL_CMD_send(JL_OPCODE_CUSTOMER_USER, data, len, 1);
|
||||
return ret;
|
||||
}
|
||||
|
||||
void rcsp_user_recv_resp(u8 *data, u16 len)
|
||||
{
|
||||
///收到固件发出去,APP的回复
|
||||
rcsp_user_printf("resp resp\n");
|
||||
rcsp_user_printf_buf(data, len);
|
||||
}
|
||||
|
||||
|
||||
void rcsp_user_recv_cmd_resp(u8 *data, u16 len)
|
||||
{
|
||||
///收到app主动发过来的需要回复的自定义命令
|
||||
///回复在其他地方已完成,开发不需要单独回复
|
||||
rcsp_user_printf("user recv cmd:\n");
|
||||
rcsp_user_printf_buf(data, len);
|
||||
/* rcsp_user_send_resp_cmd(data, len); */
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#endif
|
||||
@ -0,0 +1,17 @@
|
||||
#ifndef __JL_ADV_CUSTOMER_USER_H__
|
||||
#define __JL_ADV_CUSTOMER_USER_H__
|
||||
|
||||
#include "app_config.h"
|
||||
#include "typedef.h"
|
||||
#include "system/event.h"
|
||||
|
||||
#include "le_common.h"
|
||||
#include "spp_user.h"
|
||||
#if (RCSP_ADV_EN)
|
||||
|
||||
void rcsp_user_recv_cmd_resp(u8 *data, u16 len);
|
||||
void rcsp_user_recv_resp(u8 *data, u16 len);
|
||||
u32 rcsp_user_send_resp_cmd(u8 *data, u16 len);
|
||||
|
||||
#endif
|
||||
#endif
|
||||
@ -0,0 +1,495 @@
|
||||
#include "app_config.h"
|
||||
#include "syscfg_id.h"
|
||||
#include "user_cfg_id.h"
|
||||
#include "le_rcsp_adv_module.h"
|
||||
#include "rcsp_adv_bluetooth.h"
|
||||
|
||||
#include "rcsp_adv_opt.h"
|
||||
#include "adv_setting_common.h"
|
||||
#include "rcsp_adv_tws_sync.h"
|
||||
#include "adv_time_stamp_setting.h"
|
||||
#include "adv_bt_name_setting.h"
|
||||
#include "adv_key_setting.h"
|
||||
#include "adv_led_setting.h"
|
||||
#include "adv_mic_setting.h"
|
||||
#include "adv_work_setting.h"
|
||||
#include "adv_eq_setting.h"
|
||||
#include "adv_high_low_vol.h"
|
||||
#include "adv_anc_voice_key.h"
|
||||
#include "bt_tws.h"
|
||||
#include "btstack/avctp_user.h"
|
||||
|
||||
#include "adv_anc_voice.h"
|
||||
#include "adv_hearing_aid_setting.h"
|
||||
|
||||
#if (RCSP_ADV_EN)
|
||||
static u16 adv_setting_event_flag = (u16) - 1;
|
||||
static void set_adv_setting_event_flag(u16 flag)
|
||||
{
|
||||
adv_setting_event_flag = flag;
|
||||
}
|
||||
|
||||
static u16 get_adv_setting_event_flag(void)
|
||||
{
|
||||
return adv_setting_event_flag;
|
||||
}
|
||||
|
||||
static u8 deal_adv_setting_string_item(u8 *des, u8 *src, u8 src_len, u8 type)
|
||||
{
|
||||
des[0] = type;
|
||||
memcpy(des + 1, src, src_len);
|
||||
return src_len + sizeof(type);
|
||||
}
|
||||
|
||||
void update_info_from_adv_vm_info(void)
|
||||
{
|
||||
if (get_adv_setting_event_flag() & BIT(ATTR_TYPE_TIME_STAMP)) {
|
||||
deal_time_stamp_setting(0, 1, 0);
|
||||
}
|
||||
|
||||
#if RCSP_ADV_NAME_SET_ENABLE
|
||||
if (get_adv_setting_event_flag() & BIT(ATTR_TYPE_EDR_NAME)) {
|
||||
deal_bt_name_setting(NULL, 1, 0);
|
||||
}
|
||||
#endif
|
||||
|
||||
#if RCSP_ADV_KEY_SET_ENABLE
|
||||
if (get_adv_setting_event_flag() & BIT(ATTR_TYPE_KEY_SETTING)) {
|
||||
deal_key_setting(NULL, 1, 0);
|
||||
}
|
||||
|
||||
if (get_adv_setting_event_flag() & BIT(ATTR_TYPE_ANC_VOICE_KEY)) {
|
||||
deal_anc_voice_key_setting(NULL, 1, 0);
|
||||
}
|
||||
#endif
|
||||
|
||||
#if RCSP_ADV_LED_SET_ENABLE
|
||||
if (get_adv_setting_event_flag() & BIT(ATTR_TYPE_LED_SETTING)) {
|
||||
deal_led_setting(NULL, 1, 0);
|
||||
}
|
||||
#endif
|
||||
|
||||
#if RCSP_ADV_MIC_SET_ENABLE
|
||||
if (get_adv_setting_event_flag() & BIT(ATTR_TYPE_MIC_SETTING)) {
|
||||
deal_mic_setting(0, 1, 0);
|
||||
}
|
||||
#endif
|
||||
|
||||
#if RCSP_ADV_WORK_SET_ENABLE
|
||||
if (get_adv_setting_event_flag() & BIT(ATTR_TYPE_WORK_MODE)) {
|
||||
deal_work_setting(0, 1, 0, 0);
|
||||
}
|
||||
#endif
|
||||
|
||||
#if RCSP_ADV_EQ_SET_ENABLE
|
||||
if (get_adv_setting_event_flag() & BIT(ATTR_TYPE_EQ_SETTING)) {
|
||||
deal_eq_setting(0, 1, 0);
|
||||
}
|
||||
#endif
|
||||
|
||||
#if RCSP_ADV_HIGH_LOW_SET
|
||||
if (get_adv_setting_event_flag() & BIT(ATTR_TYPE_HIGH_LOW_VOL)) {
|
||||
deal_high_low_vol(NULL, 1, 0);
|
||||
}
|
||||
#endif
|
||||
|
||||
#if (RCSP_ADV_ANC_VOICE)
|
||||
if (get_adv_setting_event_flag() & BIT(ATTR_TYPE_ANC_VOICE)) {
|
||||
deal_anc_voice(NULL, 1, 0);
|
||||
}
|
||||
#endif
|
||||
|
||||
#if (RCSP_ADV_ASSISTED_HEARING)
|
||||
if (get_adv_setting_event_flag() & BIT(ATTR_TYPE_ASSISTED_HEARING)) {
|
||||
deal_hearing_aid_setting(-1, -1, NULL, 1, 0);
|
||||
}
|
||||
#endif
|
||||
|
||||
set_adv_setting_event_flag(0);
|
||||
}
|
||||
|
||||
static u8 adv_read_data_from_vm(u8 syscfg_id, u8 *buf, u8 buf_len)
|
||||
{
|
||||
int len = 0;
|
||||
u8 i = 0;
|
||||
|
||||
|
||||
len = syscfg_read(syscfg_id, buf, buf_len);
|
||||
|
||||
if (len > 0) {
|
||||
for (i = 0; i < buf_len; i++) {
|
||||
if (buf[i] != 0xff) {
|
||||
return (buf_len == len);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void adv_setting_init(void)
|
||||
{
|
||||
u32 time_stamp = 0;
|
||||
if (adv_read_data_from_vm(CFG_RCSP_ADV_TIME_STAMP, (u8 *)&time_stamp, sizeof(time_stamp))) {
|
||||
set_adv_time_stamp(time_stamp);
|
||||
//deal_time_stamp_setting(0, 0, 0);
|
||||
}
|
||||
|
||||
#if RCSP_ADV_NAME_SET_ENABLE
|
||||
u8 bt_name_info[32] = {0};
|
||||
if (adv_read_data_from_vm(CFG_BT_NAME, bt_name_info, sizeof(bt_name_info))) {
|
||||
set_bt_name_setting(bt_name_info);
|
||||
//deal_bt_name_setting(NULL, 0, 0);
|
||||
}
|
||||
#endif
|
||||
|
||||
#if RCSP_ADV_KEY_SET_ENABLE
|
||||
u8 key_setting_info[4] = {0};
|
||||
if (adv_read_data_from_vm(CFG_RCSP_ADV_KEY_SETTING, key_setting_info, sizeof(key_setting_info))) {
|
||||
set_key_setting(key_setting_info);
|
||||
deal_key_setting(NULL, 0, 0);
|
||||
}
|
||||
|
||||
u8 key_anc_voice_mode[4] = {0};
|
||||
if (adv_read_data_from_vm(CFG_RCSP_ADV_ANC_VOICE_KEY, key_anc_voice_mode, sizeof(key_anc_voice_mode))) {
|
||||
set_anc_voice_key_mode(key_anc_voice_mode);
|
||||
deal_anc_voice_key_setting(NULL, 0, 0);
|
||||
}
|
||||
#endif
|
||||
|
||||
#if RCSP_ADV_LED_SET_ENABLE
|
||||
u8 led_setting_info[3] = {0};
|
||||
if (adv_read_data_from_vm(CFG_RCSP_ADV_LED_SETTING, led_setting_info, sizeof(led_setting_info))) {
|
||||
set_led_setting(led_setting_info);
|
||||
deal_led_setting(NULL, 0, 0);
|
||||
}
|
||||
#endif
|
||||
|
||||
#if RCSP_ADV_MIC_SET_ENABLE
|
||||
u8 mic_setting_info = 0;
|
||||
if (adv_read_data_from_vm(CFG_RCSP_ADV_MIC_SETTING, &mic_setting_info, sizeof(mic_setting_info))) {
|
||||
set_mic_setting(mic_setting_info);
|
||||
deal_mic_setting(0, 0, 0);
|
||||
}
|
||||
#endif
|
||||
|
||||
#if RCSP_ADV_WORK_SET_ENABLE
|
||||
u8 work_setting_info = 0;
|
||||
if (adv_read_data_from_vm(CFG_RCSP_ADV_WORK_SETTING, &work_setting_info, sizeof(work_setting_info))) {
|
||||
set_work_setting(work_setting_info);
|
||||
deal_work_setting(0, 0, 0, 1);
|
||||
}
|
||||
#endif
|
||||
|
||||
#if RCSP_ADV_EQ_SET_ENABLE
|
||||
u8 eq_setting_vm_info[11] = {0};
|
||||
u8 eq_setting_info[10] = {0};
|
||||
u8 eq_setting_mode = 0;
|
||||
u8 i;
|
||||
if (adv_read_data_from_vm(CFG_RCSP_ADV_EQ_DATA_SETTING, eq_setting_info, sizeof(eq_setting_info))) {
|
||||
if (adv_read_data_from_vm(CFG_RCSP_ADV_EQ_MODE_SETTING, &eq_setting_mode, sizeof(eq_setting_mode))) {
|
||||
eq_setting_vm_info[0] = eq_setting_mode;
|
||||
memcpy(eq_setting_vm_info + 1, eq_setting_info, sizeof(eq_setting_info));
|
||||
set_eq_setting(eq_setting_vm_info);
|
||||
deal_eq_setting(NULL, 0, 0);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#if RCSP_ADV_HIGH_LOW_SET
|
||||
u8 high_low_vol_setting[8] = {0};
|
||||
if (adv_read_data_from_vm(CFG_RCSP_ADV_HIGH_LOW_VOL, high_low_vol_setting, sizeof(high_low_vol_setting))) {
|
||||
set_high_low_vol_info(high_low_vol_setting);
|
||||
deal_high_low_vol(NULL, 0, 0);
|
||||
}
|
||||
#endif
|
||||
|
||||
#if (RCSP_ADV_ANC_VOICE)
|
||||
u8 anc_voice_setting[25] = {0};
|
||||
if (anc_voice_setting_init()) {
|
||||
if (adv_read_data_from_vm(CFG_RCSP_ADV_ANC_VOICE_MODE, anc_voice_setting, 1)) {
|
||||
if (adv_read_data_from_vm(CFG_RCSP_ADV_ANC_VOICE, anc_voice_setting + 1, sizeof(anc_voice_setting) - 1)) {
|
||||
set_anc_voice_info(anc_voice_setting);
|
||||
deal_anc_voice(NULL, 0, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
// type : 0 ~ 8
|
||||
// mode : 0 - 从vm读出并更新全局变量数据 // 1 - 同步
|
||||
void update_adv_setting(u16 type)
|
||||
{
|
||||
u8 offset = 1;
|
||||
// total_len time name key led mic work eq vol anc anc_voice
|
||||
u8 adv_setting_to_sync[1 + (4 + 1) + (32 + 1) + (4 + 1) + (3 + 1) + (1 + 1) + (1 + 1) + (11 + 1) + (8 + 1) + (25 + 1) + (4 + 1)] = {0};
|
||||
memset(adv_setting_to_sync, 0, sizeof(adv_setting_to_sync));
|
||||
|
||||
if (type & BIT(ATTR_TYPE_TIME_STAMP)) {
|
||||
u32 time_stamp = get_adv_time_stamp();
|
||||
offset += deal_adv_setting_string_item(adv_setting_to_sync + offset, (u8 *)&time_stamp, sizeof(time_stamp), ATTR_TYPE_TIME_STAMP);
|
||||
}
|
||||
|
||||
#if RCSP_ADV_NAME_SET_ENABLE
|
||||
if (type & BIT(ATTR_TYPE_EDR_NAME)) {
|
||||
u8 bt_name_info[32] = {0};
|
||||
get_bt_name_setting(bt_name_info);
|
||||
offset += deal_adv_setting_string_item(adv_setting_to_sync + offset, bt_name_info, sizeof(bt_name_info), ATTR_TYPE_EDR_NAME);
|
||||
}
|
||||
#endif
|
||||
|
||||
#if RCSP_ADV_KEY_SET_ENABLE
|
||||
if (type & BIT(ATTR_TYPE_KEY_SETTING)) {
|
||||
u8 key_setting_info[4] = {0};
|
||||
get_key_setting(key_setting_info);
|
||||
offset += deal_adv_setting_string_item(adv_setting_to_sync + offset, key_setting_info, sizeof(key_setting_info), ATTR_TYPE_KEY_SETTING);
|
||||
}
|
||||
|
||||
if (type & BIT(ATTR_TYPE_ANC_VOICE_KEY)) {
|
||||
u8 key_anc_voice_mode[4] = {0};
|
||||
get_anc_voice_key_mode(key_anc_voice_mode);
|
||||
offset += deal_adv_setting_string_item(adv_setting_to_sync + offset, key_anc_voice_mode, sizeof(key_anc_voice_mode), ATTR_TYPE_ANC_VOICE_KEY);
|
||||
}
|
||||
#endif
|
||||
|
||||
#if RCSP_ADV_LED_SET_ENABLE
|
||||
if (type & BIT(ATTR_TYPE_LED_SETTING)) {
|
||||
u8 led_setting_info[3] = {0};
|
||||
get_led_setting(led_setting_info);
|
||||
offset += deal_adv_setting_string_item(adv_setting_to_sync + offset, led_setting_info, sizeof(led_setting_info), ATTR_TYPE_LED_SETTING);
|
||||
}
|
||||
#endif
|
||||
|
||||
#if RCSP_ADV_MIC_SET_ENABLE
|
||||
if (type & BIT(ATTR_TYPE_MIC_SETTING)) {
|
||||
u8 mic_setting_info = get_mic_setting();
|
||||
offset += deal_adv_setting_string_item(adv_setting_to_sync + offset, &mic_setting_info, sizeof(mic_setting_info), ATTR_TYPE_MIC_SETTING);
|
||||
}
|
||||
#endif
|
||||
|
||||
#if RCSP_ADV_WORK_SET_ENABLE
|
||||
if (type & BIT(ATTR_TYPE_WORK_MODE)) {
|
||||
u8 work_setting_info = get_work_setting();
|
||||
offset += deal_adv_setting_string_item(adv_setting_to_sync + offset, &work_setting_info, sizeof(work_setting_info), ATTR_TYPE_WORK_MODE);
|
||||
}
|
||||
#endif
|
||||
|
||||
#if RCSP_ADV_EQ_SET_ENABLE
|
||||
if (type & BIT(ATTR_TYPE_EQ_SETTING)) {
|
||||
u8 eq_setting_info[11];
|
||||
get_eq_setting(eq_setting_info);
|
||||
offset += deal_adv_setting_string_item(adv_setting_to_sync + offset, eq_setting_info, sizeof(eq_setting_info), ATTR_TYPE_EQ_SETTING);
|
||||
}
|
||||
#endif
|
||||
|
||||
#if RCSP_ADV_HIGH_LOW_SET
|
||||
if (type & BIT(ATTR_TYPE_HIGH_LOW_VOL)) {
|
||||
u8 high_low_vol[8];
|
||||
get_high_low_vol_info(high_low_vol);
|
||||
offset += deal_adv_setting_string_item(adv_setting_to_sync + offset, high_low_vol, sizeof(high_low_vol), ATTR_TYPE_HIGH_LOW_VOL);
|
||||
}
|
||||
#endif
|
||||
|
||||
#if (RCSP_ADV_ANC_VOICE)
|
||||
if (type & BIT(ATTR_TYPE_ANC_VOICE)) {
|
||||
u8 anc_voice_info[25];
|
||||
get_anc_voice_info(anc_voice_info);
|
||||
offset += deal_adv_setting_string_item(adv_setting_to_sync + offset, anc_voice_info, sizeof(anc_voice_info), ATTR_TYPE_ANC_VOICE);
|
||||
}
|
||||
#endif
|
||||
|
||||
#if RCSP_ADV_ASSISTED_HEARING
|
||||
if (((u16) - 1) != type && type & BIT(ATTR_TYPE_ASSISTED_HEARING)) {
|
||||
u8 dha_fitting_data[3 + 2 * 4 * DHA_FITTING_CHANNEL_MAX];
|
||||
get_hearing_aid_setting(dha_fitting_data);
|
||||
offset += deal_adv_setting_string_item(adv_setting_to_sync + offset, dha_fitting_data, sizeof(dha_fitting_data), ATTR_TYPE_ASSISTED_HEARING);
|
||||
}
|
||||
#endif
|
||||
|
||||
if (offset > 1) {
|
||||
adv_setting_to_sync[0] = offset;
|
||||
if (type == ((u16) - 1)) {
|
||||
tws_api_send_data_to_sibling(adv_setting_to_sync, sizeof(adv_setting_to_sync), TWS_FUNC_ID_ADV_SETTING_SYNC);
|
||||
#if RCSP_ADV_LED_SET_ENABLE
|
||||
tws_api_sync_call_by_uuid('T', SYNC_CMD_APP_RESET_LED_UI, 300);
|
||||
#endif
|
||||
} else {
|
||||
if (tws_api_get_role() == TWS_ROLE_MASTER) {
|
||||
tws_api_send_data_to_sibling(adv_setting_to_sync, sizeof(adv_setting_to_sync), TWS_FUNC_ID_ADV_SETTING_SYNC);
|
||||
#if RCSP_ADV_LED_SET_ENABLE
|
||||
tws_api_sync_call_by_uuid('T', SYNC_CMD_APP_RESET_LED_UI, 300);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void deal_sibling_setting(u8 *buf)
|
||||
{
|
||||
u8 type;
|
||||
u8 len = buf[0];
|
||||
u8 offset = 1;
|
||||
u8 *data;
|
||||
u32 time_stamp = 0;
|
||||
set_adv_setting_event_flag(0);
|
||||
while (offset < len) {
|
||||
type = buf[offset++];
|
||||
data = buf + offset;
|
||||
switch (type) {
|
||||
#if RCSP_ADV_NAME_SET_ENABLE
|
||||
case ATTR_TYPE_EDR_NAME:
|
||||
set_bt_name_setting(data);
|
||||
offset += 32;
|
||||
break;
|
||||
#endif
|
||||
#if RCSP_ADV_KEY_SET_ENABLE
|
||||
case ATTR_TYPE_KEY_SETTING :
|
||||
set_key_setting(data);
|
||||
offset += 4;
|
||||
break;
|
||||
case ATTR_TYPE_ANC_VOICE_KEY:
|
||||
set_anc_voice_key_mode(data);
|
||||
offset += 4;
|
||||
break;
|
||||
#endif
|
||||
#if RCSP_ADV_LED_SET_ENABLE
|
||||
case ATTR_TYPE_LED_SETTING :
|
||||
set_led_setting(data);
|
||||
offset += 3;
|
||||
break;
|
||||
#endif
|
||||
#if RCSP_ADV_MIC_SET_ENABLE
|
||||
case ATTR_TYPE_MIC_SETTING :
|
||||
set_mic_setting(*data);
|
||||
offset += 1;
|
||||
break;
|
||||
#endif
|
||||
#if RCSP_ADV_WORK_SET_ENABLE
|
||||
case ATTR_TYPE_WORK_MODE :
|
||||
set_work_setting(*data);
|
||||
offset += 1;
|
||||
break;
|
||||
#endif
|
||||
#if RCSP_ADV_EQ_SET_ENABLE
|
||||
case ATTR_TYPE_EQ_SETTING :
|
||||
/* g_printf("tws eq setting\n"); */
|
||||
set_eq_setting(data);
|
||||
offset += 11;
|
||||
break;
|
||||
#endif
|
||||
#if RCSP_ADV_HIGH_LOW_SET
|
||||
case ATTR_TYPE_HIGH_LOW_VOL:
|
||||
set_high_low_vol_info(data);
|
||||
offset += 8;
|
||||
break;
|
||||
#endif
|
||||
#if (RCSP_ADV_ANC_VOICE)
|
||||
case ATTR_TYPE_ANC_VOICE:
|
||||
set_anc_voice_info(data);
|
||||
offset += 25;
|
||||
break;
|
||||
#endif
|
||||
#if (RCSP_ADV_ASSISTED_HEARING)
|
||||
case ATTR_TYPE_ASSISTED_HEARING:
|
||||
set_hearing_aid_setting(data);
|
||||
offset += 3 + 2 * 4 * DHA_FITTING_CHANNEL_MAX;
|
||||
break;
|
||||
#endif
|
||||
case ATTR_TYPE_TIME_STAMP:
|
||||
time_stamp = (data[0] | (data[1] << 8) | (data[2] << 16) | (data[3] << 24));//*((u32 *)data);
|
||||
|
||||
set_adv_time_stamp(time_stamp);
|
||||
offset += 4;
|
||||
break;
|
||||
default:
|
||||
return;
|
||||
}
|
||||
set_adv_setting_event_flag(get_adv_setting_event_flag() | BIT(type));
|
||||
}
|
||||
// 发送事件
|
||||
JL_rcsp_event_to_user(DEVICE_EVENT_FROM_RCSP, MSG_JL_ADV_SETTING_UPDATE, NULL, 0);
|
||||
}
|
||||
|
||||
#if (0)
|
||||
static void adv_reset_data_to_vm(u8 syscfg_id, u8 *buf, u8 buf_len)
|
||||
{
|
||||
u8 res = 0;
|
||||
res = syscfg_write(syscfg_id, buf, buf_len);
|
||||
}
|
||||
|
||||
u8 rcsp_setting_info_reset() //恢复默认的APP设置
|
||||
{
|
||||
printf("%s", __func__);
|
||||
|
||||
u32 time_stamp = 0xffffffff;
|
||||
adv_reset_data_to_vm(CFG_RCSP_ADV_TIME_STAMP, (u8 *)&time_stamp, sizeof(time_stamp));
|
||||
|
||||
/* #if RCSP_ADV_NAME_SET_ENABLE */
|
||||
/* u8 bt_name_info[32] = {0}; */
|
||||
/* memset(bt_name_info,0xff,32); */
|
||||
/* adv_reset_data_to_vm(CFG_BT_NAME, bt_name_info, sizeof(bt_name_info)); */
|
||||
/* #endif */
|
||||
|
||||
#if RCSP_ADV_KEY_SET_ENABLE
|
||||
u8 key_setting_info[4] = {0};
|
||||
memset(key_setting_info, 0xff, 4);
|
||||
adv_reset_data_to_vm(CFG_RCSP_ADV_KEY_SETTING, key_setting_info, sizeof(key_setting_info));
|
||||
#endif
|
||||
|
||||
#if RCSP_ADV_LED_SET_ENABLE
|
||||
u8 led_setting_info[3] = {0};
|
||||
memset(led_setting_info, 0xff, 3);
|
||||
adv_reset_data_to_vm(CFG_RCSP_ADV_LED_SETTING, led_setting_info, sizeof(led_setting_info));
|
||||
#endif
|
||||
|
||||
#if RCSP_ADV_MIC_SET_ENABLE
|
||||
u8 mic_setting_info = 0xff;
|
||||
adv_reset_data_to_vm(CFG_RCSP_ADV_MIC_SETTING, &mic_setting_info, sizeof(mic_setting_info));
|
||||
#endif
|
||||
|
||||
#if RCSP_ADV_WORK_SET_ENABLE
|
||||
u8 work_setting_info = 0xff;
|
||||
adv_reset_data_to_vm(CFG_RCSP_ADV_WORK_SETTING, &work_setting_info, sizeof(work_setting_info));
|
||||
#endif
|
||||
|
||||
#if RCSP_ADV_EQ_SET_ENABLE
|
||||
u8 eq_setting_info[10] = {0};
|
||||
u8 eq_setting_mode = 0xff;
|
||||
memset(eq_setting_info, 0xff, 10);
|
||||
adv_reset_data_to_vm(CFG_RCSP_ADV_EQ_DATA_SETTING, &eq_setting_info, sizeof(eq_setting_info));
|
||||
adv_reset_data_to_vm(CFG_RCSP_ADV_EQ_MODE_SETTING, &eq_setting_mode, sizeof(eq_setting_mode));
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
u8 remap_app_chargestore_data_deal(u8 *buf, u8 len)
|
||||
{
|
||||
u8 send_buf[30];
|
||||
u8 ret = 0;
|
||||
send_buf[0] = buf[0];
|
||||
//#define CMD_GET_NAME 0xc1
|
||||
switch (buf[0]) {
|
||||
case 0x08:
|
||||
//printf("\n\n\n\n\n\n---------------reset store sys\n");
|
||||
ret = 1 ;
|
||||
|
||||
void bt_tws_remove_pairs();
|
||||
bt_tws_remove_pairs();
|
||||
extern u8 rcsp_setting_info_reset();
|
||||
rcsp_setting_info_reset();
|
||||
user_send_cmd_prepare(USER_CTRL_DEL_ALL_REMOTE_INFO, 0, NULL);
|
||||
os_time_dly(60);
|
||||
cpu_reset();
|
||||
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
#endif
|
||||
@ -0,0 +1,6 @@
|
||||
#ifndef __RCSP_ADV_OPT_H__
|
||||
#define __RCSP_ADV_OPT_H__
|
||||
|
||||
void deal_sibling_setting(u8 *buf);
|
||||
|
||||
#endif
|
||||
@ -0,0 +1,105 @@
|
||||
#include "app_config.h"
|
||||
#include "rcsp_adv_tws_sync.h"
|
||||
#include "adv_setting_common.h"
|
||||
#include "rcsp_adv_opt.h"
|
||||
#include "adv_time_stamp_setting.h"
|
||||
#include "rcsp_adv_bluetooth.h"
|
||||
#include "bt_tws.h"
|
||||
|
||||
#if (RCSP_ADV_EN && TCFG_USER_TWS_ENABLE)
|
||||
static void adv_sync_tws_func_t(void *data, u16 len, bool rx)
|
||||
{
|
||||
if (rx) {
|
||||
deal_sibling_setting((u8 *)data);
|
||||
}
|
||||
}
|
||||
|
||||
REGISTER_TWS_FUNC_STUB(adv_tws_sync) = {
|
||||
.func_id = TWS_FUNC_ID_ADV_SETTING_SYNC,
|
||||
.func = adv_sync_tws_func_t,
|
||||
};
|
||||
|
||||
static void adv_sync_time_stamp_func_t(void *data, u16 len, bool rx)
|
||||
{
|
||||
if (rx) {
|
||||
deal_sibling_time_stamp_setting_switch(data, len);
|
||||
}
|
||||
}
|
||||
|
||||
REGISTER_TWS_FUNC_STUB(adv_time_stamp_sync) = {
|
||||
.func_id = TWS_FUNC_ID_TIME_STAMP_SYNC,
|
||||
.func = adv_sync_time_stamp_func_t,
|
||||
};
|
||||
|
||||
#define TWS_FUNC_ID_ADV_RESET_SYNC \
|
||||
(((u8)('R' + 'C' + 'S' + 'P') << (3 * 8)) | \
|
||||
((u8)('A' + 'D' + 'V') << (2 * 8)) | \
|
||||
((u8)('R' + 'E' + 'S' + 'E' + 'T') << (1 * 8)) | \
|
||||
((u8)('S' + 'Y' + 'N' + 'C') << (0 * 8)))
|
||||
|
||||
static void adv_sync_reset_sync_func_t(int args)
|
||||
{
|
||||
extern void cpu_reset();
|
||||
cpu_reset();
|
||||
}
|
||||
|
||||
TWS_SYNC_CALL_REGISTER(adv_reset_sync) = {
|
||||
.uuid = TWS_FUNC_ID_ADV_RESET_SYNC,
|
||||
.func = adv_sync_reset_sync_func_t,
|
||||
};
|
||||
|
||||
void modify_bt_name_and_reset(u32 msec)
|
||||
{
|
||||
tws_api_sync_call_by_uuid(TWS_FUNC_ID_ADV_RESET_SYNC, 0, msec);
|
||||
}
|
||||
|
||||
#define TWS_FUNC_ID_ADV_FIND_DEV_SYNC \
|
||||
(((u8)('A' + 'D' + 'V') << (3 * 8)) | \
|
||||
((u8)('F' + 'I' + 'N' + 'D') << (2 * 8)) | \
|
||||
((u8)('D' + 'E' + 'V') << (1 * 8)) | \
|
||||
((u8)('S' + 'Y' + 'N' + 'C') << (0 * 8)))
|
||||
|
||||
static void adv_find_dev_sync_func_t(int args)
|
||||
{
|
||||
JL_rcsp_event_to_user(DEVICE_EVENT_FROM_RCSP, MSG_JL_FIND_DEVICE_RESUME, &args, sizeof(args));
|
||||
}
|
||||
|
||||
TWS_SYNC_CALL_REGISTER(adv_find_dev_sync) = {
|
||||
.uuid = TWS_FUNC_ID_ADV_FIND_DEV_SYNC,
|
||||
.func = adv_find_dev_sync_func_t,
|
||||
};
|
||||
|
||||
void find_device_sync(u8 *param, u32 msec)
|
||||
{
|
||||
int priv = 0;
|
||||
if (TWS_ROLE_MASTER == tws_api_get_role()) {
|
||||
memcpy(&priv, param, 3);
|
||||
tws_api_sync_call_by_uuid(TWS_FUNC_ID_ADV_FIND_DEV_SYNC, priv, msec);
|
||||
}
|
||||
}
|
||||
|
||||
#define TWS_FUNC_ID_ADV_FIND_DEV_STOP_TIMER_SYNC \
|
||||
(((u8)('F' + 'I' + 'N' + 'D') << (3 * 8)) | \
|
||||
((u8)('D' + 'E' + 'V') << (2 * 8)) | \
|
||||
((u8)('S' + 'T' + 'O' + 'P') << (1 * 8)) | \
|
||||
((u8)('S' + 'Y' + 'N' + 'C') << (0 * 8)))
|
||||
|
||||
static void adv_find_dev_stop_sync_timer_func_t(int args)
|
||||
{
|
||||
JL_rcsp_event_to_user(DEVICE_EVENT_FROM_RCSP, MSG_JL_FIND_DEVICE_STOP, &args, sizeof(args));
|
||||
}
|
||||
|
||||
TWS_SYNC_CALL_REGISTER(adv_find_dev_stop_sync) = {
|
||||
.uuid = TWS_FUNC_ID_ADV_FIND_DEV_STOP_TIMER_SYNC,
|
||||
.func = adv_find_dev_stop_sync_timer_func_t,
|
||||
};
|
||||
|
||||
void find_devic_stop_timer(u8 *param, u32 msec)
|
||||
{
|
||||
int priv = 0;
|
||||
if (TWS_ROLE_MASTER == tws_api_get_role()) {
|
||||
memcpy(&priv, param, 3);
|
||||
tws_api_sync_call_by_uuid(TWS_FUNC_ID_ADV_FIND_DEV_STOP_TIMER_SYNC, priv, msec);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
@ -0,0 +1,13 @@
|
||||
#ifndef __RCSP_ADV_TWS_SYNC_H__
|
||||
#define __RCSP_ADV_TWS_SYNC_H__
|
||||
|
||||
#include "classic/tws_api.h"
|
||||
|
||||
#define TWS_FUNC_ID_ADV_SETTING_SYNC \
|
||||
TWS_FUNC_ID('R', 'C', 'S', 'P')
|
||||
#define TWS_FUNC_ID_TIME_STAMP_SYNC \
|
||||
TWS_FUNC_ID('R' + 'C' + 'S' + 'P', \
|
||||
'A' + 'D' + 'V', \
|
||||
'T' + 'I' + 'M' + 'E', \
|
||||
'S' + 'T' + 'A' + 'M' + 'P')
|
||||
#endif
|
||||
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,197 @@
|
||||
// binary representation
|
||||
// attribute size in bytes (16), flags(16), handle (16), uuid (16/128), value(...)
|
||||
|
||||
#ifndef _LE_SERVER_MODULE_H
|
||||
#define _LE_SERVER_MODULE_H
|
||||
|
||||
#include <stdint.h>
|
||||
#include "bt_common.h"
|
||||
#include "audio_anc.h"
|
||||
#if (TCFG_BLE_DEMO_SELECT == DEF_BLE_DEMO_ADV_RCSP)
|
||||
//
|
||||
// gatt profile include file, generated by jieli gatt_inc_generator.exe
|
||||
//
|
||||
static const uint8_t profile_data[] = {
|
||||
//////////////////////////////////////////////////////
|
||||
//
|
||||
// 0x0001 PRIMARY_SERVICE 1800
|
||||
//
|
||||
//////////////////////////////////////////////////////
|
||||
0x0a, 0x00, 0x02, 0x00, 0x01, 0x00, 0x00, 0x28, 0x00, 0x18,
|
||||
|
||||
/* CHARACTERISTIC, 2a00, READ | WRITE | DYNAMIC, */
|
||||
// 0x0002 CHARACTERISTIC 2a00 READ | WRITE | DYNAMIC
|
||||
0x0d, 0x00, 0x02, 0x00, 0x02, 0x00, 0x03, 0x28, 0x0a, 0x03, 0x00, 0x00, 0x2a,
|
||||
// 0x0003 VALUE 2a00 READ | WRITE | DYNAMIC
|
||||
0x08, 0x00, 0x0a, 0x01, 0x03, 0x00, 0x00, 0x2a,
|
||||
|
||||
//////////////////////////////////////////////////////
|
||||
//
|
||||
// 0x0004 PRIMARY_SERVICE ae00
|
||||
//
|
||||
//////////////////////////////////////////////////////
|
||||
0x0a, 0x00, 0x02, 0x00, 0x80, 0x00, 0x00, 0x28, 0x00, 0xae,
|
||||
|
||||
/* CHARACTERISTIC, ae01, WRITE_WITHOUT_RESPONSE | DYNAMIC, */
|
||||
// 0x0040 CHARACTERISTIC ae01 WRITE_WITHOUT_RESPONSE | DYNAMIC
|
||||
0x0d, 0x00, 0x02, 0x00, 0x81, 0x00, 0x03, 0x28, 0x04, 0x82, 0x00, 0x01, 0xae,
|
||||
// 0x0041 VALUE ae01 WRITE_WITHOUT_RESPONSE | DYNAMIC
|
||||
0x08, 0x00, 0x04, 0x01, 0x82, 0x00, 0x01, 0xae,
|
||||
|
||||
/* CHARACTERISTIC, ae02, NOTIFY, */
|
||||
// 0x0042 CHARACTERISTIC ae02 NOTIFY
|
||||
0x0d, 0x00, 0x02, 0x00, 0x83, 0x00, 0x03, 0x28, 0x10, 0x84, 0x00, 0x02, 0xae,
|
||||
// 0x0043 VALUE ae02 NOTIFY
|
||||
0x08, 0x00, 0x10, 0x00, 0x84, 0x00, 0x02, 0xae,
|
||||
// 0x0044 CLIENT_CHARACTERISTIC_CONFIGURATION
|
||||
0x0a, 0x00, 0x0a, 0x01, 0x85, 0x00, 0x02, 0x29, 0x00, 0x00,
|
||||
//////////////////////////////////////////////////////
|
||||
//
|
||||
// 0x0014 PRIMARY_SERVICE 1812
|
||||
//
|
||||
//////////////////////////////////////////////////////
|
||||
// 0x0a, 0x00, 0x02, 0x00, 0x14, 0x00, 0x00, 0x28, 0x12, 0x18,
|
||||
|
||||
#if 0// authentication
|
||||
//
|
||||
10, 0x00, 0x00, 0x00, 0x1A, 0x00, 0x00, 0x28, 0x0A, 0x18, //primary service declaration
|
||||
13, 0x00, 0x02, 0x00, 0x1B, 0x00, 0x03, 0x28, 0x02, 0x1C, 0x00, 0x50, 0x2A, //characteristic declaration
|
||||
15, 0x00, 0x02, 0x04, 0x1C, 0x00, 0x50, 0x2A, 0x02, 0x8A, 0x24, 0x66, 0x82, 0x34, 0x36, //PnP ID
|
||||
#endif
|
||||
|
||||
// END
|
||||
0x00, 0x00,
|
||||
};
|
||||
//
|
||||
// characteristics <--> handles
|
||||
//
|
||||
#define ATT_CHARACTERISTIC_2a00_01_VALUE_HANDLE 0x0003
|
||||
#define ATT_CHARACTERISTIC_ae01_01_VALUE_HANDLE 0x0082
|
||||
#define ATT_CHARACTERISTIC_ae02_01_VALUE_HANDLE 0x0084
|
||||
#define ATT_CHARACTERISTIC_ae02_01_CLIENT_CONFIGURATION_HANDLE 0x0085
|
||||
|
||||
// #define ATT_CHARACTERISTIC_ae01_01_VALUE_HANDLE 0x0006
|
||||
// #define ATT_CHARACTERISTIC_ae02_01_VALUE_HANDLE 0x0008
|
||||
// #define ATT_CHARACTERISTIC_ae02_01_CLIENT_CONFIGURATION_HANDLE 0x0009
|
||||
// #define ATT_CHARACTERISTIC_ae03_01_VALUE_HANDLE 0x000b
|
||||
// #define ATT_CHARACTERISTIC_ae04_01_VALUE_HANDLE 0x000d
|
||||
// #define ATT_CHARACTERISTIC_ae04_01_CLIENT_CONFIGURATION_HANDLE 0x000e
|
||||
// #define ATT_CHARACTERISTIC_ae05_01_VALUE_HANDLE 0x0010
|
||||
// #define ATT_CHARACTERISTIC_ae05_01_CLIENT_CONFIGURATION_HANDLE 0x0011
|
||||
// #define ATT_CHARACTERISTIC_ae10_01_VALUE_HANDLE 0x0013
|
||||
|
||||
|
||||
|
||||
|
||||
#define JL_OPCODE_SET_ADV 0xC0
|
||||
#define JL_OPCODE_GET_ADV 0xC1
|
||||
#define JL_OPCODE_ADV_DEVICE_NOTIFY 0xC2
|
||||
#define JL_OPCODE_ADV_NOTIFY_SETTING 0xC3
|
||||
#define JL_OPCODE_ADV_DEVICE_REQUEST 0xC4
|
||||
|
||||
#define ATTR_TYPE_BAT_VALUE (0)
|
||||
#define ATTR_TYPE_EDR_NAME (1)
|
||||
#define ATTR_TYPE_KEY_SETTING (2)
|
||||
#define ATTR_TYPE_LED_SETTING (3)
|
||||
#define ATTR_TYPE_MIC_SETTING (4)
|
||||
#define ATTR_TYPE_WORK_MODE (5)
|
||||
#define ATTR_TYPE_PRODUCT_MESSAGE (6)
|
||||
#define ATTR_TYPE_TIME_STAMP (7)
|
||||
#define ATTR_TYPE_EQ_SETTING (8)
|
||||
#define ATTR_TYPE_HIGH_LOW_VOL (9)
|
||||
#define ATTR_TYPE_ANC_VOICE_KEY (10)
|
||||
#define ATTR_TYPE_ANC_VOICE (11)
|
||||
#define ATTR_TYPE_ASSISTED_HEARING (12)
|
||||
|
||||
//rcsp功能模块使能
|
||||
#define RCSP_ADV_NAME_SET_ENABLE 1
|
||||
#define RCSP_ADV_KEY_SET_ENABLE 1
|
||||
#define RCSP_ADV_LED_SET_ENABLE 1
|
||||
#define RCSP_ADV_MIC_SET_ENABLE 1
|
||||
#define RCSP_ADV_WORK_SET_ENABLE 1
|
||||
|
||||
#if (JL_EARPHONE_APP_EN)
|
||||
#define RCSP_ADV_EQ_SET_ENABLE 1
|
||||
#define RCSP_ADV_MUSIC_INFO_ENABLE 1
|
||||
#define RCSP_ADV_HIGH_LOW_SET 1
|
||||
#define RCSP_ADV_FIND_DEVICE_ENABLE 1
|
||||
#define RCSP_ADV_AI_NO_PICK 0 // 智能免摘
|
||||
#define RCSP_ADV_ASSISTED_HEARING 0 // 辅听,注意开启辅听后,需要关闭ANC相关功能
|
||||
|
||||
#if !RCSP_ADV_ASSISTED_HEARING
|
||||
#define RCSP_ADV_ANC_VOICE 0 // 主动降噪
|
||||
|
||||
#if RCSP_ADV_ANC_VOICE
|
||||
#define RCSP_ADV_ADAPTIVE_NOISE_REDUCTION 1 // 自适应降噪
|
||||
#define RCSP_ADV_SCENE_NOISE_REDUCTION 1 // 场景降噪
|
||||
#define RCSP_ADV_WIND_NOISE_DETECTION 1 // 风噪检测
|
||||
#define RCSP_ADV_VOICE_ENHANCEMENT_MODE 1 // 人声增强模式
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
#else
|
||||
#define RCSP_ADV_EQ_SET_ENABLE 0
|
||||
#define RCSP_ADV_MUSIC_INFO_ENABLE 0
|
||||
#define RCSP_ADV_HIGH_LOW_SET 0
|
||||
#define RCSP_ADV_FIND_DEVICE_ENABLE 0
|
||||
#define RCSP_ADV_ASSISTED_HEARING 0 // 辅听,注意开启辅听后,需要关闭ANC相关功能
|
||||
#define RCSP_ADV_ANC_VOICE 0 // 主动降噪
|
||||
#define RCSP_ADV_ADAPTIVE_NOISE_REDUCTION 0 // 自适应降噪
|
||||
#define RCSP_ADV_AI_NO_PICK 0 // 智能免摘
|
||||
#define RCSP_ADV_SCENE_NOISE_REDUCTION 0 // 场景降噪
|
||||
#define RCSP_ADV_WIND_NOISE_DETECTION 0 // 风噪检测
|
||||
#define RCSP_ADV_VOICE_ENHANCEMENT_MODE 0 // 人声增强模式
|
||||
#endif
|
||||
#define RCSP_ADV_PRODUCT_MSG_ENABLE 1
|
||||
|
||||
#if !TCFG_EQ_ENABLE
|
||||
#undef RCSP_ADV_EQ_SET_ENABLE
|
||||
#define RCSP_ADV_EQ_SET_ENABLE 0
|
||||
#endif
|
||||
#if !ANC_EAR_ADAPTIVE_EN && JL_EARPHONE_APP_EN
|
||||
#undef RCSP_ADV_ADAPTIVE_NOISE_REDUCTION
|
||||
#define RCSP_ADV_ADAPTIVE_NOISE_REDUCTION 0 //自适应降噪
|
||||
#endif
|
||||
|
||||
enum {
|
||||
BT_ADV_ENABLE,
|
||||
BT_ADV_DISABLE,
|
||||
BT_ADV_SET_EDR_CON_FLAG,
|
||||
BT_ADV_SET_BAT_CHARGE_L,
|
||||
BT_ADV_SET_BAT_CHARGE_R,
|
||||
BT_ADV_SET_BAT_CHARGE_C,
|
||||
BT_ADV_SET_BAT_PERCENT_L,
|
||||
BT_ADV_SET_BAT_PERCENT_R,
|
||||
BT_ADV_SET_BAT_PERCENT_C,
|
||||
BT_ADV_SET_NOTIFY_EN,
|
||||
};
|
||||
|
||||
// BT_ADV_SET_EDR_CON_FLAG
|
||||
#define SECNE_DISMISS (0x00)
|
||||
#define SECNE_UNCONNECTED (0x01)
|
||||
#define SECNE_CONNECTED (0x02)
|
||||
#define SECNE_CONNECTING (0x03)
|
||||
#define SECNE_CONNECTINLESS (0x04)
|
||||
|
||||
#define TWS_FUNC_ID_SEQ_RAND_SYNC (('S' << (3 * 8)) | ('E' << (2 * 8)) | ('Q' << (1 * 8)) | ('\0'))
|
||||
|
||||
enum {
|
||||
TWS_ADV_SEQ_CHANGE = 0,
|
||||
TWS_VERSON_INFO,
|
||||
TWS_UPDATE_INFO,
|
||||
};
|
||||
|
||||
extern int bt_ble_adv_ioctl(u32 cmd, u32 priv, u8 mode);
|
||||
extern void bt_adv_seq_change(void);
|
||||
void ble_app_disconnect(void);
|
||||
void bt_ble_rcsp_adv_enable(void);
|
||||
void bt_ble_rcsp_adv_disable(void);
|
||||
u8 get_ble_adv_notify(void);
|
||||
void set_ble_adv_notify(u8 en);
|
||||
u8 get_connect_flag(void);
|
||||
void set_connect_flag(u8 value);
|
||||
void ble_module_enable(u8 en);
|
||||
|
||||
#endif
|
||||
#endif
|
||||
@ -0,0 +1,91 @@
|
||||
|
||||
#include "app_config.h"
|
||||
#include "app_action.h"
|
||||
|
||||
#include "system/includes.h"
|
||||
#include "spp_user.h"
|
||||
#include "string.h"
|
||||
#include "circular_buf.h"
|
||||
#include "3th_profile_api.h"
|
||||
#include "bt_common.h"
|
||||
|
||||
|
||||
#if 1
|
||||
extern void printf_buf(u8 *buf, u32 len);
|
||||
#define log_info printf
|
||||
#define log_info_hexdump printf_buf
|
||||
#else
|
||||
#define log_info(...)
|
||||
#define log_info_hexdump(...)
|
||||
#endif
|
||||
|
||||
/* #define DEBUG_ENABLE */
|
||||
/* #include "debug_log.h" */
|
||||
|
||||
/* #include "rcsp_spp_user.h" */
|
||||
#if (RCSP_ADV_EN)
|
||||
|
||||
static struct spp_operation_t *spp_api = NULL;
|
||||
static u8 spp_state;
|
||||
|
||||
int rcsp_spp_send_data(u8 *data, u16 len)
|
||||
{
|
||||
if (spp_api) {
|
||||
return spp_api->send_data(NULL, data, len);
|
||||
}
|
||||
return SPP_USER_ERR_SEND_FAIL;
|
||||
}
|
||||
|
||||
int rcsp_spp_send_data_check(u16 len)
|
||||
{
|
||||
if (spp_api) {
|
||||
if (spp_api->busy_state()) {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
static void rcsp_spp_state_cbk(u8 state)
|
||||
{
|
||||
spp_state = state;
|
||||
switch (state) {
|
||||
case SPP_USER_ST_CONNECT:
|
||||
log_info("SPP_USER_ST_CONNECT ~~~\n");
|
||||
set_app_connect_type(TYPE_SPP);
|
||||
break;
|
||||
|
||||
case SPP_USER_ST_DISCONN:
|
||||
log_info("SPP_USER_ST_DISCONN ~~~\n");
|
||||
set_app_connect_type(TYPE_NULL);
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
static void rcsp_spp_send_wakeup(void)
|
||||
{
|
||||
putchar('W');
|
||||
}
|
||||
|
||||
static void rcsp_spp_recieve_cbk(void *priv, u8 *buf, u16 len)
|
||||
{
|
||||
log_info("spp_api_rx ~~~\n");
|
||||
log_info_hexdump(buf, len);
|
||||
}
|
||||
|
||||
void rcsp_spp_init(void)
|
||||
{
|
||||
spp_state = 0;
|
||||
spp_get_operation_table(&spp_api);
|
||||
spp_api->regist_recieve_cbk(0, rcsp_spp_recieve_cbk);
|
||||
spp_api->regist_state_cbk(0, rcsp_spp_state_cbk);
|
||||
spp_api->regist_wakeup_send(NULL, rcsp_spp_send_wakeup);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
42
apps/common/third_party_profile/jieli/JL_rcsp/btcrypt.h
Normal file
42
apps/common/third_party_profile/jieli/JL_rcsp/btcrypt.h
Normal file
@ -0,0 +1,42 @@
|
||||
#ifndef TOMCRYPT_H_
|
||||
#define TOMCRYPT_H_
|
||||
// #include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
|
||||
#define HARDWARE_METHOD 0
|
||||
|
||||
#ifndef WIN32
|
||||
// #include "hw_cpu.h"
|
||||
#undef HARDWARE_METHOD
|
||||
#define HARDWARE_METHOD 1
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*
|
||||
@param [in] pt[*1] The plaintext
|
||||
@param ptlen The length of the plaintext(octets) range: 1~32
|
||||
@param [in] key[*1] The key for encrypt
|
||||
@param keylen[*1] The length of the key(octets) range: 1~32
|
||||
@param [out] mac[*1] output : The Message Authentication Code 16 bytes.
|
||||
*/
|
||||
extern void btcon_hash(unsigned char *pt, int ptlen, unsigned char *key, int keylen, unsigned char *mac);
|
||||
|
||||
#if HARDWARE_METHOD
|
||||
extern int yf_aes_start_enc(unsigned char key[16], unsigned char plaintext[16], unsigned char encrypt[16]);
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* TOMCRYPT_H_ */
|
||||
|
||||
|
||||
/* $Source$ */
|
||||
/* $Revision$ */
|
||||
/* $Date$ */
|
||||
100
apps/common/third_party_profile/jieli/JL_rcsp/rcsp_bluetooth.h
Normal file
100
apps/common/third_party_profile/jieli/JL_rcsp/rcsp_bluetooth.h
Normal file
@ -0,0 +1,100 @@
|
||||
#ifndef __JL_BLUETOOTH_H__
|
||||
#define __JL_BLUETOOTH_H__
|
||||
|
||||
#include "typedef.h"
|
||||
#include "le_common.h"
|
||||
#include "spp_user.h"
|
||||
#include "system/event.h"
|
||||
#include "rcsp_msg.h"
|
||||
#include "ble_user.h"
|
||||
#if RCSP_BTMATE_EN
|
||||
void rcsp_init();
|
||||
void rcsp_dev_select(u8 type);
|
||||
void function_change_inform(void);
|
||||
|
||||
bool common_msg_deal(u32 param, void *priv);
|
||||
bool ble_msg_deal(u32 param);
|
||||
bool music_msg_deal(u32 param, void *priv);
|
||||
bool linein_msg_deal(u32 param);
|
||||
bool rtc_msg_deal(u32 param);
|
||||
|
||||
void rcsp_exit(void);
|
||||
u8 rcsp_get_asr_status(void);
|
||||
u8 get_rcsp_support_new_reconn_flag(void);
|
||||
|
||||
// enum {
|
||||
// RCSP_BLE,
|
||||
// RCSP_SPP,
|
||||
// };
|
||||
|
||||
|
||||
enum {
|
||||
ANDROID,
|
||||
APPLE_IOS,
|
||||
};
|
||||
|
||||
struct JL_AI_VAR {
|
||||
ble_state_e JL_ble_status;
|
||||
struct ble_server_operation_t *rcsp_ble;
|
||||
u8 JL_spp_status;
|
||||
struct spp_operation_t *rcsp_spp;
|
||||
volatile u8 speech_state;
|
||||
u32 feature_mask;
|
||||
u8 device_type;
|
||||
u8 phone_platform;
|
||||
void (*start_speech)(void);
|
||||
void (*stop_speech)(void);
|
||||
u8 err_report;
|
||||
volatile u8 file_browse_lock_flag;
|
||||
u32 return_msg;
|
||||
u8 spec_mode;
|
||||
struct __rcsp_user_var *rcsp_user;
|
||||
volatile u8 rcsp_run_flag;
|
||||
u8 ffr_mode;
|
||||
u16 ffr_time;
|
||||
u16 rcsp_timer_hdl;
|
||||
volatile u8 wait_asr_end;
|
||||
u8 new_reconn_flag; //是否支持新的回连方式(进行地址修改)
|
||||
};
|
||||
|
||||
struct _SPEECH_OVER_DEAL {
|
||||
u8 last_task;
|
||||
u8 status;
|
||||
};
|
||||
|
||||
extern struct JL_AI_VAR jl_ai_var;
|
||||
extern struct _SPEECH_OVER_DEAL speech_deal_val;
|
||||
|
||||
enum RCSP_MSG_T {
|
||||
MSG_JL_GET_DEV_UPDATE_FILE_INFO_OFFSET = RCSP_MSG_END,
|
||||
MSG_JL_INQUIRE_DEVEICE_IF_CAN_UPDATE,
|
||||
MSG_JL_LOADER_DOWNLOAD_START,
|
||||
MSG_JL_UPDATE_START,
|
||||
MSG_JL_ENTER_UPDATE_MODE,
|
||||
MSG_JL_DEV_DISCONNECT,
|
||||
MSG_JL_BLE_UPDATE_START,
|
||||
MSG_JL_SPP_UPDATE_START,
|
||||
};
|
||||
|
||||
bool rcsp_msg_post(RCSP_MSG msg, int argc, ...);
|
||||
|
||||
#define SDK_TYPE_AC690X 0x0
|
||||
#define SDK_TYPE_AC692X 0x1
|
||||
#define SDK_TYPE_AC693X 0x2
|
||||
#define SDK_TYPE_AC695X 0x3
|
||||
#define SDK_TYPE_AC697X 0x4
|
||||
|
||||
#if (defined CONFIG_CPU_BR21)
|
||||
#define RCSP_SDK_TYPE SDK_TYPE_AC692X
|
||||
#elif (defined CONFIG_CPU_BR22)
|
||||
#define RCSP_SDK_TYPE SDK_TYPE_AC693X
|
||||
#elif (defined CONFIG_CPU_BR23)
|
||||
#define RCSP_SDK_TYPE SDK_TYPE_AC695X
|
||||
#elif (defined CONFIG_CPU_BR30)
|
||||
#define RCSP_SDK_TYPE SDK_TYPE_AC697X
|
||||
#else
|
||||
#define RCSP_SDK_TYPE SDK_TYPE_AC693X
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#endif
|
||||
13
apps/common/third_party_profile/jieli/JL_rcsp/rcsp_msg.h
Normal file
13
apps/common/third_party_profile/jieli/JL_rcsp/rcsp_msg.h
Normal file
@ -0,0 +1,13 @@
|
||||
#ifndef __RCSP_MSG_H__
|
||||
#define __RCSP_MSG_H__
|
||||
|
||||
typedef enum __RCSP_MSG {
|
||||
RCSP_MSG_UPDATE_EQ = 0,
|
||||
RCSP_MSG_SET_FMTX_POINT,
|
||||
RCSP_MSG_BS_END,
|
||||
RCSP_MSG_BT_SCAN,
|
||||
RCSP_MSG_END,
|
||||
} RCSP_MSG;
|
||||
|
||||
#endif//__RCSP_MSG_H__
|
||||
|
||||
@ -0,0 +1,575 @@
|
||||
#include "app_config.h"
|
||||
#include "rcsp_adv_user_update.h"
|
||||
#if RCSP_UPDATE_EN
|
||||
#include "uart.h"
|
||||
#include "system/timer.h"
|
||||
#include "update.h"
|
||||
#include "custom_cfg.h"
|
||||
#include "btstack/avctp_user.h"
|
||||
#include "JL_rcsp_packet.h"
|
||||
#include "JL_rcsp_protocol.h"
|
||||
#include "rcsp_adv_bluetooth.h"
|
||||
#include "le_rcsp_adv_module.h"
|
||||
#include "update_loader_download.h"
|
||||
#include "classic/tws_api.h"
|
||||
#include "syscfg_id.h"
|
||||
|
||||
#if (RCSP_ADV_EN)
|
||||
|
||||
#define RCSP_DEBUG_EN
|
||||
|
||||
#ifdef RCSP_DEBUG_EN
|
||||
#define rcsp_putchar(x) putchar(x)
|
||||
#define rcsp_printf printf
|
||||
#define rcsp_printf_buf(x,len) printf_buf(x,len)
|
||||
#else
|
||||
#define rcsp_putchar(...)
|
||||
#define rcsp_printf(...)
|
||||
#define rcsp_printf_buf(...)
|
||||
#endif
|
||||
|
||||
#define DEV_UPDATE_FILE_INFO_OFFEST 0x00//0x40
|
||||
#define DEV_UPDATE_FILE_INFO_LEN 0x00//(0x10 + VER_INFO_EXT_COUNT * (VER_INFO_EXT_MAX_LEN + 1))
|
||||
|
||||
typedef enum {
|
||||
UPDATA_START = 0x00,
|
||||
UPDATA_REV_DATA,
|
||||
UPDATA_STOP,
|
||||
} UPDATA_BIT_FLAG;
|
||||
|
||||
#if 0
|
||||
static update_file_id_t update_file_id_info = {
|
||||
.ver[0] = 0xff,
|
||||
.ver[1] = 0xff,
|
||||
};
|
||||
#else
|
||||
static update_file_ext_id_t update_file_id_info = {
|
||||
.update_file_id_info.ver[0] = 0xff,
|
||||
.update_file_id_info.ver[1] = 0xff,
|
||||
};
|
||||
#endif
|
||||
|
||||
extern const int support_dual_bank_update_en;
|
||||
extern void JL_ble_disconnect(void);
|
||||
extern u8 check_le_pakcet_sent_finish_flag(void);
|
||||
|
||||
static u8 update_flag = 0;
|
||||
static u8 tws_need_update = 0; //标志耳机是否需要强制升级
|
||||
static u8 tws_need_role_switch = 0; //用于tws连接之后版本号不匹配进行role_switch,低版本号的作为主机进行强制升级
|
||||
static u8 disconnect_flag = 0;
|
||||
u8 get_jl_update_flag(void)
|
||||
{
|
||||
printf("get_update_flag:%x\n", update_flag);
|
||||
return update_flag;
|
||||
}
|
||||
|
||||
void set_jl_update_flag(u8 flag)
|
||||
{
|
||||
update_flag = flag;
|
||||
printf("update_flag:%x\n", update_flag);
|
||||
}
|
||||
|
||||
typedef struct _update_mode_t {
|
||||
u8 opcode;
|
||||
u8 opcode_sn;
|
||||
|
||||
} update_mode_t;
|
||||
|
||||
static update_mode_t update_record_info;
|
||||
|
||||
void JL_controller_save_curr_cmd_para(u8 OpCode, u8 OpCode_SN)
|
||||
{
|
||||
update_record_info.opcode = OpCode;
|
||||
update_record_info.opcode_sn = OpCode_SN;
|
||||
}
|
||||
|
||||
void JL_controller_get_curr_cmd_para(u8 *OpCode, u8 *OpCode_SN)
|
||||
{
|
||||
*OpCode = update_record_info.opcode;
|
||||
*OpCode_SN = update_record_info.opcode_sn;
|
||||
}
|
||||
|
||||
static void (*fw_update_block_handle)(u8 state, u8 *buf, u16 len) = NULL;
|
||||
void register_receive_fw_update_block_handle(void (*handle)(u8 state, u8 *buf, u16 len))
|
||||
{
|
||||
fw_update_block_handle = handle;
|
||||
}
|
||||
|
||||
static u16 ble_discon_timeout;
|
||||
static void ble_discon_timeout_handle(void *priv)
|
||||
{
|
||||
JL_rcsp_event_to_user(DEVICE_EVENT_FROM_RCSP, MSG_JL_UPDATE_START, NULL, 0);
|
||||
}
|
||||
|
||||
void JL_rcsp_update_cmd_resp(void *priv, u8 OpCode, u8 OpCode_SN, u8 *data, u16 len)
|
||||
{
|
||||
u8 msg[4];
|
||||
rcsp_printf("%s\n", __FUNCTION__);
|
||||
switch (OpCode) {
|
||||
case JL_OPCODE_GET_DEVICE_UPDATE_FILE_INFO_OFFSET:
|
||||
if (0 == len) {
|
||||
msg[0] = OpCode;
|
||||
msg[1] = OpCode_SN;
|
||||
rcsp_printf("JL_OPCODE_GET_DEVICE_UPDATE_FILE_INFO_OFFSET\n");
|
||||
JL_rcsp_event_to_user(DEVICE_EVENT_FROM_RCSP,
|
||||
MSG_JL_GET_DEV_UPDATE_FILE_INFO_OFFSET,
|
||||
msg,
|
||||
2);
|
||||
} else {
|
||||
rcsp_printf("JL_OPCODE_GET_DEVICE_UPDATE_FILE_INFO_OFFSET ERR\n");
|
||||
}
|
||||
break;
|
||||
case JL_OPCODE_INQUIRE_DEVICE_IF_CAN_UPDATE:
|
||||
rcsp_printf("JL_OPCODE_INQUIRE_DEVICE_IF_CAN_UPDATE:%x %x\n", len, data[0]);
|
||||
if (len) {
|
||||
extern void set_curr_update_type(u8 type);
|
||||
set_curr_update_type(data[0]);
|
||||
msg[0] = OpCode;
|
||||
msg[1] = OpCode_SN;
|
||||
msg[2] = 0x00;
|
||||
JL_rcsp_event_to_user(DEVICE_EVENT_FROM_RCSP,
|
||||
MSG_JL_INQUIRE_DEVEICE_IF_CAN_UPDATE,
|
||||
msg,
|
||||
3);
|
||||
}
|
||||
break;
|
||||
case JL_OPCODE_EXIT_UPDATE_MODE:
|
||||
rcsp_printf("JL_OPCODE_EXIT_UPDATE_MODE\n");
|
||||
break;
|
||||
case JL_OPCODE_ENTER_UPDATE_MODE:
|
||||
rcsp_printf("JL_OPCODE_ENTER_UPDATE_MODE\n");
|
||||
msg[0] = OpCode;
|
||||
msg[1] = OpCode_SN;
|
||||
JL_rcsp_event_to_user(DEVICE_EVENT_FROM_RCSP,
|
||||
MSG_JL_ENTER_UPDATE_MODE,
|
||||
msg,
|
||||
2);
|
||||
break;
|
||||
case JL_OPCODE_SEND_FW_UPDATE_BLOCK:
|
||||
rcsp_printf("JL_OPCODE_SEND_FW_UPDATE_BLOCK\n");
|
||||
break;
|
||||
case JL_OPCODE_GET_DEVICE_REFRESH_FW_STATUS:
|
||||
rcsp_printf("JL_OPCODE_GET_DEVICE_REFRESH_FW_STATUS\n");
|
||||
JL_controller_save_curr_cmd_para(OpCode, OpCode_SN);
|
||||
if (fw_update_block_handle) {
|
||||
fw_update_block_handle(UPDATA_STOP, NULL, 0);
|
||||
}
|
||||
break;
|
||||
/* case JL_OPCODE_SET_DEVICE_REBOOT: */
|
||||
/* rcsp_printf("JL_OPCODE_SET_DEVICE_REBOOT\n"); */
|
||||
/* if (support_dual_bank_update_en) { */
|
||||
/* cpu_reset(); */
|
||||
/* } */
|
||||
/* break; */
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void JL_rcsp_resp_dev_update_file_info_offest(u8 OpCode, u8 OpCode_SN)
|
||||
{
|
||||
u8 data[4 + 2];
|
||||
u16 update_file_info_offset = DEV_UPDATE_FILE_INFO_OFFEST;
|
||||
u16 update_file_info_len = DEV_UPDATE_FILE_INFO_LEN;
|
||||
WRITE_BIG_U32(data + 0, update_file_info_offset);
|
||||
WRITE_BIG_U16(data + 4, update_file_info_len);
|
||||
JL_CMD_response_send(OpCode, JL_PRO_STATUS_SUCCESS, OpCode_SN, data, sizeof(data));
|
||||
}
|
||||
|
||||
static void JL_resp_inquire_device_if_can_update(u8 OpCode, u8 OpCode_SN, u8 update_sta)
|
||||
{
|
||||
u8 data[1];
|
||||
data[0] = update_sta;
|
||||
JL_CMD_response_send(OpCode, JL_PRO_STATUS_SUCCESS, OpCode_SN, data, sizeof(data));
|
||||
}
|
||||
|
||||
enum {
|
||||
UPDATE_FLAG_OK,
|
||||
UPDATE_FLAG_LOW_POWER,
|
||||
UPDATE_FLAG_FW_INFO_ERR,
|
||||
UPDATE_FLAG_FW_INFO_CONSISTENT,
|
||||
UPDATE_FLAG_TWS_DISCONNECT,
|
||||
};
|
||||
|
||||
static u8 judge_remote_version_can_update(void)
|
||||
{
|
||||
//extern u16 ex_cfg_get_local_version_info(void);
|
||||
u16 remote_file_ver = READ_BIG_U16(update_file_id_info.update_file_id_info.ver);
|
||||
//u16 local_ver = ex_cfg_get_local_version_info();
|
||||
u16 local_ver = get_vid_pid_ver_from_cfg_file(GET_VID_FROM_EX_CFG);
|
||||
|
||||
#if (0 == VER_INFO_EXT_COUNT)
|
||||
//extern u16 ex_cfg_get_local_pid_info(void);
|
||||
//extern u16 ex_cfg_get_local_vid_info(void);
|
||||
|
||||
//u16 local_pid = ex_cfg_get_local_pid_info();
|
||||
//u16 local_vid = ex_cfg_get_local_vid_info();
|
||||
u16 local_pid = get_vid_pid_ver_from_cfg_file(GET_PID_FROM_EX_CFG);
|
||||
u16 local_vid = get_vid_pid_ver_from_cfg_file(GET_VID_FROM_EX_CFG);
|
||||
|
||||
u16 remote_file_pid = READ_BIG_U16(update_file_id_info.update_file_id_info.pid);
|
||||
u16 remote_file_vid = READ_BIG_U16(update_file_id_info.update_file_id_info.vid);
|
||||
|
||||
if (remote_file_ver > local_ver || remote_file_pid != local_pid || remote_file_vid != local_vid) {
|
||||
return UPDATE_FLAG_FW_INFO_ERR;
|
||||
}
|
||||
#else
|
||||
//extern u32 ex_cfg_get_local_authkey_info(u8 * authkey_data[], u8 * authkey_len);
|
||||
//extern u32 ex_cfg_get_local_procode_info(u8 * procode_data[], u8 * procode_len);
|
||||
|
||||
u8 authkey_len = 0;
|
||||
u8 *local_authkey_data = NULL;
|
||||
get_authkey_procode_from_cfg_file(&local_authkey_data, &authkey_len, GET_AUTH_KEY_FROM_EX_CFG);
|
||||
|
||||
u8 procode_len = 0;
|
||||
u8 *local_procode_data = NULL;
|
||||
get_authkey_procode_from_cfg_file(&local_procode_data, &procode_len, GET_PRO_CODE_FROM_EX_CFG);
|
||||
|
||||
//ex_cfg_get_local_authkey_info(&local_authkey_data, &authkey_len);
|
||||
//ex_cfg_get_local_procode_info(&local_procode_data, &procode_len);
|
||||
|
||||
u8 *remote_authkey_data = update_file_id_info.ext;
|
||||
u8 *remote_procode_data = update_file_id_info.ext + authkey_len + 1;
|
||||
|
||||
if (remote_file_ver < local_ver
|
||||
|| 0 != memcmp(remote_authkey_data, local_authkey_data, authkey_len)
|
||||
|| 0 != memcmp(remote_procode_data, local_procode_data, procode_len)) {
|
||||
return UPDATE_FLAG_FW_INFO_ERR;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (remote_file_ver == local_ver) {
|
||||
rcsp_printf("remote_file_ver is %x, local_ver is %x, remote_file_ver is similar to local_ver\n", remote_file_ver, local_ver);
|
||||
return UPDATE_FLAG_FW_INFO_CONSISTENT;
|
||||
}
|
||||
|
||||
return UPDATE_FLAG_OK;
|
||||
}
|
||||
|
||||
static bool check_edr_is_disconnct(void)
|
||||
{
|
||||
if (get_curr_channel_state()) {
|
||||
return TRUE;
|
||||
} else {
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
static bool check_ble_all_packet_sent(void)
|
||||
{
|
||||
if (check_le_pakcet_sent_finish_flag()) {
|
||||
return TRUE;
|
||||
} else {
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static u32 rcsp_update_data_read(void *priv, u32 offset_addr, u16 len)
|
||||
{
|
||||
u32 err;
|
||||
u8 data[4 + 2];
|
||||
WRITE_BIG_U32(data, offset_addr);
|
||||
WRITE_BIG_U16(data + 4, len);
|
||||
err = JL_CMD_send(JL_OPCODE_SEND_FW_UPDATE_BLOCK, data, sizeof(data), JL_NEED_RESPOND);
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
static JL_ERR JL_controller_resp_get_dev_refresh_fw_status(u8 OpCode, u8 OpCode_SN, u8 result)
|
||||
{
|
||||
JL_ERR send_err = JL_ERR_NONE;
|
||||
u8 data[1];
|
||||
|
||||
data[0] = result; //0:sucess 1:fail;
|
||||
|
||||
send_err = JL_CMD_response_send(OpCode, JL_PRO_STATUS_SUCCESS, OpCode_SN, data, sizeof(data));
|
||||
|
||||
return send_err;
|
||||
}
|
||||
|
||||
u32 rcsp_update_status_response(void *priv, u8 status)
|
||||
{
|
||||
u8 OpCode;
|
||||
u8 OpCode_SN;
|
||||
|
||||
JL_ERR send_err = JL_ERR_NONE;
|
||||
|
||||
JL_controller_get_curr_cmd_para(&OpCode, &OpCode_SN);
|
||||
|
||||
//log_info("get cmd para:%x %x\n", OpCode, OpCode_SN);
|
||||
|
||||
if (JL_OPCODE_GET_DEVICE_REFRESH_FW_STATUS == OpCode) {
|
||||
send_err = JL_controller_resp_get_dev_refresh_fw_status(OpCode, OpCode_SN, status);
|
||||
}
|
||||
|
||||
return send_err;
|
||||
}
|
||||
|
||||
|
||||
|
||||
void JL_rcsp_update_cmd_receive_resp(void *priv, u8 OpCode, u8 status, u8 *data, u16 len)
|
||||
{
|
||||
switch (OpCode) {
|
||||
case JL_OPCODE_SEND_FW_UPDATE_BLOCK:
|
||||
if (fw_update_block_handle) {
|
||||
fw_update_block_handle(UPDATA_REV_DATA, data, len);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void rcsp_loader_download_result_handle(void *priv, u8 type, u8 cmd)
|
||||
{
|
||||
if (UPDATE_LOADER_OK == cmd) {
|
||||
//JL_rcsp_event_to_user(DEVICE_EVENT_FROM_RCSP,MSG_JL_UPDATE_START,NULL,0);
|
||||
set_jl_update_flag(1);
|
||||
if (support_dual_bank_update_en) {
|
||||
rcsp_printf(">>>rcsp update succ\n");
|
||||
update_result_set(UPDATA_SUCC);
|
||||
}
|
||||
} else {
|
||||
rcsp_printf(">>>update loader err\n");
|
||||
/* #if OTA_TWS_SAME_TIME_ENABLE */
|
||||
/* if((tws_ota_control(OTA_TYPE_GET) == OTA_TWS)) { */
|
||||
/* tws_ota_stop(OTA_STOP_UPDATE_OVER_ERR); */
|
||||
/* } */
|
||||
/* #endif */
|
||||
//rcsp_db_update_fail_deal();
|
||||
}
|
||||
}
|
||||
|
||||
extern void register_receive_fw_update_block_handle(void (*handle)(u8 state, u8 *buf, u16 len));
|
||||
extern void rcsp_update_data_api_register(u32(*data_send_hdl)(void *priv, u32 offset, u16 len), u32(*send_update_handl)(void *priv, u8 state));
|
||||
extern void rcsp_update_handle(void *buf, int len);
|
||||
extern void bt_set_low_latency_mode(int enable);
|
||||
extern void bt_adv_seq_change(void);
|
||||
extern int bt_tws_poweroff();
|
||||
extern void bt_wait_phone_connect_control(u8 enable);
|
||||
extern int tws_api_get_role(void);
|
||||
extern void tws_cancle_all_noconn();
|
||||
extern void bt_ble_rcsp_adv_disable(void);
|
||||
extern void ble_module_enable(u8 en);
|
||||
extern void bt_ble_rcsp_adv_enable(void);
|
||||
extern u32 ex_cfg_fill_content_api(void);
|
||||
extern void update_param_priv_fill(UPDATA_PARM *p, void *priv, u16 priv_len);
|
||||
|
||||
u8 rcsp_get_update_flag(void)
|
||||
{
|
||||
return tws_need_update;
|
||||
}
|
||||
|
||||
void rcsp_set_update_flag(u8 flag)
|
||||
{
|
||||
tws_need_update = flag;
|
||||
}
|
||||
|
||||
u8 rcsp_update_get_role_switch(void)
|
||||
{
|
||||
return tws_need_role_switch;
|
||||
}
|
||||
|
||||
void rcsp_update_set_role_switch(u8 sw)
|
||||
{
|
||||
tws_need_role_switch = sw;
|
||||
}
|
||||
|
||||
void update_slave_adv_reopen(void)
|
||||
{
|
||||
r_printf("slave reopen adv...\n");
|
||||
ble_module_enable(1);
|
||||
bt_ble_rcsp_adv_enable();
|
||||
}
|
||||
|
||||
static void rcsp_update_private_param_fill(UPDATA_PARM *p)
|
||||
{
|
||||
u32 exif_addr = ex_cfg_fill_content_api();
|
||||
update_param_priv_fill(p, (void *)&exif_addr, sizeof(exif_addr));
|
||||
}
|
||||
|
||||
static void rcsp_update_before_jump_handle(int type)
|
||||
{
|
||||
#if CONFIG_UPDATE_JUMP_TO_MASK
|
||||
y_printf(">>>[test]:latch reset update\n");
|
||||
latch_reset();
|
||||
#if 0
|
||||
update_close_hw("null");
|
||||
ram_protect_close();
|
||||
/* save_spi_port(); */
|
||||
extern void __BT_UPDATA_JUMP();
|
||||
y_printf("update jump to __BT_UPDATA ...\n");
|
||||
/* clk_set("sys", 48 * 1000000L); */
|
||||
//跳转到uboot加载完,30ms左右(200410_yzb)
|
||||
__BT_UPDATA_JUMP();
|
||||
#endif
|
||||
#else
|
||||
cpu_reset();
|
||||
#endif
|
||||
}
|
||||
|
||||
void JL_rcsp_msg_deal(void *hdl, u8 event, u8 *msg)
|
||||
{
|
||||
u16 remote_file_version;
|
||||
u8 can_update_flag = UPDATE_FLAG_FW_INFO_ERR;
|
||||
|
||||
switch (event) {
|
||||
case MSG_JL_GET_DEV_UPDATE_FILE_INFO_OFFSET:
|
||||
rcsp_printf("MSG_JL_GET_DEV_UPDATE_FILE_INFO_OFFSET\n");
|
||||
|
||||
/* extern void linein_mutex_stop(void *priv); */
|
||||
/* linein_mutex_stop(NULL); */
|
||||
/* extern void linein_mute(u8 mute); */
|
||||
/* linein_mute(1); */
|
||||
|
||||
JL_rcsp_resp_dev_update_file_info_offest((u8)msg[0], (u8)msg[1]);
|
||||
break;
|
||||
|
||||
case MSG_JL_INQUIRE_DEVEICE_IF_CAN_UPDATE:
|
||||
rcsp_printf("MSG_JL_INQUIRE_DEVEICE_IF_CAN_UPDATE\n");
|
||||
#if 0
|
||||
remote_file_version = READ_BIG_U16(update_file_id_info.update_file_id_info.ver);
|
||||
rcsp_printf("remote_file_ver:V%d.%d.%d.%d\n",
|
||||
(remote_file_version & 0xf000) >> 12,
|
||||
(remote_file_version & 0x0f00) >> 8,
|
||||
(remote_file_version & 0x00f0) >> 4,
|
||||
(remote_file_version & 0x000f));
|
||||
|
||||
if (0 == remote_file_version) {
|
||||
can_update_flag = UPDATE_FLAG_OK;
|
||||
} else {
|
||||
can_update_flag = judge_remote_version_can_update();
|
||||
}
|
||||
|
||||
if (UPDATE_FLAG_OK == can_update_flag) {
|
||||
set_jl_update_flag(1);
|
||||
}
|
||||
#else
|
||||
#if OTA_TWS_SAME_TIME_ENABLE
|
||||
int get_bt_tws_connect_status();
|
||||
if (get_bt_tws_connect_status() || (!support_dual_bank_update_en)) { //单备份返回成功
|
||||
can_update_flag = UPDATE_FLAG_OK;
|
||||
} else {
|
||||
can_update_flag = UPDATE_FLAG_TWS_DISCONNECT;
|
||||
}
|
||||
#else
|
||||
can_update_flag = UPDATE_FLAG_OK;
|
||||
#endif //endif OTA_TWS_SAME_TIME_ENABLE
|
||||
#endif
|
||||
//todo;judge voltage
|
||||
JL_resp_inquire_device_if_can_update((u8)msg[0], (u8)msg[1], can_update_flag);
|
||||
|
||||
if (0 == support_dual_bank_update_en) {
|
||||
if (tws_api_get_role() == TWS_ROLE_MASTER) {
|
||||
g_printf("tws master start update...\n");
|
||||
JL_rcsp_event_to_user(DEVICE_EVENT_FROM_RCSP, MSG_JL_LOADER_DOWNLOAD_START, NULL, 0);
|
||||
//需要通知从机进入了升级
|
||||
u8 data = TWS_UPDATE_INFO;
|
||||
tws_api_send_data_to_sibling(&data, sizeof(data), TWS_FUNC_ID_SEQ_RAND_SYNC);
|
||||
} else {
|
||||
bt_ble_rcsp_adv_disable();
|
||||
ble_module_enable(0); //关闭广播防止从机被手机误回连
|
||||
r_printf("slave close adv...\n");
|
||||
sys_timeout_add(NULL, update_slave_adv_reopen, 1000 * 60); //延迟一分钟再开广播
|
||||
}
|
||||
if (RCSP_SPP == JL_get_cur_bt_channel_sel()) {
|
||||
#if TCFG_USER_TWS_ENABLE
|
||||
tws_api_detach(TWS_DETACH_BY_LOCAL); //单备份升级断开tws
|
||||
tws_cancle_all_noconn();
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case MSG_JL_DEV_DISCONNECT:
|
||||
if (check_ble_all_packet_sent()) {
|
||||
rcsp_printf("MSG_JL_DEV_DISCONNECT\n");
|
||||
JL_ble_disconnect();
|
||||
if (check_edr_is_disconnct()) {
|
||||
puts("-need discon edr\n");
|
||||
user_send_cmd_prepare(USER_CTRL_POWER_OFF, 0, NULL);
|
||||
}
|
||||
ble_discon_timeout = sys_timeout_add(NULL, ble_discon_timeout_handle, 1000);
|
||||
} else {
|
||||
rcsp_printf("W");
|
||||
JL_rcsp_event_to_user(DEVICE_EVENT_FROM_RCSP, MSG_JL_DEV_DISCONNECT, NULL, 0);
|
||||
}
|
||||
break;
|
||||
|
||||
case MSG_JL_LOADER_DOWNLOAD_START:
|
||||
rcsp_update_data_api_register(rcsp_update_data_read, rcsp_update_status_response);
|
||||
register_receive_fw_update_block_handle(rcsp_update_handle);
|
||||
if (RCSP_BLE == get_curr_device_type()) {
|
||||
rcsp_update_loader_download_init(BLE_APP_UPDATA, rcsp_loader_download_result_handle);
|
||||
} else if (RCSP_SPP == get_curr_device_type()) {
|
||||
rcsp_update_loader_download_init(SPP_APP_UPDATA, rcsp_loader_download_result_handle);
|
||||
}
|
||||
break;
|
||||
|
||||
case MSG_JL_UPDATE_START:
|
||||
if (check_edr_is_disconnct()) {
|
||||
rcsp_printf("b");
|
||||
JL_rcsp_event_to_user(DEVICE_EVENT_FROM_RCSP, MSG_JL_UPDATE_START, NULL, 0);
|
||||
break;
|
||||
}
|
||||
|
||||
if (RCSP_BLE == get_curr_device_type()) {
|
||||
rcsp_printf("BLE_APP_UPDATE\n");
|
||||
update_mode_api_v2(BLE_APP_UPDATA,
|
||||
rcsp_update_private_param_fill,
|
||||
rcsp_update_before_jump_handle);
|
||||
} else {
|
||||
rcsp_printf("SPP_APP_UPDATA\n");
|
||||
update_mode_api_v2(SPP_APP_UPDATA,
|
||||
rcsp_update_private_param_fill,
|
||||
rcsp_update_before_jump_handle);
|
||||
}
|
||||
break;
|
||||
|
||||
case MSG_JL_ENTER_UPDATE_MODE:
|
||||
rcsp_printf("MSG_JL_ENTER_UPDATE_MODE:%x %x\n", msg[0], msg[1]);
|
||||
clk_set("sys",96*1000000L);
|
||||
bt_set_low_latency_mode(0);
|
||||
if (support_dual_bank_update_en && !tws_api_get_role()) {
|
||||
u8 status = 0;
|
||||
JL_CMD_response_send(msg[0], JL_PRO_STATUS_SUCCESS, msg[1], &status, 1);
|
||||
rcsp_update_data_api_register(rcsp_update_data_read, rcsp_update_status_response);
|
||||
register_receive_fw_update_block_handle(rcsp_update_handle);
|
||||
rcsp_update_loader_download_init(DUAL_BANK_UPDATA, rcsp_loader_download_result_handle);
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#else
|
||||
//以下函数是为了编译通过
|
||||
void update_slave_adv_reopen(void)
|
||||
{
|
||||
printf("%s:NULL", __func__);
|
||||
}
|
||||
void rcsp_set_update_flag(u8 flag)
|
||||
{
|
||||
printf("%s:NULL", __func__);
|
||||
}
|
||||
void rcsp_update_set_role_switch(u8 sw)
|
||||
{
|
||||
printf("%s:NULL", __func__);
|
||||
}
|
||||
u8 get_jl_update_flag(void)
|
||||
{
|
||||
printf("%s:NULL", __func__);
|
||||
return 0;
|
||||
}
|
||||
u8 rcsp_get_update_flag(void)
|
||||
{
|
||||
printf("%s:NULL", __func__);
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
@ -0,0 +1,27 @@
|
||||
#ifndef _RCSP_ADV_USER_UPDATE_H_
|
||||
#define _RCSP_ADV_USER_UPDATE_H_
|
||||
|
||||
//#include "rcsp_protocol.h"
|
||||
//#include "rcsp_packet.h"
|
||||
#include "typedef.h"
|
||||
|
||||
#define JL_OPCODE_GET_DEVICE_UPDATE_FILE_INFO_OFFSET 0xe1
|
||||
#define JL_OPCODE_INQUIRE_DEVICE_IF_CAN_UPDATE 0xe2
|
||||
#define JL_OPCODE_ENTER_UPDATE_MODE 0xe3
|
||||
#define JL_OPCODE_EXIT_UPDATE_MODE 0xe4
|
||||
#define JL_OPCODE_SEND_FW_UPDATE_BLOCK 0xe5
|
||||
#define JL_OPCODE_GET_DEVICE_REFRESH_FW_STATUS 0xe6
|
||||
#define JL_OPCODE_SET_DEVICE_REBOOT 0xe7
|
||||
#define JL_OPCODE_NOTIFY_UPDATE_CONENT_SIZE 0xe8
|
||||
|
||||
|
||||
void JL_rcsp_update_cmd_resp(void *priv, u8 OpCode, u8 OpCode_SN, u8 *data, u16 len);
|
||||
void JL_rcsp_update_cmd_receive_resp(void *priv, u8 OpCode, u8 status, u8 *data, u16 len);
|
||||
void JL_rcsp_msg_deal(void *hdl, u8 event, u8 *msg);
|
||||
u8 get_jl_update_flag(void);
|
||||
void set_jl_update_flag(u8 flag);
|
||||
u8 get_curr_device_type(void);
|
||||
void update_slave_adv_reopen(void);
|
||||
|
||||
#endif
|
||||
|
||||
@ -0,0 +1,377 @@
|
||||
//#include "update_lib.h"
|
||||
#include "update.h"
|
||||
#include "uart.h"
|
||||
#include "update_loader_download.h"
|
||||
#include "system/fs/fs.h"
|
||||
#include "rcsp_user_update.h"
|
||||
#include "JL_rcsp_protocol.h"
|
||||
#include "os/os_error.h"
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#if OTA_TWS_SAME_TIME_NEW
|
||||
#include "update_tws_new.h"
|
||||
#else
|
||||
#include "update_tws.h"
|
||||
#endif
|
||||
|
||||
#if TCFG_USER_TWS_ENABLE
|
||||
#include "bt_tws.h"
|
||||
#endif
|
||||
|
||||
#if ((RCSP_ADV_EN || RCSP_BTMATE_EN))
|
||||
|
||||
#define LMP_CH_UPDATE_DEBUG_EN 1
|
||||
#if LMP_CH_UPDATE_DEBUG_EN
|
||||
#define deg_puts puts
|
||||
#define deg_printf printf
|
||||
#else
|
||||
#define deg_puts(...)
|
||||
#define deg_printf(...)
|
||||
#endif
|
||||
|
||||
typedef enum __DEVICE_REFRESH_FW_STATUS {
|
||||
DEVICE_UPDATE_STA_SUCCESS = 0, //升级成功(default)
|
||||
DEVICE_UPDATE_STA_VERIFY_ERR, //升级完校验代码出错(default)
|
||||
DEVICE_UPDATE_STA_FAIL, //升级失败(default)
|
||||
DEVICE_UPDATE_STA_KEY_ERR, //加密key不匹配
|
||||
DEVICE_UPDATE_STA_FILE_ERR, //升级文件出错
|
||||
DEVICE_UPDATE_STA_TYPE_ERR, //升级类型出错,仅code_type;
|
||||
//DEVICE_UPDATE_STA_MAX_ERR,
|
||||
DEVICE_UPDATE_STA_LOADER_DOWNLOAD_SUCC = 0x80,
|
||||
} DEVICE_UPDATE_STA;
|
||||
|
||||
enum {
|
||||
BT_UPDATE_OVER = 0,
|
||||
BT_UPDATE_KEY_ERR,
|
||||
BT_UPDATE_CONNECT_ERR,
|
||||
};
|
||||
|
||||
typedef enum {
|
||||
UPDATA_START = 0x00,
|
||||
UPDATA_REV_DATA,
|
||||
UPDATA_STOP,
|
||||
} UPDATA_BIT_FLAG;
|
||||
|
||||
|
||||
typedef struct _rcsp_update_param_t {
|
||||
u32 state;
|
||||
u32 read_len;
|
||||
u32 need_rx_len;
|
||||
u8 *read_buf;
|
||||
void (*resume_hdl)(void *priv);
|
||||
int (*sleep_hdl)(void *priv);
|
||||
u32(*data_send_hdl)(void *priv, u32 offset, u16 len);
|
||||
u32(*send_update_status_hdl)(void *priv, u8 state);
|
||||
u32 file_offset;
|
||||
u8 seek_type;
|
||||
} rcsp_update_param_t;
|
||||
|
||||
extern void set_jl_update_flag(u8 flag);
|
||||
|
||||
extern const int support_dual_bank_update_en;
|
||||
|
||||
static rcsp_update_param_t rcsp_update_param;
|
||||
#define __this (&rcsp_update_param)
|
||||
|
||||
static u8 *bt_read_buf = NULL;
|
||||
static u16 g_bt_read_len = 0;
|
||||
static u32 rcsp_file_offset = 0;
|
||||
static u8 rcsp_seek_type = 0;
|
||||
|
||||
//NOTE:测试盒的定义和本sdk文件系统的seek_type定义不一样;
|
||||
enum {
|
||||
BT_SEEK_SET = 0x01,
|
||||
BT_SEEK_CUR = 0x02,
|
||||
|
||||
BT_SEEK_TYPE_UPDATE_LEN = 0x10,
|
||||
};
|
||||
|
||||
void tws_api_auto_role_switch_disable();
|
||||
void tws_api_auto_role_switch_enable();
|
||||
|
||||
int rcsp_f_seek(void *fp, u8 type, u32 offset)
|
||||
{
|
||||
if (type == SEEK_SET) {
|
||||
__this->file_offset = offset;
|
||||
__this->seek_type = BT_SEEK_SET;
|
||||
} else if (type == SEEK_CUR) {
|
||||
__this->file_offset += offset;
|
||||
__this->seek_type = BT_SEEK_CUR;
|
||||
}
|
||||
|
||||
/* lib_printf("---------UPDATA_seek type %d, offsize %d----------\n", bt_seek_type, bt_file_offset); */
|
||||
return 0;//FR_OK;
|
||||
}
|
||||
|
||||
static u16 rcsp_f_stop(u8 err);
|
||||
|
||||
#define RETRY_TIMES 3
|
||||
u8 get_rcsp_connect_status();
|
||||
u16 rcsp_f_read(void *fp, u8 *buff, u16 len)
|
||||
{
|
||||
//printf("===rcsp_read:%x %x\n", __this->file_offset, len);
|
||||
u8 retry_cnt = 0;
|
||||
|
||||
__this->need_rx_len = len;
|
||||
__this->state = UPDATA_REV_DATA;
|
||||
__this->read_len = 0;
|
||||
__this->read_buf = buff;
|
||||
|
||||
__RETRY:
|
||||
if (!get_rcsp_connect_status()) { //如果已经断开连接直接返回-1
|
||||
return -1;
|
||||
}
|
||||
__this->data_send_hdl(fp, __this->file_offset, len);
|
||||
|
||||
while (!((0 == __this->state) && (__this->read_len == len))) {
|
||||
if (__this->sleep_hdl && get_rcsp_connect_status()) {
|
||||
__this->sleep_hdl(NULL);
|
||||
} else {
|
||||
len = -1;
|
||||
break;
|
||||
}
|
||||
|
||||
if (!((0 == __this->state) && (__this->read_len == len))) {
|
||||
if (retry_cnt++ > RETRY_TIMES) {
|
||||
len = (u16) - 1;
|
||||
break;
|
||||
} else {
|
||||
goto __RETRY;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ((u16) - 1 != len) {
|
||||
__this->file_offset += len;
|
||||
}
|
||||
|
||||
|
||||
return len;
|
||||
}
|
||||
|
||||
u16 rcsp_f_open(void)
|
||||
{
|
||||
deg_puts(">>>rcsp_f_open\n");
|
||||
__this->file_offset = 0;
|
||||
__this->seek_type = BT_SEEK_SET;
|
||||
return 1;
|
||||
}
|
||||
|
||||
u16 rcsp_send_update_len(u32 update_len)
|
||||
{
|
||||
/* while (0 == (bit(updata_start) & bt_updata_get_flag())); */
|
||||
/* bt_updata_clr_flag(updata_start); //clr flag */
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
static u8 update_result_handle(u8 err)
|
||||
{
|
||||
u8 res = DEVICE_UPDATE_STA_LOADER_DOWNLOAD_SUCC;
|
||||
|
||||
/* #if OTA_TWS_SAME_TIME_ENABLE */
|
||||
/* tws_api_auto_role_switch_enable(); */
|
||||
/* #endif */
|
||||
|
||||
if (err & UPDATE_RESULT_FLAG_BITMAP) {
|
||||
switch (err & 0x7f) {
|
||||
//升级文件错误
|
||||
case UPDATE_RESULT_FILE_SIZE_ERR:
|
||||
case UPDATE_RESULT_LOADER_SIZE_ERR:
|
||||
case UPDATE_RESULT_REMOTE_FILE_HEAD_ERR:
|
||||
case UPDATE_RESULT_LOCAL_FILE_HEAD_ERR:
|
||||
case UPDATE_RESULT_FILE_OPERATION_ERR:
|
||||
case UPDATE_RESULT_NOT_FIND_TARGET_FILE_ERR:
|
||||
case UPDATE_RESULT_PRODUCT_INFO_NOT_MATCH:
|
||||
res = DEVICE_UPDATE_STA_FILE_ERR;
|
||||
break;
|
||||
//文件内容校验失败
|
||||
case UPDATE_RESULT_LOADER_VERIFY_ERR:
|
||||
case UPDATE_RESULT_FLASH_DATA_VERIFY_ERR:
|
||||
res = DEVICE_UPDATE_STA_VERIFY_ERR;
|
||||
break;
|
||||
|
||||
}
|
||||
} else if (BT_UPDATE_OVER == err) {
|
||||
if (support_dual_bank_update_en) {
|
||||
res = DEVICE_UPDATE_STA_SUCCESS;
|
||||
} else {
|
||||
res = DEVICE_UPDATE_STA_LOADER_DOWNLOAD_SUCC;
|
||||
}
|
||||
} else if (BT_UPDATE_KEY_ERR == err) {
|
||||
res = DEVICE_UPDATE_STA_KEY_ERR;
|
||||
} else {
|
||||
res = DEVICE_UPDATE_STA_FAIL;
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
static u16 rcsp_f_stop(u8 err)
|
||||
{
|
||||
/* while (0 == (bit(updata_start) & bt_updata_get_flag())); */
|
||||
/* bt_updata_clr_flag(updata_start); //clr flag */
|
||||
|
||||
err = update_result_handle(err);
|
||||
__this->state = UPDATA_STOP;
|
||||
printf(">>>rcsp_stop:%x\n", __this->state);
|
||||
|
||||
if (__this->data_send_hdl) {
|
||||
__this->data_send_hdl(NULL, 0, 0);
|
||||
}
|
||||
|
||||
while (!(0 == __this->state)) {
|
||||
if (__this->sleep_hdl && get_rcsp_connect_status()) {
|
||||
if (__this->sleep_hdl(NULL) == OS_TIMEOUT) {
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (__this->send_update_status_hdl) {
|
||||
__this->send_update_status_hdl(NULL, err);
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
void db_update_notify_fail_to_phone()
|
||||
{
|
||||
if (get_rcsp_connect_status()) {
|
||||
rcsp_f_stop(DEVICE_UPDATE_STA_FAIL);
|
||||
}
|
||||
}
|
||||
|
||||
__attribute__((weak))
|
||||
void user_change_ble_conn_param(u8 param_index)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
static int rcsp_notify_update_content_size(void *priv, u32 size)
|
||||
{
|
||||
int err;
|
||||
|
||||
u8 data[4];
|
||||
|
||||
WRITE_BIG_U32(data, size);
|
||||
|
||||
user_change_ble_conn_param(0);
|
||||
|
||||
deg_printf("send content_size:%x\n", size);
|
||||
err = JL_CMD_send(JL_OPCODE_NOTIFY_UPDATE_CONENT_SIZE, data, sizeof(data), JL_NEED_RESPOND);
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
void rcsp_update_handle(u8 state, void *buf, int len)
|
||||
{
|
||||
/* deg_puts("R"); */
|
||||
if (state != __this->state) {
|
||||
deg_puts(">>>rcsp state err\n");
|
||||
return;
|
||||
}
|
||||
|
||||
switch (state) {
|
||||
case UPDATA_REV_DATA:
|
||||
if (__this->read_buf) {
|
||||
memcpy(__this->read_buf, buf, len);
|
||||
__this->read_len = len;
|
||||
__this->state = 0;
|
||||
}
|
||||
break;
|
||||
|
||||
case UPDATA_STOP:
|
||||
__this->state = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
if (__this->resume_hdl) {
|
||||
__this->resume_hdl(NULL);
|
||||
}
|
||||
}
|
||||
|
||||
void rcsp_resume(void)
|
||||
{
|
||||
if (__this->resume_hdl) {
|
||||
__this->resume_hdl(NULL);
|
||||
}
|
||||
}
|
||||
|
||||
static void rcsp_update_resume_hdl_register(void (*resume_hdl)(void *priv), int (*sleep_hdl)(void *priv))
|
||||
{
|
||||
__this->resume_hdl = resume_hdl;
|
||||
__this->sleep_hdl = sleep_hdl;
|
||||
}
|
||||
|
||||
void rcsp_update_data_api_register(u32(*data_send_hdl)(void *priv, u32 offset, u16 len), u32(*send_update_status_hdl)(void *priv, u8 state))
|
||||
{
|
||||
__this->data_send_hdl = data_send_hdl;
|
||||
__this->send_update_status_hdl = send_update_status_hdl;
|
||||
}
|
||||
|
||||
void rcsp_update_data_api_unregister(void)
|
||||
{
|
||||
__this->data_send_hdl = NULL;
|
||||
__this->send_update_status_hdl = NULL;
|
||||
}
|
||||
|
||||
void rcsp_ch_update_init(void (*resume_hdl)(void *priv), int (*sleep_hdl)(void *priv))
|
||||
{
|
||||
deg_puts("------------rcsp_ch_update_init\n");
|
||||
|
||||
rcsp_update_resume_hdl_register(resume_hdl, sleep_hdl);
|
||||
//register_receive_fw_update_block_handle(rcsp_updata_handle);
|
||||
}
|
||||
|
||||
const update_op_api_t rcsp_update_op = {
|
||||
.ch_init = rcsp_ch_update_init,
|
||||
.f_open = rcsp_f_open,
|
||||
.f_read = rcsp_f_read,
|
||||
.f_seek = rcsp_f_seek,
|
||||
.f_stop = rcsp_f_stop,
|
||||
.notify_update_content_size = rcsp_notify_update_content_size,
|
||||
};
|
||||
|
||||
static void rcsp_update_state_cbk(int type, u32 state, void *priv)
|
||||
{
|
||||
update_ret_code_t *ret_code = (update_ret_code_t *)priv;
|
||||
if (ret_code) {
|
||||
printf("state:%x err:%x\n", ret_code->stu, ret_code->err_code);
|
||||
}
|
||||
switch (state) {
|
||||
case UPDATE_CH_EXIT:
|
||||
if (UPDATE_DUAL_BANK_IS_SUPPORT()) {
|
||||
if ((0 == ret_code->stu) && (0 == ret_code->err_code)) {
|
||||
set_jl_update_flag(1);
|
||||
printf(">>>rcsp update succ\n");
|
||||
update_result_set(UPDATA_SUCC);
|
||||
|
||||
} else {
|
||||
update_result_set(UPDATA_DEV_ERR);
|
||||
printf(">>>rcsp update succ\n");
|
||||
}
|
||||
} else {
|
||||
if ((0 == ret_code->stu) && (0 == ret_code->err_code)) {
|
||||
set_jl_update_flag(1);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void rcsp_update_loader_download_init(int update_type, void (*result_cbk)(void *priv, u8 type, u8 cmd))
|
||||
{
|
||||
update_mode_info_t info = {
|
||||
.type = update_type,
|
||||
.state_cbk = rcsp_update_state_cbk,
|
||||
.p_op_api = &rcsp_update_op,
|
||||
.task_en = 1,
|
||||
};
|
||||
app_active_update_task_init(&info);
|
||||
}
|
||||
|
||||
#endif //(OTA_TWS_SAME_TIME_ENABLE && (RCSP_ADV_EN || RCSP_BTMATE_EN))
|
||||
@ -0,0 +1,564 @@
|
||||
#include "rcsp_user_update.h"
|
||||
#include "app_config.h"
|
||||
#if RCSP_UPDATE_EN
|
||||
#include "uart.h"
|
||||
#include "system/timer.h"
|
||||
#include "update.h"
|
||||
#include "custom_cfg.h"
|
||||
#include "btstack/avctp_user.h"
|
||||
#include "JL_rcsp_packet.h"
|
||||
#include "JL_rcsp_protocol.h"
|
||||
#include "rcsp_bluetooth.h"
|
||||
#include "update_loader_download.h"
|
||||
#if(TCFG_USER_TWS_ENABLE == 1)
|
||||
#include "classic/tws_api.h"
|
||||
#endif
|
||||
#include "btstack_3th_protocol_user.h"
|
||||
|
||||
#if (RCSP_BTMATE_EN)
|
||||
|
||||
#define RCSP_DEBUG_EN
|
||||
|
||||
#ifdef RCSP_BTMATE_EN
|
||||
#define rcsp_putchar(x) putchar(x)
|
||||
#define rcsp_printf printf
|
||||
#define rcsp_printf_buf(x,len) printf_buf(x,len)
|
||||
#else
|
||||
#define rcsp_putchar(...)
|
||||
#define rcsp_printf(...)
|
||||
#define rcsp_printf_buf(...)
|
||||
#endif
|
||||
|
||||
#define DEV_UPDATE_FILE_INFO_OFFEST 0x00//0x40
|
||||
#define DEV_UPDATE_FILE_INFO_LEN 0x00//(0x10 + VER_INFO_EXT_COUNT * (VER_INFO_EXT_MAX_LEN + 1))
|
||||
|
||||
typedef enum {
|
||||
UPDATA_START = 0x00,
|
||||
UPDATA_REV_DATA,
|
||||
UPDATA_STOP,
|
||||
} UPDATA_BIT_FLAG;
|
||||
|
||||
typedef struct _update_mode_t {
|
||||
u8 opcode;
|
||||
u8 opcode_sn;
|
||||
|
||||
} update_mode_t;
|
||||
|
||||
|
||||
extern const int support_dual_bank_update_en;
|
||||
extern void JL_ble_disconnect(void);
|
||||
extern void set_curr_update_type(u8 type);
|
||||
extern u8 check_le_pakcet_sent_finish_flag(void);
|
||||
extern void register_receive_fw_update_block_handle(void (*handle)(u8 state, u8 *buf, u16 len));
|
||||
extern void rcsp_update_data_api_register(u32(*data_send_hdl)(void *priv, u32 offset, u16 len), u32(*send_update_handl)(void *priv, u8 state));
|
||||
extern void rcsp_update_handle(void *buf, int len);
|
||||
extern u32 ex_cfg_fill_content_api(void);
|
||||
extern void update_result_set(u16 result);
|
||||
|
||||
static u8 rcsp_update_status;
|
||||
static u8 update_flag = 0;
|
||||
static u16 ble_discon_timeout;
|
||||
static void (*fw_update_block_handle)(u8 state, u8 *buf, u16 len) = NULL;
|
||||
|
||||
static update_file_ext_id_t update_file_id_info = {
|
||||
.update_file_id_info.ver[0] = 0xff,
|
||||
.update_file_id_info.ver[1] = 0xff,
|
||||
};
|
||||
|
||||
static update_mode_t update_record_info;
|
||||
|
||||
u8 get_jl_update_flag(void)
|
||||
{
|
||||
printf("get_update_flag:%x\n", update_flag);
|
||||
return update_flag;
|
||||
}
|
||||
|
||||
void set_jl_update_flag(u8 flag)
|
||||
{
|
||||
update_flag = flag;
|
||||
printf("update_flag:%x\n", update_flag);
|
||||
}
|
||||
|
||||
void JL_controller_save_curr_cmd_para(u8 OpCode, u8 OpCode_SN)
|
||||
{
|
||||
update_record_info.opcode = OpCode;
|
||||
update_record_info.opcode_sn = OpCode_SN;
|
||||
}
|
||||
|
||||
void JL_controller_get_curr_cmd_para(u8 *OpCode, u8 *OpCode_SN)
|
||||
{
|
||||
*OpCode = update_record_info.opcode;
|
||||
*OpCode_SN = update_record_info.opcode_sn;
|
||||
}
|
||||
|
||||
void register_receive_fw_update_block_handle(void (*handle)(u8 state, u8 *buf, u16 len))
|
||||
{
|
||||
fw_update_block_handle = handle;
|
||||
}
|
||||
|
||||
static void ble_discon_timeout_handle(void *priv)
|
||||
{
|
||||
rcsp_msg_post(MSG_JL_UPDATE_START, 0);
|
||||
}
|
||||
|
||||
void JL_rcsp_update_cmd_resp(void *priv, u8 OpCode, u8 OpCode_SN, u8 *data, u16 len)
|
||||
{
|
||||
u8 msg[4];
|
||||
rcsp_printf("%s\n", __FUNCTION__);
|
||||
switch (OpCode) {
|
||||
case JL_OPCODE_GET_DEVICE_UPDATE_FILE_INFO_OFFSET:
|
||||
if (0 == len) {
|
||||
rcsp_printf("JL_OPCODE_GET_DEVICE_UPDATE_FILE_INFO_OFFSET\n");
|
||||
rcsp_msg_post(MSG_JL_GET_DEV_UPDATE_FILE_INFO_OFFSET, 2, OpCode, OpCode_SN);
|
||||
} else {
|
||||
rcsp_printf("JL_OPCODE_GET_DEVICE_UPDATE_FILE_INFO_OFFSET ERR\n");
|
||||
}
|
||||
break;
|
||||
case JL_OPCODE_INQUIRE_DEVICE_IF_CAN_UPDATE:
|
||||
rcsp_printf("JL_OPCODE_INQUIRE_DEVICE_IF_CAN_UPDATE:%x %x\n", len, data[0]);
|
||||
//if (DEV_UPDATE_FILE_INFO_LEN == len) {
|
||||
if (len) {
|
||||
//memcpy((u8 *)&update_file_id_info, data, DEV_UPDATE_FILE_INFO_LEN);
|
||||
set_curr_update_type(data[0]);
|
||||
rcsp_msg_post(MSG_JL_INQUIRE_DEVEICE_IF_CAN_UPDATE, 3, OpCode, OpCode_SN, 0x00);
|
||||
}
|
||||
break;
|
||||
case JL_OPCODE_EXIT_UPDATE_MODE:
|
||||
rcsp_printf("JL_OPCODE_EXIT_UPDATE_MODE\n");
|
||||
break;
|
||||
case JL_OPCODE_ENTER_UPDATE_MODE:
|
||||
rcsp_printf("JL_OPCODE_ENTER_UPDATE_MODE\n");
|
||||
rcsp_msg_post(MSG_JL_ENTER_UPDATE_MODE, 2, OpCode, OpCode_SN);
|
||||
break;
|
||||
case JL_OPCODE_SEND_FW_UPDATE_BLOCK:
|
||||
rcsp_printf("JL_OPCODE_SEND_FW_UPDATE_BLOCK\n");
|
||||
break;
|
||||
case JL_OPCODE_GET_DEVICE_REFRESH_FW_STATUS:
|
||||
rcsp_printf("JL_OPCODE_GET_DEVICE_REFRESH_FW_STATUS\n");
|
||||
JL_controller_save_curr_cmd_para(OpCode, OpCode_SN);
|
||||
if (fw_update_block_handle) {
|
||||
fw_update_block_handle(UPDATA_STOP, NULL, 0);
|
||||
}
|
||||
break;
|
||||
case JL_OPCODE_SET_DEVICE_REBOOT:
|
||||
rcsp_printf("JL_OPCODE_SET_DEVICE_REBOOT\n");
|
||||
if (support_dual_bank_update_en) {
|
||||
cpu_reset();
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void JL_rcsp_resp_dev_update_file_info_offest(u8 OpCode, u8 OpCode_SN)
|
||||
{
|
||||
u8 data[4 + 2];
|
||||
u16 update_file_info_offset = DEV_UPDATE_FILE_INFO_OFFEST;
|
||||
u16 update_file_info_len = DEV_UPDATE_FILE_INFO_LEN;
|
||||
WRITE_BIG_U32(data + 0, update_file_info_offset);
|
||||
WRITE_BIG_U16(data + 4, update_file_info_len);
|
||||
|
||||
JL_CMD_response_send(OpCode, JL_PRO_STATUS_SUCCESS, OpCode_SN, data, sizeof(data));
|
||||
}
|
||||
|
||||
static void JL_resp_inquire_device_if_can_update(u8 OpCode, u8 OpCode_SN, u8 update_sta)
|
||||
{
|
||||
u8 data[1];
|
||||
data[0] = update_sta;
|
||||
JL_CMD_response_send(OpCode, JL_PRO_STATUS_SUCCESS, OpCode_SN, data, sizeof(data));
|
||||
}
|
||||
|
||||
enum {
|
||||
UPDATE_FLAG_OK,
|
||||
UPDATE_FLAG_LOW_POWER,
|
||||
UPDATE_FLAG_FW_INFO_ERR,
|
||||
UPDATE_FLAG_FW_INFO_CONSISTENT,
|
||||
};
|
||||
|
||||
static u8 judge_remote_version_can_update(void)
|
||||
{
|
||||
//extern u16 ex_cfg_get_local_version_info(void);
|
||||
u16 remote_file_ver = READ_BIG_U16(update_file_id_info.update_file_id_info.ver);
|
||||
//u16 local_ver = ex_cfg_get_local_version_info();
|
||||
u16 local_ver = get_vid_pid_ver_from_cfg_file(GET_VID_FROM_EX_CFG);
|
||||
|
||||
#if (0 == VER_INFO_EXT_COUNT)
|
||||
//extern u16 ex_cfg_get_local_pid_info(void);
|
||||
//extern u16 ex_cfg_get_local_vid_info(void);
|
||||
|
||||
//u16 local_pid = ex_cfg_get_local_pid_info();
|
||||
//u16 local_vid = ex_cfg_get_local_vid_info();
|
||||
u16 local_pid = get_vid_pid_ver_from_cfg_file(GET_PID_FROM_EX_CFG);
|
||||
u16 local_vid = get_vid_pid_ver_from_cfg_file(GET_VID_FROM_EX_CFG);
|
||||
|
||||
u16 remote_file_pid = READ_BIG_U16(update_file_id_info.update_file_id_info.pid);
|
||||
u16 remote_file_vid = READ_BIG_U16(update_file_id_info.update_file_id_info.vid);
|
||||
|
||||
if (remote_file_ver > local_ver || remote_file_pid != local_pid || remote_file_vid != local_vid) {
|
||||
return UPDATE_FLAG_FW_INFO_ERR;
|
||||
}
|
||||
#else
|
||||
//extern u32 ex_cfg_get_local_authkey_info(u8 * authkey_data[], u8 * authkey_len);
|
||||
//extern u32 ex_cfg_get_local_procode_info(u8 * procode_data[], u8 * procode_len);
|
||||
|
||||
u8 authkey_len = 0;
|
||||
u8 *local_authkey_data = NULL;
|
||||
get_authkey_procode_from_cfg_file(&local_authkey_data, &authkey_len, GET_AUTH_KEY_FROM_EX_CFG);
|
||||
|
||||
u8 procode_len = 0;
|
||||
u8 *local_procode_data = NULL;
|
||||
get_authkey_procode_from_cfg_file(&local_procode_data, &procode_len, GET_PRO_CODE_FROM_EX_CFG);
|
||||
|
||||
//ex_cfg_get_local_authkey_info(&local_authkey_data, &authkey_len);
|
||||
//ex_cfg_get_local_procode_info(&local_procode_data, &procode_len);
|
||||
|
||||
u8 *remote_authkey_data = update_file_id_info.ext;
|
||||
u8 *remote_procode_data = update_file_id_info.ext + authkey_len + 1;
|
||||
|
||||
if (remote_file_ver < local_ver
|
||||
|| 0 != memcmp(remote_authkey_data, local_authkey_data, authkey_len)
|
||||
|| 0 != memcmp(remote_procode_data, local_procode_data, procode_len)) {
|
||||
return UPDATE_FLAG_FW_INFO_ERR;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (remote_file_ver == local_ver) {
|
||||
rcsp_printf("remote_file_ver is %x, local_ver is %x, remote_file_ver is similar to local_ver\n", remote_file_ver, local_ver);
|
||||
return UPDATE_FLAG_FW_INFO_CONSISTENT;
|
||||
}
|
||||
|
||||
return UPDATE_FLAG_OK;
|
||||
}
|
||||
|
||||
static bool check_edr_is_disconnct(void)
|
||||
{
|
||||
if (get_curr_channel_state()) {
|
||||
return TRUE;
|
||||
} else {
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
static bool check_ble_all_packet_sent(void)
|
||||
{
|
||||
if (check_le_pakcet_sent_finish_flag()) {
|
||||
return TRUE;
|
||||
} else {
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static u32 rcsp_update_data_read(void *priv, u32 offset_addr, u16 len)
|
||||
{
|
||||
u32 err;
|
||||
u8 data[4 + 2];
|
||||
WRITE_BIG_U32(data, offset_addr);
|
||||
WRITE_BIG_U16(data + 4, len);
|
||||
err = JL_CMD_send(JL_OPCODE_SEND_FW_UPDATE_BLOCK, data, sizeof(data), JL_NEED_RESPOND);
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
static JL_ERR JL_controller_resp_get_dev_refresh_fw_status(u8 OpCode, u8 OpCode_SN, u8 result)
|
||||
{
|
||||
JL_ERR send_err = JL_ERR_NONE;
|
||||
u8 data[1];
|
||||
|
||||
data[0] = result; //0:sucess 1:fail;
|
||||
|
||||
send_err = JL_CMD_response_send(OpCode, JL_PRO_STATUS_SUCCESS, OpCode_SN, data, sizeof(data));
|
||||
|
||||
return send_err;
|
||||
}
|
||||
|
||||
u32 rcsp_update_status_response(void *priv, u8 status)
|
||||
{
|
||||
u8 OpCode;
|
||||
u8 OpCode_SN;
|
||||
|
||||
JL_ERR send_err = JL_ERR_NONE;
|
||||
|
||||
JL_controller_get_curr_cmd_para(&OpCode, &OpCode_SN);
|
||||
|
||||
//log_info("get cmd para:%x %x\n", OpCode, OpCode_SN);
|
||||
|
||||
if (JL_OPCODE_GET_DEVICE_REFRESH_FW_STATUS == OpCode) {
|
||||
send_err = JL_controller_resp_get_dev_refresh_fw_status(OpCode, OpCode_SN, status);
|
||||
}
|
||||
|
||||
return send_err;
|
||||
}
|
||||
|
||||
|
||||
|
||||
void JL_rcsp_update_cmd_receive_resp(void *priv, u8 OpCode, u8 status, u8 *data, u16 len)
|
||||
{
|
||||
switch (OpCode) {
|
||||
case JL_OPCODE_SEND_FW_UPDATE_BLOCK:
|
||||
if (fw_update_block_handle) {
|
||||
fw_update_block_handle(UPDATA_REV_DATA, data, len);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void rcsp_loader_download_result_handle(void *priv, u8 type, u8 cmd)
|
||||
{
|
||||
if (UPDATE_LOADER_OK == cmd) {
|
||||
//rcsp_msg(MSG_JL_UPDATE_START, 0);
|
||||
set_jl_update_flag(1);
|
||||
if (support_dual_bank_update_en) {
|
||||
rcsp_printf(">>>rcsp update succ\n");
|
||||
update_result_set(UPDATA_SUCC);
|
||||
}
|
||||
} else {
|
||||
rcsp_printf(">>>update loader err\n");
|
||||
#if OTA_TWS_SAME_TIME_ENABLE
|
||||
if ((tws_ota_control(OTA_TYPE_GET) == OTA_TWS)) {
|
||||
tws_ota_stop(OTA_STOP_UPDATE_OVER_ERR);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
u32 get_jl_rcsp_update_status()
|
||||
{
|
||||
return rcsp_update_status;
|
||||
}
|
||||
|
||||
static void rcsp_update_private_param_fill(UPDATA_PARM *p)
|
||||
{
|
||||
u32 exif_addr;
|
||||
|
||||
exif_addr = ex_cfg_fill_content_api();
|
||||
update_param_priv_fill(p, (void *)&exif_addr, sizeof(exif_addr));
|
||||
}
|
||||
|
||||
static void rcsp_update_before_jump_handle(int type)
|
||||
{
|
||||
#if CONFIG_UPDATE_JUMP_TO_MASK
|
||||
y_printf(">>>[test]:latch reset update\n");
|
||||
latch_reset();
|
||||
|
||||
#if 0
|
||||
update_close_hw("null");
|
||||
ram_protect_close();
|
||||
/* save_spi_port(); */
|
||||
extern void __BT_UPDATA_JUMP();
|
||||
y_printf("update jump to __BT_UPDATA ...\n");
|
||||
//跳转到uboot加载完,30ms左右(200410_yzb)
|
||||
/* clk_set("sys", 48 * 1000000L); */
|
||||
__BT_UPDATA_JUMP();
|
||||
#endif
|
||||
#else
|
||||
cpu_reset();
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
void JL_rcsp_msg_deal(RCSP_MSG msg, int argc, int *argv)
|
||||
{
|
||||
u16 remote_file_version;
|
||||
u8 can_update_flag = UPDATE_FLAG_FW_INFO_ERR;
|
||||
|
||||
switch (msg) {
|
||||
case MSG_JL_GET_DEV_UPDATE_FILE_INFO_OFFSET:
|
||||
rcsp_printf("MSG_JL_GET_DEV_UPDATE_FILE_INFO_OFFSET\n");
|
||||
rcsp_update_status = 1;
|
||||
/* extern void linein_mutex_stop(void *priv); */
|
||||
/* linein_mutex_stop(NULL); */
|
||||
/* extern void linein_mute(u8 mute); */
|
||||
/* linein_mute(1); */
|
||||
if (argc < 2) {
|
||||
rcsp_printf("err: MSG_JL_GET_DEV_UPDATE_FILE_INFO_OFFSET too few argument, argc is %d\n", argc);
|
||||
return;
|
||||
}
|
||||
|
||||
JL_rcsp_resp_dev_update_file_info_offest((u8)argv[0], (u8)argv[1]);
|
||||
break;
|
||||
|
||||
case MSG_JL_INQUIRE_DEVEICE_IF_CAN_UPDATE:
|
||||
rcsp_printf("MSG_JL_INQUIRE_DEVEICE_IF_CAN_UPDATE\n");
|
||||
if (argc < 2) {
|
||||
rcsp_printf("err: MSG_JL_INQUIRE_DEVEICE_IF_CAN_UPDATE too few argument, argc is %d\n", argc);
|
||||
return;
|
||||
}
|
||||
#if 0
|
||||
remote_file_version = READ_BIG_U16(update_file_id_info.update_file_id_info.ver);
|
||||
rcsp_printf("remote_file_ver:V%d.%d.%d.%d\n",
|
||||
(remote_file_version & 0xf000) >> 12,
|
||||
(remote_file_version & 0x0f00) >> 8,
|
||||
(remote_file_version & 0x00f0) >> 4,
|
||||
(remote_file_version & 0x000f));
|
||||
|
||||
if (0 == remote_file_version) {
|
||||
can_update_flag = UPDATE_FLAG_OK;
|
||||
} else {
|
||||
can_update_flag = judge_remote_version_can_update();
|
||||
}
|
||||
|
||||
if (UPDATE_FLAG_OK == can_update_flag) {
|
||||
set_jl_update_flag(1);
|
||||
}
|
||||
#else
|
||||
can_update_flag = UPDATE_FLAG_OK;
|
||||
#endif
|
||||
//todo;judge voltage
|
||||
JL_resp_inquire_device_if_can_update((u8)argv[0], (u8)argv[1], can_update_flag);
|
||||
|
||||
if (0 == support_dual_bank_update_en) {
|
||||
rcsp_msg_post(MSG_JL_LOADER_DOWNLOAD_START, 0);
|
||||
}
|
||||
break;
|
||||
|
||||
case MSG_JL_DEV_DISCONNECT:
|
||||
if (check_ble_all_packet_sent()) {
|
||||
rcsp_printf("MSG_JL_DEV_DISCONNECT\n");
|
||||
JL_ble_disconnect();
|
||||
if (check_edr_is_disconnct()) {
|
||||
puts("-need discon edr\n");
|
||||
user_send_cmd_prepare(USER_CTRL_POWER_OFF, 0, NULL);
|
||||
}
|
||||
ble_discon_timeout = sys_timeout_add(NULL, ble_discon_timeout_handle, 1000);
|
||||
} else {
|
||||
rcsp_printf("W");
|
||||
rcsp_msg_post(MSG_JL_DEV_DISCONNECT, 0);
|
||||
}
|
||||
break;
|
||||
|
||||
case MSG_JL_LOADER_DOWNLOAD_START:
|
||||
rcsp_update_data_api_register(rcsp_update_data_read, rcsp_update_status_response);
|
||||
register_receive_fw_update_block_handle(rcsp_update_handle);
|
||||
if (RCSP_BLE == get_curr_device_type()) {
|
||||
rcsp_update_loader_download_init(BLE_APP_UPDATA, rcsp_loader_download_result_handle);
|
||||
} else if (RCSP_SPP == get_curr_device_type()) {
|
||||
rcsp_update_loader_download_init(SPP_APP_UPDATA, rcsp_loader_download_result_handle);
|
||||
}
|
||||
break;
|
||||
|
||||
case MSG_JL_UPDATE_START:
|
||||
if (check_edr_is_disconnct()) {
|
||||
rcsp_printf("b");
|
||||
rcsp_msg_post(MSG_JL_UPDATE_START, 0);
|
||||
break;
|
||||
}
|
||||
|
||||
if (RCSP_BLE == get_curr_device_type()) {
|
||||
rcsp_printf("BLE_APP_UPDATE\n");
|
||||
update_mode_api_v2(BLE_APP_UPDATA,
|
||||
rcsp_update_private_param_fill,
|
||||
rcsp_update_before_jump_handle);
|
||||
} else {
|
||||
rcsp_printf("SPP_APP_UPDATA\n");
|
||||
update_mode_api_v2(SPP_APP_UPDATA,
|
||||
rcsp_update_private_param_fill,
|
||||
rcsp_update_before_jump_handle);
|
||||
}
|
||||
/* if (RCSP_BLE == get_curr_device_type()) { */
|
||||
/* rcsp_printf("BLE_APP_UPDATE\n"); */
|
||||
/* update_mode_api(BLE_APP_UPDATA); */
|
||||
/* } else { */
|
||||
/* rcsp_printf("SPP_APP_UPDATA\n"); */
|
||||
/* update_mode_api(SPP_APP_UPDATA); */
|
||||
/* } */
|
||||
break;
|
||||
|
||||
case MSG_JL_ENTER_UPDATE_MODE:
|
||||
if (argc < 2) {
|
||||
rcsp_printf("err: MSG_JL_ENTER_UPDATE_MODE too few argument, argc is %d\n", argc);
|
||||
return;
|
||||
}
|
||||
rcsp_printf("MSG_JL_ENTER_UPDATE_MODE:%x %x\n", (u8)argv[0], (u8)argv[1]);
|
||||
#if(TCFG_USER_TWS_ENABLE == 1)
|
||||
void tws_cancle_all_noconn();
|
||||
tws_cancle_all_noconn();
|
||||
#endif
|
||||
user_send_cmd_prepare(USER_CTRL_WRITE_CONN_DISABLE, 0, NULL);
|
||||
user_send_cmd_prepare(USER_CTRL_WRITE_SCAN_DISABLE, 0, NULL);
|
||||
if (support_dual_bank_update_en) {
|
||||
u8 status = 0;
|
||||
JL_CMD_response_send((u8)argv[0], JL_PRO_STATUS_SUCCESS, (u8)argv[1], &status, 1);
|
||||
rcsp_update_data_api_register(rcsp_update_data_read, rcsp_update_status_response);
|
||||
register_receive_fw_update_block_handle(rcsp_update_handle);
|
||||
rcsp_update_loader_download_init(DUAL_BANK_UPDATA, rcsp_loader_download_result_handle);
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void rcsp_update_jump_for_hid_device()
|
||||
{
|
||||
if (RCSP_BLE == get_curr_device_type()) {
|
||||
rcsp_printf("BLE_APP_UPDATE\n");
|
||||
update_mode_api_v2(BLE_APP_UPDATA,
|
||||
rcsp_update_private_param_fill,
|
||||
rcsp_update_before_jump_handle);
|
||||
} else {
|
||||
rcsp_printf("SPP_APP_UPDATA\n");
|
||||
update_mode_api_v2(SPP_APP_UPDATA,
|
||||
rcsp_update_private_param_fill,
|
||||
rcsp_update_before_jump_handle);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
static u8 rcsp_update_flag = 0;
|
||||
void set_rcsp_db_update_status(u8 value)
|
||||
{
|
||||
rcsp_update_flag = value;
|
||||
}
|
||||
|
||||
u8 get_rcsp_db_update_status()
|
||||
{
|
||||
return rcsp_update_flag;
|
||||
}
|
||||
|
||||
void rcsp_before_enter_db_update_mode() //进入双备份升级前
|
||||
{
|
||||
r_printf("%s", __func__);
|
||||
rcsp_update_flag = 1;
|
||||
void sys_auto_shut_down_disable(void);
|
||||
if (get_total_connect_dev() == 0) {
|
||||
sys_auto_shut_down_disable();
|
||||
}
|
||||
#if TCFG_USER_TWS_ENABLE
|
||||
int tws_api_get_role(void);
|
||||
if (tws_api_get_role() == TWS_ROLE_SLAVE) {
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
if (get_total_connect_dev()) { //断开蓝牙连接,断开之后不能让他重新开
|
||||
/* user_send_cmd_prepare(USER_CTRL_DISCONNECTION_HCI, 0, NULL); */
|
||||
}
|
||||
#if TCFG_USER_TWS_ENABLE
|
||||
extern void tws_cancle_all_noconn();
|
||||
/* tws_cancle_all_noconn() ; */
|
||||
#else
|
||||
user_send_cmd_prepare(USER_CTRL_WRITE_SCAN_DISABLE, 0, NULL);
|
||||
user_send_cmd_prepare(USER_CTRL_WRITE_CONN_DISABLE, 0, NULL);
|
||||
#endif
|
||||
}
|
||||
|
||||
extern void sys_auto_shut_down_enable(void);
|
||||
void rcsp_db_update_fail_deal() //双备份升级失败处理
|
||||
{
|
||||
r_printf("%s", __func__);
|
||||
if (rcsp_update_flag) {
|
||||
rcsp_update_flag = 0;
|
||||
if (get_total_connect_dev() == 0) {
|
||||
sys_auto_shut_down_enable();
|
||||
}
|
||||
}
|
||||
/* cpu_reset(); //升级失败直接复位 */
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
@ -0,0 +1,25 @@
|
||||
#ifndef _RCSP_USER_UPDATE_H_
|
||||
#define _RCSP_USER_UPDATE_H_
|
||||
|
||||
//#include "rcsp_protocol.h"
|
||||
//#include "rcsp_packet.h"
|
||||
#include "typedef.h"
|
||||
|
||||
|
||||
#define JL_OPCODE_GET_DEVICE_UPDATE_FILE_INFO_OFFSET 0xe1
|
||||
#define JL_OPCODE_INQUIRE_DEVICE_IF_CAN_UPDATE 0xe2
|
||||
#define JL_OPCODE_ENTER_UPDATE_MODE 0xe3
|
||||
#define JL_OPCODE_EXIT_UPDATE_MODE 0xe4
|
||||
#define JL_OPCODE_SEND_FW_UPDATE_BLOCK 0xe5
|
||||
#define JL_OPCODE_GET_DEVICE_REFRESH_FW_STATUS 0xe6
|
||||
#define JL_OPCODE_SET_DEVICE_REBOOT 0xe7
|
||||
#define JL_OPCODE_NOTIFY_UPDATE_CONENT_SIZE 0xe8
|
||||
|
||||
void JL_rcsp_update_cmd_resp(void *priv, u8 OpCode, u8 OpCode_SN, u8 *data, u16 len);
|
||||
void JL_rcsp_update_cmd_receive_resp(void *priv, u8 OpCode, u8 status, u8 *data, u16 len);
|
||||
u8 get_jl_update_flag(void);
|
||||
void set_jl_update_flag(u8 flag);
|
||||
u8 get_curr_device_type(void);
|
||||
|
||||
#endif
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user