mirror of
https://github.com/Ralim/IronOS.git
synced 2025-02-26 07:53:55 +00:00
Scratch
This commit is contained in:
@@ -1,363 +0,0 @@
|
||||
#include "ble_lib_api.h"
|
||||
#include "bluetooth.h"
|
||||
#include "conn.h"
|
||||
#include "hci_core.h"
|
||||
#include "hci_driver.h"
|
||||
#include "byteorder.h"
|
||||
#include "log.h"
|
||||
#include "errno.h"
|
||||
|
||||
struct blhast_le_adv_data {
|
||||
u8_t ad[31];
|
||||
size_t ad_len;
|
||||
};
|
||||
|
||||
static struct bt_le_scan_param blhast_le_scan_param;
|
||||
static struct bt_le_adv_param blhast_le_adv_param;
|
||||
static struct blhast_le_adv_data blhast_le_ad;
|
||||
static struct blhast_le_adv_data blhast_le_sd;
|
||||
static bt_le_scan_cb_t *blhast_le_scan_cb;
|
||||
|
||||
static void blhast_ble_scan_assist_cb(const struct bt_le_scan_param *param, bt_le_scan_cb_t cb);
|
||||
static void blhast_ble_adv_assist_cb(const struct bt_le_adv_param *param, const struct bt_data *ad,
|
||||
size_t ad_len, const struct bt_data *sd, size_t sd_len);
|
||||
|
||||
static struct blhast_cb assist_cb = {
|
||||
.le_scan_cb = blhast_ble_scan_assist_cb,
|
||||
.le_adv_cb = blhast_ble_adv_assist_cb,
|
||||
};
|
||||
|
||||
extern struct bt_dev bt_dev;
|
||||
|
||||
static void blhast_ble_scan_assist_cb(const struct bt_le_scan_param *param, bt_le_scan_cb_t cb)
|
||||
{
|
||||
memcpy(&blhast_le_scan_param, param, sizeof(struct bt_le_scan_param));
|
||||
blhast_le_scan_cb = cb;
|
||||
}
|
||||
|
||||
static void blhast_ble_get_ad(const struct bt_data *ad, size_t ad_len, uint8_t *output)
|
||||
{
|
||||
int i;
|
||||
uint8_t data_len = 0;
|
||||
|
||||
for (i = 0; i < ad_len; i++) {
|
||||
*(output + data_len) = ad[i].type;
|
||||
data_len++;
|
||||
|
||||
*(output + data_len) = ad[i].data_len;
|
||||
data_len++;
|
||||
|
||||
memcpy(output + data_len, ad[i].data, ad[i].data_len);
|
||||
|
||||
data_len += ad[i].data_len;
|
||||
}
|
||||
}
|
||||
|
||||
static void blhast_ble_construct_ad(struct blhast_le_adv_data *adv_data, struct bt_data *output)
|
||||
{
|
||||
int i;
|
||||
size_t ad_len = adv_data->ad_len;
|
||||
u8_t *p_ad = adv_data->ad;
|
||||
|
||||
for (i = 0; i < ad_len; i++) {
|
||||
memcpy(&output[i], p_ad, 2); //type, data_len
|
||||
p_ad += 2;
|
||||
output[i].data = (const u8_t *)p_ad;
|
||||
p_ad += output[i].data_len;
|
||||
}
|
||||
}
|
||||
|
||||
static void blhast_ble_adv_assist_cb(const struct bt_le_adv_param *param, const struct bt_data *ad,
|
||||
size_t ad_len, const struct bt_data *sd, size_t sd_len)
|
||||
{
|
||||
memcpy(&blhast_le_adv_param, param, sizeof(struct bt_le_adv_param));
|
||||
|
||||
if (ad) {
|
||||
blhast_le_ad.ad_len = ad_len;
|
||||
memset(blhast_le_ad.ad, 0, sizeof(blhast_le_ad.ad));
|
||||
blhast_ble_get_ad(ad, ad_len, blhast_le_ad.ad);
|
||||
}
|
||||
|
||||
if (sd) {
|
||||
blhast_le_sd.ad_len = sd_len;
|
||||
memset(blhast_le_sd.ad, 0, sizeof(blhast_le_sd.ad));
|
||||
blhast_ble_get_ad(sd, sd_len, blhast_le_sd.ad);
|
||||
}
|
||||
}
|
||||
|
||||
static int blhast_common_reset(void)
|
||||
{
|
||||
struct net_buf *rsp;
|
||||
int err;
|
||||
|
||||
if (!(bt_dev.drv->quirks & BT_QUIRK_NO_RESET)) {
|
||||
/* Send HCI_RESET */
|
||||
err = bt_hci_cmd_send_sync(BT_HCI_OP_RESET, NULL, &rsp);
|
||||
if (err) {
|
||||
return err;
|
||||
}
|
||||
bt_hci_reset_complete(rsp);
|
||||
net_buf_unref(rsp);
|
||||
}
|
||||
|
||||
#if defined(CONFIG_BT_HCI_ACL_FLOW_CONTROL)
|
||||
err = bt_set_flow_control();
|
||||
if (err) {
|
||||
return err;
|
||||
}
|
||||
#endif /* CONFIG_BT_HCI_ACL_FLOW_CONTROL */
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int blhast_ble_reset(void)
|
||||
{
|
||||
struct bt_hci_cp_write_le_host_supp *cp_le;
|
||||
struct net_buf *buf, *rsp;
|
||||
int err;
|
||||
|
||||
if (!BT_FEAT_LE(bt_dev.features)) {
|
||||
BT_ERR("Non-LE capable controller detected!");
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
if (BT_FEAT_BREDR(bt_dev.features)) {
|
||||
buf = bt_hci_cmd_create(BT_HCI_OP_LE_WRITE_LE_HOST_SUPP,
|
||||
sizeof(*cp_le));
|
||||
if (!buf) {
|
||||
return -ENOBUFS;
|
||||
}
|
||||
|
||||
cp_le = net_buf_add(buf, sizeof(*cp_le));
|
||||
|
||||
/* Explicitly enable LE for dual-mode controllers */
|
||||
cp_le->le = 0x01;
|
||||
cp_le->simul = 0x00;
|
||||
err = bt_hci_cmd_send_sync(BT_HCI_OP_LE_WRITE_LE_HOST_SUPP, buf,
|
||||
NULL);
|
||||
if (err) {
|
||||
return err;
|
||||
}
|
||||
}
|
||||
|
||||
if (IS_ENABLED(CONFIG_BT_CONN) &&
|
||||
IS_ENABLED(CONFIG_BT_DATA_LEN_UPDATE) &&
|
||||
BT_FEAT_LE_DLE(bt_dev.le.features)) {
|
||||
struct bt_hci_cp_le_write_default_data_len *cp;
|
||||
struct bt_hci_rp_le_read_max_data_len *rp;
|
||||
u16_t tx_octets, tx_time;
|
||||
|
||||
err = bt_hci_cmd_send_sync(BT_HCI_OP_LE_READ_MAX_DATA_LEN, NULL,
|
||||
&rsp);
|
||||
if (err) {
|
||||
return err;
|
||||
}
|
||||
|
||||
rp = (void *)rsp->data;
|
||||
tx_octets = sys_le16_to_cpu(rp->max_tx_octets);
|
||||
tx_time = sys_le16_to_cpu(rp->max_tx_time);
|
||||
net_buf_unref(rsp);
|
||||
|
||||
buf = bt_hci_cmd_create(BT_HCI_OP_LE_WRITE_DEFAULT_DATA_LEN,
|
||||
sizeof(*cp));
|
||||
if (!buf) {
|
||||
return -ENOBUFS;
|
||||
}
|
||||
|
||||
cp = net_buf_add(buf, sizeof(*cp));
|
||||
cp->max_tx_octets = sys_cpu_to_le16(tx_octets);
|
||||
cp->max_tx_time = sys_cpu_to_le16(tx_time);
|
||||
|
||||
err = bt_hci_cmd_send_sync(BT_HCI_OP_LE_WRITE_DEFAULT_DATA_LEN,
|
||||
buf, NULL);
|
||||
if (err) {
|
||||
return err;
|
||||
}
|
||||
}
|
||||
|
||||
return bt_le_set_event_mask();
|
||||
}
|
||||
|
||||
#if defined(CONFIG_BT_BREDR)
|
||||
static int blhast_br_reset(void)
|
||||
{
|
||||
struct net_buf *buf;
|
||||
struct bt_hci_cp_write_ssp_mode *ssp_cp;
|
||||
struct bt_hci_cp_write_inquiry_mode *inq_cp;
|
||||
struct bt_hci_write_local_name *name_cp;
|
||||
int err;
|
||||
|
||||
/* Set SSP mode */
|
||||
buf = bt_hci_cmd_create(BT_HCI_OP_WRITE_SSP_MODE, sizeof(*ssp_cp));
|
||||
if (!buf) {
|
||||
return -ENOBUFS;
|
||||
}
|
||||
|
||||
ssp_cp = net_buf_add(buf, sizeof(*ssp_cp));
|
||||
ssp_cp->mode = 0x01;
|
||||
err = bt_hci_cmd_send_sync(BT_HCI_OP_WRITE_SSP_MODE, buf, NULL);
|
||||
if (err) {
|
||||
return err;
|
||||
}
|
||||
|
||||
/* Enable Inquiry results with RSSI or extended Inquiry */
|
||||
buf = bt_hci_cmd_create(BT_HCI_OP_WRITE_INQUIRY_MODE, sizeof(*inq_cp));
|
||||
if (!buf) {
|
||||
return -ENOBUFS;
|
||||
}
|
||||
|
||||
inq_cp = net_buf_add(buf, sizeof(*inq_cp));
|
||||
inq_cp->mode = 0x02;
|
||||
err = bt_hci_cmd_send_sync(BT_HCI_OP_WRITE_INQUIRY_MODE, buf, NULL);
|
||||
if (err) {
|
||||
return err;
|
||||
}
|
||||
|
||||
/* Set local name */
|
||||
buf = bt_hci_cmd_create(BT_HCI_OP_WRITE_LOCAL_NAME, sizeof(*name_cp));
|
||||
if (!buf) {
|
||||
return -ENOBUFS;
|
||||
}
|
||||
|
||||
name_cp = net_buf_add(buf, sizeof(*name_cp));
|
||||
strncpy((char *)name_cp->local_name, CONFIG_BT_DEVICE_NAME,
|
||||
sizeof(name_cp->local_name));
|
||||
|
||||
err = bt_hci_cmd_send_sync(BT_HCI_OP_WRITE_LOCAL_NAME, buf, NULL);
|
||||
if (err) {
|
||||
return err;
|
||||
}
|
||||
|
||||
/* Set page timeout*/
|
||||
buf = bt_hci_cmd_create(BT_HCI_OP_WRITE_PAGE_TIMEOUT, sizeof(u16_t));
|
||||
if (!buf) {
|
||||
return -ENOBUFS;
|
||||
}
|
||||
|
||||
net_buf_add_le16(buf, CONFIG_BT_PAGE_TIMEOUT);
|
||||
|
||||
err = bt_hci_cmd_send_sync(BT_HCI_OP_WRITE_PAGE_TIMEOUT, buf, NULL);
|
||||
if (err) {
|
||||
return err;
|
||||
}
|
||||
|
||||
/* Enable BR/EDR SC if supported */
|
||||
if (BT_FEAT_SC(bt_dev.features)) {
|
||||
struct bt_hci_cp_write_sc_host_supp *sc_cp;
|
||||
|
||||
buf = bt_hci_cmd_create(BT_HCI_OP_WRITE_SC_HOST_SUPP,
|
||||
sizeof(*sc_cp));
|
||||
if (!buf) {
|
||||
return -ENOBUFS;
|
||||
}
|
||||
|
||||
sc_cp = net_buf_add(buf, sizeof(*sc_cp));
|
||||
sc_cp->sc_support = 0x01;
|
||||
|
||||
err = bt_hci_cmd_send_sync(BT_HCI_OP_WRITE_SC_HOST_SUPP, buf,
|
||||
NULL);
|
||||
if (err) {
|
||||
return err;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
static int blhast_host_hci_reset(void)
|
||||
{
|
||||
int err;
|
||||
ATOMIC_DEFINE(old_flags, BT_DEV_NUM_FLAGS);
|
||||
memcpy(old_flags, bt_dev.flags, sizeof(old_flags));
|
||||
|
||||
err = blhast_common_reset();
|
||||
|
||||
if (err) {
|
||||
return err;
|
||||
}
|
||||
|
||||
err = blhast_ble_reset();
|
||||
if (err) {
|
||||
return err;
|
||||
}
|
||||
|
||||
#if defined(CONFIG_BT_BREDR)
|
||||
if (BT_FEAT_BREDR(bt_dev.features)) {
|
||||
err = blhast_br_reset();
|
||||
if (err) {
|
||||
return err;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
err = bt_set_event_mask();
|
||||
if (err) {
|
||||
return err;
|
||||
}
|
||||
|
||||
memcpy(bt_dev.flags, old_flags, sizeof(old_flags));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void blhast_host_state_restore(void)
|
||||
{
|
||||
struct bt_data *ad = NULL;
|
||||
struct bt_data *sd = NULL;
|
||||
k_sem_give(&bt_dev.ncmd_sem);
|
||||
net_buf_unref(bt_dev.sent_cmd);
|
||||
bt_dev.sent_cmd = NULL;
|
||||
|
||||
blhast_host_hci_reset();
|
||||
|
||||
#if defined(CONFIG_BT_CONN)
|
||||
bt_notify_disconnected();
|
||||
#endif
|
||||
|
||||
atomic_set_bit(bt_dev.flags, BT_DEV_ASSIST_RUN);
|
||||
|
||||
#if defined(CONFIG_BT_OBSERVER)
|
||||
if (atomic_test_bit(bt_dev.flags, BT_DEV_EXPLICIT_SCAN)) {
|
||||
BT_WARN("Restore BLE scan\r\n");
|
||||
atomic_clear_bit(bt_dev.flags, BT_DEV_EXPLICIT_SCAN);
|
||||
atomic_clear_bit(bt_dev.flags, BT_DEV_SCANNING);
|
||||
bt_le_scan_start((const struct bt_le_scan_param *)&blhast_le_scan_param, blhast_le_scan_cb);
|
||||
}
|
||||
#endif
|
||||
|
||||
if (atomic_test_and_clear_bit(bt_dev.flags, BT_DEV_ADVERTISING)) {
|
||||
BT_WARN("Restore BLE advertising\r\n");
|
||||
if (blhast_le_ad.ad_len > 0) {
|
||||
ad = k_malloc(sizeof(struct bt_data) * blhast_le_ad.ad_len);
|
||||
blhast_ble_construct_ad(&blhast_le_ad, ad);
|
||||
}
|
||||
if (blhast_le_sd.ad_len > 0) {
|
||||
sd = k_malloc(sizeof(struct bt_data) * blhast_le_sd.ad_len);
|
||||
blhast_ble_construct_ad(&blhast_le_sd, sd);
|
||||
}
|
||||
|
||||
bt_le_adv_start((const struct bt_le_adv_param *)&blhast_le_adv_param, ad,
|
||||
blhast_le_ad.ad_len, sd, blhast_le_sd.ad_len);
|
||||
|
||||
if (ad)
|
||||
k_free(ad);
|
||||
if (sd)
|
||||
k_free(sd);
|
||||
}
|
||||
|
||||
atomic_clear_bit(bt_dev.flags, BT_DEV_ASSIST_RUN);
|
||||
}
|
||||
|
||||
void blhast_bt_reset(void)
|
||||
{
|
||||
ble_controller_reset();
|
||||
blhast_host_state_restore();
|
||||
}
|
||||
|
||||
void blhast_init(void)
|
||||
{
|
||||
memset(&blhast_le_ad, 0, sizeof(struct blhast_le_adv_data));
|
||||
memset(&blhast_le_sd, 0, sizeof(struct blhast_le_adv_data));
|
||||
bt_register_host_assist_cb(&assist_cb);
|
||||
}
|
||||
@@ -35,7 +35,7 @@
|
||||
#include "att_internal.h"
|
||||
#include "gatt_internal.h"
|
||||
#if defined(BFLB_BLE)
|
||||
#include "config.h"
|
||||
#include "ble_config.h"
|
||||
|
||||
extern struct k_sem g_poll_sem;
|
||||
#endif
|
||||
|
||||
@@ -30,7 +30,7 @@
|
||||
#include <gatt.h>
|
||||
#include <hci_driver.h>
|
||||
#if defined(BFLB_BLE)
|
||||
#include "config.h"
|
||||
#include "ble_config.h"
|
||||
#include <util.h>
|
||||
#endif
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -26,7 +26,7 @@
|
||||
#include "conn_internal.h"
|
||||
#include "l2cap_internal.h"
|
||||
|
||||
#include "config.h"
|
||||
#include "ble_config.h"
|
||||
|
||||
#define LE_CHAN_RTX(_w) CONTAINER_OF(_w, struct bt_l2cap_le_chan, chan.rtx_work)
|
||||
#define CHAN_RX(_w) CONTAINER_OF(_w, struct bt_l2cap_le_chan, rx_work)
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
*/
|
||||
|
||||
#include <zephyr.h>
|
||||
#include <ble_config.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
#include <atomic.h>
|
||||
|
||||
@@ -14,7 +14,6 @@ NOTES
|
||||
#include <stdlib.h>
|
||||
#include <FreeRTOS.h>
|
||||
#include <task.h>
|
||||
#include <blog.h>
|
||||
|
||||
#include "bluetooth.h"
|
||||
#include "conn.h"
|
||||
|
||||
@@ -1,625 +0,0 @@
|
||||
#include <stdbool.h>
|
||||
#include <string.h>
|
||||
#include <net/buf.h>
|
||||
#include "oad_service.h"
|
||||
#include "oad.h"
|
||||
#include "oad_main.h"
|
||||
#ifdef CONFIG_BT_SETTINGS
|
||||
#include "settings.h"
|
||||
#include "ef_def.h"
|
||||
#endif
|
||||
#include "conn_internal.h"
|
||||
#if !defined(CONFIG_BL_MCU_SDK)
|
||||
#include "hal_boot2.h"
|
||||
#include "bl_flash.h"
|
||||
#include "bl_sys.h"
|
||||
#include "hosal_ota.h"
|
||||
#include "bl702_common.h"
|
||||
#include "hal_sys.h"
|
||||
#else
|
||||
#include "partition.h"
|
||||
#include "hal_flash.h"
|
||||
#include "errno.h"
|
||||
#include "bl702_glb.h"
|
||||
#include "mbedtls/sha256.h"
|
||||
#endif
|
||||
#include "log.h"
|
||||
#include "bl702.h"
|
||||
#include "softcrc.h"
|
||||
#if defined(CONFIG_BL_MCU_SDK)
|
||||
#define BL_SDK_VER "1.00"
|
||||
#define BOOT2_PARTITION_ADDR (0x4202DC00)
|
||||
#endif //CONFIG_BL_MCU_SDK
|
||||
|
||||
#define OTA_WRITE_FLASH_SIZE (256 * 16)
|
||||
#define WBUF_SIZE(CON) (OTA_WRITE_FLASH_SIZE + bt_gatt_get_mtu(CON))
|
||||
#define UPGRD_TIMEOUT K_SECONDS(2)
|
||||
|
||||
static app_check_oad_cb app_check_cb = NULL;
|
||||
struct oad_env_tag oad_env;
|
||||
|
||||
struct wflash_data_t {
|
||||
u8_t *wdata_buf;
|
||||
u16_t index;
|
||||
} __packed;
|
||||
|
||||
static struct wflash_data_t wData;
|
||||
|
||||
#if defined(CONFIG_BL_MCU_SDK)
|
||||
static int hal_boot2_partition_addr_inactive(const char *name, uint32_t *addr, uint32_t *size);
|
||||
static int hal_boot2_get_active_entries_byname(u8_t *name, pt_table_entry_config *ptEntry_hal);
|
||||
static int hal_boot2_update_ptable(pt_table_entry_config *ptEntry_hal);
|
||||
static int fw_check_hash256(void);
|
||||
#endif
|
||||
static bool check_data_valid(struct oad_file_info *file_info)
|
||||
{
|
||||
if (file_info->manu_code != oad_env.file_info.manu_code || file_info->file_ver != oad_env.upgrd_file_ver)
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static void oad_notify_image_info(struct bt_conn *conn)
|
||||
{
|
||||
u8_t *buf = (u8_t *)k_malloc(sizeof(u8_t) * 256);
|
||||
u8_t index = 0;
|
||||
char *build_date = __DATE__;
|
||||
char *build_time = __TIME__;
|
||||
char *build_ver = BL_SDK_VER;
|
||||
|
||||
if (buf) {
|
||||
memset(buf, 0, 256);
|
||||
} else {
|
||||
BT_WARN("Buffer allocation failed\r\n");
|
||||
return;
|
||||
}
|
||||
buf[index++] = OAD_CMD_IMAG_INFO;
|
||||
if (strlen(build_date) + index <= 256) {
|
||||
buf[index] = strlen(build_date);
|
||||
memcpy(&buf[++index], build_date, strlen(build_date));
|
||||
index += strlen(build_date);
|
||||
} else {
|
||||
BT_WARN("No enough space\r\n");
|
||||
}
|
||||
if (strlen(build_time) + index <= 256) {
|
||||
buf[index] = strlen(build_time);
|
||||
memcpy(&buf[++index], build_time, strlen(build_time));
|
||||
index += strlen(build_time);
|
||||
} else {
|
||||
BT_WARN("No enough space\r\n");
|
||||
}
|
||||
|
||||
if (strlen(build_ver) + index <= 256) {
|
||||
buf[index] = strlen(build_ver);
|
||||
memcpy(&buf[++index], build_ver, strlen(build_ver));
|
||||
index += strlen(build_ver);
|
||||
} else {
|
||||
BT_WARN("No enough space\r\n");
|
||||
}
|
||||
BT_WARN("Info:%s,%s,%s\r\n", build_date, build_time, build_ver);
|
||||
BT_WARN("Send:%s\r\n", bt_hex(buf, index));
|
||||
bt_oad_notify(conn, buf, index);
|
||||
k_free(buf);
|
||||
}
|
||||
|
||||
static void oad_notify_block_req(struct bt_conn *conn)
|
||||
{
|
||||
struct net_buf_simple *buf = NET_BUF_SIMPLE(sizeof(struct oad_block_req_t) + OAD_OPCODE_SIZE);
|
||||
struct oad_block_req_t *block_req;
|
||||
|
||||
net_buf_simple_init(buf, 0);
|
||||
*(buf->data) = OAD_CMD_IMAG_BLOCK_REQ;
|
||||
block_req = (struct oad_block_req_t *)(buf->data + 1);
|
||||
buf->len = sizeof(struct oad_block_req_t) + OAD_OPCODE_SIZE;
|
||||
|
||||
block_req->file_info.file_ver = oad_env.upgrd_file_ver;
|
||||
block_req->file_info.manu_code = oad_env.file_info.manu_code;
|
||||
block_req->file_offset = oad_env.upgrd_offset;
|
||||
|
||||
bt_oad_notify(conn, buf->data, buf->len);
|
||||
}
|
||||
|
||||
static void oad_notify_upgrd_end(struct bt_conn *conn, u8_t status)
|
||||
{
|
||||
struct net_buf_simple *buf = NET_BUF_SIMPLE(sizeof(struct oad_upgrd_end_t) + OAD_OPCODE_SIZE);
|
||||
struct oad_upgrd_end_t *upgrd_end;
|
||||
|
||||
if (status == OAD_SUCC) {
|
||||
BT_WARN("Submit upgrade work\r\n");
|
||||
#if !defined(CONFIG_BL_MCU_SDK)
|
||||
if (!hosal_ota_finish(1, 0))
|
||||
#else
|
||||
if (!fw_check_hash256())
|
||||
#endif
|
||||
k_delayed_work_submit(&oad_env.upgrd_work, UPGRD_TIMEOUT);
|
||||
else {
|
||||
BT_WARN("Hash256 check failed");
|
||||
status = OAD_CHECK_HASH256_FAIL;
|
||||
}
|
||||
}
|
||||
|
||||
net_buf_simple_init(buf, 0);
|
||||
*(buf->data) = OAD_CMD_IMAG_UPGRD_END;
|
||||
upgrd_end = (struct oad_upgrd_end_t *)(buf->data + 1);
|
||||
buf->len = sizeof(struct oad_upgrd_end_t) + OAD_OPCODE_SIZE;
|
||||
upgrd_end->file_info.file_ver = oad_env.upgrd_file_ver;
|
||||
upgrd_end->file_info.manu_code = oad_env.file_info.manu_code;
|
||||
upgrd_end->status = status;
|
||||
|
||||
bt_oad_notify(conn, buf->data, buf->len);
|
||||
}
|
||||
|
||||
static void oad_notity_image_identity(struct bt_conn *conn)
|
||||
{
|
||||
struct net_buf_simple *buf = NET_BUF_SIMPLE(sizeof(struct oad_image_identity_t));
|
||||
struct oad_image_identity_t *identity;
|
||||
|
||||
net_buf_simple_init(buf, 0);
|
||||
*(buf->data) = OAD_CMD_IMAG_IDENTITY;
|
||||
identity = (void *)(buf->data + 1);
|
||||
buf->len = sizeof(struct oad_image_identity_t) + OAD_OPCODE_SIZE;
|
||||
|
||||
identity->file_info.file_ver = oad_env.file_info.file_ver;
|
||||
identity->file_info.manu_code = oad_env.file_info.manu_code;
|
||||
identity->file_size = oad_env.cur_file_size;
|
||||
identity->crc32 = 0;
|
||||
|
||||
bt_oad_notify(conn, buf->data, buf->len);
|
||||
}
|
||||
|
||||
void ota_finish(struct k_work *work)
|
||||
{
|
||||
BT_WARN("oad_upgrade\r\n");
|
||||
oad_env.file_info.file_ver = oad_env.upgrd_file_ver;
|
||||
|
||||
#if defined(CONFIG_BT_SETTINGS)
|
||||
struct oad_ef_info ef_info;
|
||||
memset(&ef_info, 0, sizeof(struct oad_ef_info));
|
||||
bt_settings_set_bin(NV_IMG_info, (uint8_t *)&ef_info, sizeof(struct oad_ef_info));
|
||||
#endif
|
||||
|
||||
#if defined(CONFIG_BL_MCU_SDK)
|
||||
GLB_SW_System_Reset();
|
||||
#else
|
||||
hal_reboot();
|
||||
#endif
|
||||
}
|
||||
|
||||
static u8_t oad_write_flash(uint32_t filesize, uint32_t offset, u8_t *data, u16_t len)
|
||||
{
|
||||
#if defined(CONFIG_BL_MCU_SDK)
|
||||
uint32_t size = 0;
|
||||
uint32_t wflash_address = 0;
|
||||
|
||||
if (!oad_env.new_img_addr) {
|
||||
if (hal_boot2_partition_addr_inactive("FW", (uint32_t *)&oad_env.new_img_addr, &size)) {
|
||||
BT_WARN("New img address is null\r\n");
|
||||
return OAD_ABORT;
|
||||
}
|
||||
|
||||
BT_WARN("Upgrade file size is %d\r\n", oad_env.upgrd_file_size);
|
||||
if (oad_env.upgrd_file_size <= size) {
|
||||
BT_WARN("flash erase\r\n");
|
||||
flash_erase(oad_env.new_img_addr, oad_env.upgrd_file_size);
|
||||
} else {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
BT_WARN("upgrd_offset is 0x%x len (%d)\r\n", oad_env.upgrd_offset, len);
|
||||
|
||||
if (oad_env.w_img_end_addr <= oad_env.new_img_addr && !oad_env.w_img_end_addr) {
|
||||
wflash_address = oad_env.new_img_addr;
|
||||
} else if (oad_env.w_img_end_addr) {
|
||||
wflash_address = oad_env.w_img_end_addr;
|
||||
} else {
|
||||
BT_WARN("Write flash address invalid\r\n");
|
||||
}
|
||||
|
||||
BT_WARN("Start address : 0x%x\r\n", wflash_address);
|
||||
flash_write(wflash_address, data, len);
|
||||
oad_env.w_img_end_addr = wflash_address + len;
|
||||
BT_WARN("End address : 0x%x\r\n", wflash_address + len);
|
||||
#else
|
||||
hosal_ota_update(filesize, offset, data, len);
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static u8_t oad_image_data_handler(struct bt_conn *conn, const u8_t *data, u16_t len)
|
||||
{
|
||||
u16_t left_size = 0;
|
||||
u16_t oDataLen = 0;
|
||||
static u32_t write_count = 0;
|
||||
|
||||
if (!wData.wdata_buf) {
|
||||
wData.wdata_buf = (u8_t *)k_malloc(WBUF_SIZE(conn));
|
||||
if (!wData.wdata_buf) {
|
||||
BT_WARN("Buf is NULL\r\n");
|
||||
return OAD_ABORT;
|
||||
};
|
||||
memset(wData.wdata_buf, 0, WBUF_SIZE(conn));
|
||||
wData.index = 0;
|
||||
}
|
||||
|
||||
if (wData.wdata_buf) {
|
||||
left_size = /*WBUF_SIZE(conn)*/ OTA_WRITE_FLASH_SIZE - wData.index;
|
||||
BT_WARN("left_size (0x%x) wData.index (0x%x) len (%d)\r\n", left_size, wData.index, len);
|
||||
if (left_size >= len) {
|
||||
memcpy((wData.wdata_buf + wData.index), data, len);
|
||||
wData.index += len;
|
||||
|
||||
} else {
|
||||
oDataLen = len - left_size;
|
||||
memcpy((wData.wdata_buf + wData.index), data, left_size);
|
||||
wData.index += left_size;
|
||||
if (wData.index == OTA_WRITE_FLASH_SIZE) {
|
||||
if (oad_write_flash(oad_env.upgrd_file_size, oad_env.hosal_offset, wData.wdata_buf, OTA_WRITE_FLASH_SIZE)) {
|
||||
BT_ERR("Failed to write flash\r\n");
|
||||
return OAD_ABORT;
|
||||
}
|
||||
} else {
|
||||
BT_ERR("Unexpect result\r\n");
|
||||
return OAD_ABORT;
|
||||
}
|
||||
|
||||
write_count += 1;
|
||||
oad_env.hosal_offset = write_count * OTA_WRITE_FLASH_SIZE;
|
||||
#if defined(CONFIG_BT_SETTINGS)
|
||||
struct oad_ef_info ef_info;
|
||||
memcpy(&ef_info.file_info, &oad_env.file_info, sizeof(struct oad_file_info));
|
||||
ef_info.file_offset = write_count * OTA_WRITE_FLASH_SIZE;
|
||||
ef_info.last_wflash_addr = oad_env.w_img_end_addr;
|
||||
ef_info.upgrd_crc32 = oad_env.upgrd_crc32;
|
||||
|
||||
bt_settings_set_bin(NV_IMG_info, (uint8_t *)&ef_info, sizeof(struct oad_ef_info));
|
||||
BT_WARN("ef_info: file ver(%d) manu code(0x%x) file offset(0x%x) last_adder (0x%x)\r\n", ef_info.file_info.file_ver, ef_info.file_info.manu_code,
|
||||
ef_info.file_offset, ef_info.last_wflash_addr);
|
||||
#endif
|
||||
wData.index = 0;
|
||||
memcpy((wData.wdata_buf + wData.index), (data + left_size), oDataLen);
|
||||
wData.index += oDataLen;
|
||||
}
|
||||
}
|
||||
|
||||
oad_env.upgrd_offset += len;
|
||||
if (oad_env.upgrd_offset > oad_env.upgrd_file_size) {
|
||||
return OAD_INVALID_IMAG;
|
||||
} else if (oad_env.upgrd_offset == oad_env.upgrd_file_size) {
|
||||
if (wData.index) {
|
||||
oad_write_flash(oad_env.upgrd_file_size, oad_env.hosal_offset, wData.wdata_buf, wData.index);
|
||||
}
|
||||
|
||||
if (wData.wdata_buf) {
|
||||
k_free(wData.wdata_buf);
|
||||
wData.wdata_buf = NULL;
|
||||
}
|
||||
|
||||
return OAD_UPGRD_CMPLT;
|
||||
} else {
|
||||
return OAD_REQ_MORE_DATA;
|
||||
}
|
||||
}
|
||||
|
||||
static void oad_image_info_handler(struct bt_conn *conn, const u8_t *data, u16_t len)
|
||||
{
|
||||
oad_notify_image_info(conn);
|
||||
}
|
||||
|
||||
static u8_t oad_image_block_resp_handler(struct bt_conn *conn, const u8_t *data, u16_t len)
|
||||
{
|
||||
struct oad_block_rsp_t *block_rsp;
|
||||
const u8_t *rsp_data;
|
||||
u8_t status = OAD_SUCC;
|
||||
|
||||
switch (*data) {
|
||||
case OAD_SUCC: {
|
||||
block_rsp = (struct oad_block_rsp_t *)data;
|
||||
if (!check_data_valid(&block_rsp->file_info)) {
|
||||
status = OAD_INVALID_IMAG;
|
||||
break;
|
||||
}
|
||||
|
||||
if (block_rsp->file_offset != oad_env.upgrd_offset) {
|
||||
status = OAD_MALORMED_CMD;
|
||||
break;
|
||||
}
|
||||
|
||||
rsp_data = data + OAD_BLK_RSP_DATA_OFFSET;
|
||||
status = oad_image_data_handler(conn, rsp_data, block_rsp->data_size);
|
||||
if (status == OAD_UPGRD_CMPLT) {
|
||||
oad_notify_upgrd_end(conn, OAD_SUCC);
|
||||
} else if (status == OAD_REQ_MORE_DATA) {
|
||||
oad_notify_block_req(conn);
|
||||
} else {
|
||||
oad_notify_upgrd_end(conn, status);
|
||||
}
|
||||
} break;
|
||||
case OAD_ABORT: {
|
||||
#if !defined(CONFIG_BL_MCU_SDK)
|
||||
bl_flash_erase(oad_env.new_img_addr, oad_env.upgrd_file_size);
|
||||
#else
|
||||
flash_erase(oad_env.new_img_addr, oad_env.upgrd_file_size);
|
||||
#endif
|
||||
} break;
|
||||
|
||||
default:
|
||||
status = OAD_MALORMED_CMD;
|
||||
}
|
||||
return status;
|
||||
}
|
||||
|
||||
static void oad_image_identity_handler(struct bt_conn *conn, const u8_t *data, u16_t len)
|
||||
{
|
||||
struct bt_le_conn_param conn_param;
|
||||
struct oad_image_identity_t *identity = (struct oad_image_identity_t *)(data);
|
||||
int err = 0;
|
||||
|
||||
BT_WARN("File size=[0x%x] [0x%x] [0x%x] [0x%x]\r\n", identity->file_size, identity->file_info.file_ver,
|
||||
identity->file_info.manu_code, identity->crc32);
|
||||
#if defined(CONFIG_BT_SETTINGS)
|
||||
size_t llen = 0;
|
||||
struct oad_ef_info ef_info;
|
||||
|
||||
memset(&ef_info, 0, sizeof(struct oad_ef_info));
|
||||
bt_settings_get_bin(NV_IMG_info, (uint8_t *)&ef_info, sizeof(struct oad_ef_info), &llen);
|
||||
BT_WARN("ef_info: file ver(%d) manu code(0x%x) file offset(0x%x) last_adder (0x%x)\r\n", ef_info.file_info.file_ver, ef_info.file_info.manu_code,
|
||||
ef_info.file_offset, ef_info.last_wflash_addr);
|
||||
#else
|
||||
oad_env.new_img_addr = 0;
|
||||
oad_env.w_img_end_addr = 0;
|
||||
#endif
|
||||
|
||||
if (identity->file_info.manu_code == oad_env.file_info.manu_code &&
|
||||
(app_check_cb)(oad_env.file_info.file_ver, identity->file_info.file_ver)) {
|
||||
#if defined(CONFIG_BT_SETTINGS)
|
||||
if (identity->crc32 && ef_info.upgrd_crc32 == identity->crc32) {
|
||||
if (ef_info.file_offset && ef_info.file_offset <= identity->file_size) {
|
||||
oad_env.upgrd_offset = ef_info.file_offset;
|
||||
}
|
||||
|
||||
oad_env.new_img_addr = ef_info.last_wflash_addr;
|
||||
|
||||
} else
|
||||
#endif
|
||||
{
|
||||
oad_env.upgrd_offset = 0x00;
|
||||
}
|
||||
|
||||
conn_param.interval_max = 6;
|
||||
conn_param.interval_min = 6;
|
||||
conn_param.latency = 0;
|
||||
conn_param.timeout = 500; //5s
|
||||
err = bt_conn_le_param_update(conn, &conn_param);
|
||||
if (err)
|
||||
BT_WARN("fail to start conn update\r\n");
|
||||
else
|
||||
BT_WARN("start conn update\r\n");
|
||||
|
||||
oad_env.upgrd_file_ver = identity->file_info.file_ver;
|
||||
oad_env.upgrd_file_size = identity->file_size;
|
||||
oad_env.upgrd_crc32 = identity->crc32;
|
||||
BT_WARN("Send the image block request\r\n");
|
||||
#if !defined(CONFIG_BL_MCU_SDK)
|
||||
hosal_ota_start(oad_env.upgrd_file_size);
|
||||
#endif
|
||||
oad_notify_block_req(conn);
|
||||
} else {
|
||||
oad_notity_image_identity(conn);
|
||||
}
|
||||
}
|
||||
|
||||
static void oad_recv_callback(struct bt_conn *conn, const u8_t *data, u16_t len)
|
||||
{
|
||||
if (len) {
|
||||
if (*data == OAD_CMD_IMAG_IDENTITY && ((len - 1) == sizeof(struct oad_image_identity_t))) {
|
||||
oad_image_identity_handler(conn, data + 1, len - 1);
|
||||
}
|
||||
if (*data == OAD_CMD_IMAG_BLOCK_RESP) {
|
||||
oad_image_block_resp_handler(conn, data + 1, len - 1);
|
||||
}
|
||||
if (*data == OAD_CMD_IMAG_INFO) {
|
||||
oad_image_info_handler(conn, data + 1, len - 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void oad_disc_callback(struct bt_conn *conn, u8_t reason)
|
||||
{
|
||||
if (wData.wdata_buf) {
|
||||
k_free(wData.wdata_buf);
|
||||
wData.wdata_buf = NULL;
|
||||
wData.index = 0;
|
||||
}
|
||||
}
|
||||
#if defined(CONFIG_BL_MCU_SDK)
|
||||
static struct {
|
||||
u8_t partition_active_idx;
|
||||
u8_t pad[3];
|
||||
pt_table_stuff_config table;
|
||||
} boot2_partition_table;
|
||||
|
||||
//#define PARTITION_MAGIC (0x54504642)
|
||||
|
||||
pt_table_id_type active_id = PT_TABLE_ID_INVALID;
|
||||
pt_table_stuff_config pt_table_stuff[2];
|
||||
|
||||
static int fw_check_hash256(void)
|
||||
{
|
||||
uint32_t bin_size;
|
||||
uint32_t hash_addr;
|
||||
pt_table_entry_config ptEntry;
|
||||
|
||||
if (oad_env.upgrd_file_size <= 32) {
|
||||
return -1;
|
||||
}
|
||||
if (oad_env.w_img_end_addr <= 32) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
bin_size = oad_env.upgrd_file_size - 32;
|
||||
hash_addr = oad_env.w_img_end_addr - 32;
|
||||
|
||||
if (hal_boot2_get_active_entries_byname((uint8_t *)"FW", &ptEntry)) {
|
||||
BT_WARN("Failed to get active entries by name\r\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
#define CHECK_IMG_BUF_SIZE 512
|
||||
uint8_t sha_check[32] = { 0 };
|
||||
uint8_t dst_sha[32] = { 0 };
|
||||
uint32_t read_size;
|
||||
mbedtls_sha256_context sha256_ctx;
|
||||
int i, offset = 0;
|
||||
uint8_t r_buf[CHECK_IMG_BUF_SIZE];
|
||||
|
||||
BT_WARN("[OTA]prepare OTA partition info\r\n");
|
||||
mbedtls_sha256_init(&sha256_ctx);
|
||||
mbedtls_sha256_starts_ret(&sha256_ctx, 0);
|
||||
|
||||
memset(sha_check, 0, 32);
|
||||
memset(dst_sha, 0, 32);
|
||||
offset = 0;
|
||||
while (offset < bin_size) {
|
||||
(bin_size - offset >= CHECK_IMG_BUF_SIZE) ? (read_size = CHECK_IMG_BUF_SIZE) : (read_size = bin_size - offset);
|
||||
if (flash_read(oad_env.new_img_addr + offset, r_buf, read_size)) {
|
||||
BT_WARN("flash read failed \r\n");
|
||||
return -1;
|
||||
}
|
||||
mbedtls_sha256_update_ret(&sha256_ctx, (const uint8_t *)r_buf, read_size);
|
||||
offset += read_size;
|
||||
}
|
||||
|
||||
mbedtls_sha256_finish_ret(&sha256_ctx, sha_check);
|
||||
|
||||
flash_read(hash_addr, dst_sha, 32);
|
||||
for (i = 0; i < 32; i++) {
|
||||
BT_WARN("%02X", dst_sha[i]);
|
||||
}
|
||||
puts("\r\nHeader SET SHA256 Checksum:");
|
||||
for (i = 0; i < 32; i++) {
|
||||
BT_WARN("%02X", sha_check[i]);
|
||||
}
|
||||
|
||||
if (memcmp(sha_check, (const void *)dst_sha, 32) != 0) {
|
||||
BT_WARN("sha256 check error\r\n");
|
||||
return -1;
|
||||
}
|
||||
ptEntry.len = bin_size;
|
||||
BT_WARN("[OTA] Update PARTITION, partition len is %lu\r\n", ptEntry.len);
|
||||
hal_boot2_update_ptable(&ptEntry);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int oad_hal_boot2_partition_addr(const char *name, uint32_t *addr0, uint32_t *addr1, uint32_t *size0, uint32_t *size1, int *active)
|
||||
{
|
||||
int i;
|
||||
|
||||
if (BFLB_PT_MAGIC_CODE != boot2_partition_table.table.pt_table.magicCode) {
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
/*Get Target partition*/
|
||||
for (i = 0; i < boot2_partition_table.table.pt_table.entryCnt; i++) {
|
||||
if (0 == strcmp((char *)&(boot2_partition_table.table.pt_entries[i].name[0]), name)) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (boot2_partition_table.table.pt_table.entryCnt == i) {
|
||||
return -ENOENT;
|
||||
}
|
||||
*addr0 = boot2_partition_table.table.pt_entries[i].start_address[0];
|
||||
*addr1 = boot2_partition_table.table.pt_entries[i].start_address[1];
|
||||
*size0 = boot2_partition_table.table.pt_entries[i].max_len[0];
|
||||
*size1 = boot2_partition_table.table.pt_entries[i].max_len[1];
|
||||
*active = boot2_partition_table.table.pt_entries[i].active_index;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int hal_boot2_partition_addr_inactive(const char *name, uint32_t *addr, uint32_t *size)
|
||||
{
|
||||
uint32_t addr0, addr1;
|
||||
uint32_t size0, size1;
|
||||
int active, ret;
|
||||
|
||||
if ((ret = oad_hal_boot2_partition_addr(name, &addr0, &addr1, &size0, &size1, &active))) {
|
||||
return ret;
|
||||
}
|
||||
*addr = active ? addr0 : addr1;
|
||||
*size = active ? size0 : size1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static pt_table_error_type oad_PtTable_Get_Active_Entries_By_Name(pt_table_stuff_config *ptStuff,
|
||||
u8_t *name,
|
||||
pt_table_entry_config *ptEntry)
|
||||
{
|
||||
uint32_t i = 0;
|
||||
uint32_t len = strlen((char *)name);
|
||||
|
||||
if (ptStuff == NULL || ptEntry == NULL) {
|
||||
return PT_ERROR_PARAMETER;
|
||||
}
|
||||
for (i = 0; i < ptStuff->pt_table.entryCnt; i++) {
|
||||
if (strlen((char *)ptStuff->pt_entries[i].name) == len &&
|
||||
memcmp((char *)ptStuff->pt_entries[i].name, (char *)name, len) == 0) {
|
||||
ARCH_MemCpy_Fast(ptEntry, &ptStuff->pt_entries[i], sizeof(pt_table_entry_config));
|
||||
return PT_ERROR_SUCCESS;
|
||||
}
|
||||
}
|
||||
return PT_ERROR_ENTRY_NOT_FOUND;
|
||||
}
|
||||
|
||||
static int hal_boot2_update_ptable(pt_table_entry_config *ptEntry_hal)
|
||||
{
|
||||
int ret;
|
||||
//FIXME force covert
|
||||
pt_table_entry_config *ptEntry = (pt_table_entry_config *)ptEntry_hal;
|
||||
|
||||
ptEntry->active_index = !ptEntry->active_index;
|
||||
(ptEntry->age)++;
|
||||
ret = pt_table_update_entry((pt_table_id_type)(!active_id), &pt_table_stuff[!active_id], ptEntry);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int hal_boot2_get_active_entries_byname(uint8_t *name, pt_table_entry_config *ptEntry_hal)
|
||||
{
|
||||
pt_table_entry_config *ptEntry = (pt_table_entry_config *)ptEntry_hal;
|
||||
if (oad_PtTable_Get_Active_Entries_By_Name(&boot2_partition_table.table, name, ptEntry)) {
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int oad_get_boot2_partition_table(void)
|
||||
{
|
||||
memcpy(&boot2_partition_table.table, &pt_table_stuff[active_id], sizeof(pt_table_stuff_config));
|
||||
boot2_partition_table.partition_active_idx = active_id;
|
||||
BT_WARN("magicCode: 0x%x\r\n", boot2_partition_table.table.pt_table.magicCode);
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
void oad_service_enable(app_check_oad_cb cb)
|
||||
{
|
||||
//todo: get current file info for oad_env.fileinfo
|
||||
|
||||
app_check_cb = cb;
|
||||
oad_env.file_info.file_ver = LOCAL_FILE_VER;
|
||||
oad_env.file_info.manu_code = LOCAL_MANU_CODE;
|
||||
oad_env.new_img_addr = 0;
|
||||
bt_oad_service_enable();
|
||||
bt_oad_register_recv_cb(oad_recv_callback);
|
||||
bt_oad_register_disc_cb(oad_disc_callback);
|
||||
|
||||
#if defined(CONFIG_BL_MCU_SDK)
|
||||
flash_init();
|
||||
pt_table_set_flash_operation(flash_erase, flash_write, flash_read);
|
||||
active_id = pt_table_get_active_partition_need_lock(pt_table_stuff);
|
||||
oad_get_boot2_partition_table();
|
||||
#endif
|
||||
k_delayed_work_init(&oad_env.upgrd_work, ota_finish);
|
||||
}
|
||||
@@ -22,7 +22,7 @@ NOTES
|
||||
#include "uuid.h"
|
||||
#include "ble_peripheral_tp_server.h"
|
||||
#include "log.h"
|
||||
|
||||
#include "bl702_glb.h"
|
||||
static void ble_tp_connected(struct bt_conn *conn, u8_t err);
|
||||
static void ble_tp_disconnected(struct bt_conn *conn, u8_t reason);
|
||||
|
||||
|
||||
352
source/Core/BSP/Pinecilv2/ble_peripheral_tp_server.c
Normal file
352
source/Core/BSP/Pinecilv2/ble_peripheral_tp_server.c
Normal file
@@ -0,0 +1,352 @@
|
||||
/****************************************************************************
|
||||
FILE NAME
|
||||
ble_peripheral_tp_server.c
|
||||
|
||||
DESCRIPTION
|
||||
test profile demo
|
||||
|
||||
NOTES
|
||||
*/
|
||||
/****************************************************************************/
|
||||
|
||||
#include <errno.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdlib.h>
|
||||
#include <FreeRTOS.h>
|
||||
#include <task.h>
|
||||
|
||||
#include "bluetooth.h"
|
||||
#include "conn.h"
|
||||
#include "gatt.h"
|
||||
#include "hci_core.h"
|
||||
#include "uuid.h"
|
||||
#include "ble_peripheral_tp_server.h"
|
||||
#include "log.h"
|
||||
#include "hal_clock.h"
|
||||
|
||||
extern bool pds_start;
|
||||
|
||||
static void ble_tp_connected(struct bt_conn *conn, u8_t err);
|
||||
static void ble_tp_disconnected(struct bt_conn *conn, u8_t reason);
|
||||
static void ble_param_updated(struct bt_conn *conn, u16_t interval, u16_t latency, u16_t timeout);
|
||||
|
||||
static struct bt_conn *ble_tp_conn;
|
||||
#if !defined(CONFIG_BT_OAD_SERVER)
|
||||
static struct bt_gatt_exchange_params exchg_mtu;
|
||||
#endif
|
||||
static TaskHandle_t ble_tp_task_h;
|
||||
|
||||
static struct k_sem notify_poll_sem;
|
||||
|
||||
static int tx_mtu_size = 20;
|
||||
static u8_t created_tp_task = 0;
|
||||
static u8_t isRegister = 0;
|
||||
|
||||
static struct bt_conn_cb ble_tp_conn_callbacks = {
|
||||
.connected = ble_tp_connected,
|
||||
.disconnected = ble_tp_disconnected,
|
||||
.le_param_updated = ble_param_updated,
|
||||
};
|
||||
|
||||
#if !defined(CONFIG_BT_OAD_SERVER)
|
||||
/*************************************************************************
|
||||
NAME
|
||||
ble_tp_tx_mtu_size
|
||||
*/
|
||||
static void ble_tp_tx_mtu_size(struct bt_conn *conn, u8_t err,
|
||||
struct bt_gatt_exchange_params *params)
|
||||
{
|
||||
if (!err) {
|
||||
tx_mtu_size = bt_gatt_get_mtu(ble_tp_conn);
|
||||
BT_WARN("ble tp echange mtu size success, mtu size: %d", tx_mtu_size);
|
||||
} else {
|
||||
BT_WARN("ble tp echange mtu size failure, err: %d", err);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
/*************************************************************************
|
||||
NAME
|
||||
ble_tp_connected
|
||||
*/
|
||||
static void ble_tp_connected(struct bt_conn *conn, u8_t err)
|
||||
{
|
||||
#if !defined(CONFIG_BT_OAD_SERVER)
|
||||
int tx_octets = 0x00fb;
|
||||
int tx_time = 0x0848;
|
||||
int ret = -1;
|
||||
#endif
|
||||
|
||||
#if XTAL_32K_TYPE == EXTERNAL_XTAL_32K
|
||||
struct bt_le_conn_param param;
|
||||
#endif
|
||||
|
||||
if (err) {
|
||||
return;
|
||||
}
|
||||
|
||||
BT_WARN("Tp connected");
|
||||
ble_tp_conn = conn;
|
||||
pds_start = false;
|
||||
|
||||
#if XTAL_32K_TYPE == EXTERNAL_XTAL_32K
|
||||
param.interval_min = param.interval_max = 0x320;
|
||||
param.latency = 0;
|
||||
param.timeout = 0x05dc;
|
||||
ret = bt_conn_le_param_update(ble_tp_conn, ¶m);
|
||||
if (ret) {
|
||||
BT_WARN("conn update failed (err %d)\r\n", ret);
|
||||
} else {
|
||||
BT_WARN("conn update initiated\r\n");
|
||||
}
|
||||
#endif
|
||||
|
||||
#if !defined(CONFIG_BT_OAD_SERVER)
|
||||
//set data length after connected.
|
||||
ret = bt_le_set_data_len(ble_tp_conn, tx_octets, tx_time);
|
||||
|
||||
if (!ret) {
|
||||
BT_WARN("ble tp set data length success");
|
||||
} else {
|
||||
BT_WARN("ble tp set data length failure, err: %d", ret);
|
||||
}
|
||||
|
||||
//exchange mtu size after connected.
|
||||
exchg_mtu.func = ble_tp_tx_mtu_size;
|
||||
ret = bt_gatt_exchange_mtu(ble_tp_conn, &exchg_mtu);
|
||||
|
||||
if (!ret) {
|
||||
BT_WARN("ble tp exchange mtu size pending");
|
||||
} else {
|
||||
BT_WARN("ble tp exchange mtu size failure, err: %d", ret);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
/*************************************************************************
|
||||
NAME
|
||||
ble_tp_disconnected
|
||||
*/
|
||||
static void ble_tp_disconnected(struct bt_conn *conn, u8_t reason)
|
||||
{
|
||||
BT_WARN("Tp disconnected");
|
||||
|
||||
if (created_tp_task) {
|
||||
BT_WARN("Delete throughput tx task");
|
||||
vTaskDelete(ble_tp_task_h);
|
||||
created_tp_task = 0;
|
||||
}
|
||||
|
||||
ble_tp_conn = NULL;
|
||||
extern int ble_start_adv(void);
|
||||
ble_start_adv();
|
||||
pds_start = true;
|
||||
}
|
||||
|
||||
/*************************************************************************
|
||||
NAME
|
||||
ble_param_updated
|
||||
*/
|
||||
|
||||
static void ble_param_updated(struct bt_conn *conn, u16_t interval,
|
||||
u16_t latency, u16_t timeout)
|
||||
{
|
||||
BT_WARN("LE conn param updated: int 0x%04x lat %d to %d \r\n", interval, latency, timeout);
|
||||
#if XTAL_32K_TYPE == EXTERNAL_XTAL_32K
|
||||
if (interval > 80) {
|
||||
pds_start = true;
|
||||
} else {
|
||||
pds_start = false;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
/*************************************************************************
|
||||
NAME
|
||||
ble_tp_recv_rd
|
||||
*/
|
||||
static int ble_tp_recv_rd(struct bt_conn *conn, const struct bt_gatt_attr *attr,
|
||||
void *buf, u16_t len, u16_t offset)
|
||||
{
|
||||
int size = 9;
|
||||
char data[9] = { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09 };
|
||||
|
||||
memcpy(buf, data, size);
|
||||
|
||||
return size;
|
||||
}
|
||||
|
||||
/*************************************************************************
|
||||
NAME
|
||||
ble_tp_recv_wr(receive data from client)
|
||||
*/
|
||||
static int ble_tp_recv_wr(struct bt_conn *conn, const struct bt_gatt_attr *attr,
|
||||
const void *buf, u16_t len, u16_t offset, u8_t flags)
|
||||
{
|
||||
BT_WARN("recv data len=%d, offset=%d, flag=%d", len, offset, flags);
|
||||
BT_WARN("recv data:%s", bt_hex(buf, len));
|
||||
|
||||
if (flags & BT_GATT_WRITE_FLAG_PREPARE) {
|
||||
//Don't use prepare write data, execute write will upload data again.
|
||||
BT_WARN("recv prepare write request");
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (flags & BT_GATT_WRITE_FLAG_CMD) {
|
||||
//Use write command data.
|
||||
BT_WARN("recv write command");
|
||||
} else {
|
||||
//Use write request / execute write data.
|
||||
BT_WARN("recv write request / exce write");
|
||||
}
|
||||
|
||||
k_sem_give(¬ify_poll_sem);
|
||||
return len;
|
||||
}
|
||||
|
||||
/*************************************************************************
|
||||
NAME
|
||||
indicate_rsp /bl_tp_send_indicate
|
||||
*/
|
||||
|
||||
static void indicate_rsp(struct bt_conn *conn, const struct bt_gatt_attr *attr, u8_t err)
|
||||
{
|
||||
BT_WARN("receive comfirmation, err:%d", err);
|
||||
}
|
||||
|
||||
static int bl_tp_send_indicate(struct bt_conn *conn, const struct bt_gatt_attr *attr,
|
||||
const void *data, u16_t len)
|
||||
{
|
||||
static struct bt_gatt_indicate_params ind_params;
|
||||
|
||||
ind_params.attr = attr;
|
||||
ind_params.data = data;
|
||||
ind_params.len = len;
|
||||
ind_params.func = indicate_rsp;
|
||||
ind_params.uuid = NULL;
|
||||
|
||||
return bt_gatt_indicate(conn, &ind_params);
|
||||
}
|
||||
|
||||
/*************************************************************************
|
||||
NAME
|
||||
ble_tp_ind_ccc_changed
|
||||
*/
|
||||
static void ble_tp_ind_ccc_changed(const struct bt_gatt_attr *attr, u16_t value)
|
||||
{
|
||||
int err = -1;
|
||||
char data[9] = { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09 };
|
||||
|
||||
if (value == BT_GATT_CCC_INDICATE) {
|
||||
err = bl_tp_send_indicate(ble_tp_conn, get_attr(BT_CHAR_BLE_TP_IND_ATTR_VAL_INDEX), data, 9);
|
||||
BT_WARN("ble tp send indatcate: %d", err);
|
||||
}
|
||||
}
|
||||
|
||||
/*************************************************************************
|
||||
NAME
|
||||
ble_tp_notify(send data to client)
|
||||
*/
|
||||
static void ble_tp_notify_task(void *pvParameters)
|
||||
{
|
||||
int err = -1;
|
||||
u8_t data[244] = { 0x01 };
|
||||
k_sem_give(¬ify_poll_sem);
|
||||
|
||||
while (1) {
|
||||
k_sem_take(¬ify_poll_sem, K_FOREVER);
|
||||
//send data to client
|
||||
err = bt_gatt_notify(ble_tp_conn, get_attr(BT_CHAR_BLE_TP_NOT_ATTR_VAL_INDEX), data, (tx_mtu_size - 3));
|
||||
data[0] = data[0] + 1;
|
||||
BT_WARN("ble tp send notify : %d", err);
|
||||
}
|
||||
}
|
||||
|
||||
/*************************************************************************
|
||||
NAME
|
||||
ble_tp_not_ccc_changed
|
||||
*/
|
||||
static void ble_tp_notify_ccc_changed(const struct bt_gatt_attr *attr, u16_t value)
|
||||
{
|
||||
BT_WARN("ccc:value=[%d]", value);
|
||||
|
||||
if (value == BT_GATT_CCC_NOTIFY) {
|
||||
if (xTaskCreate(ble_tp_notify_task, (char *)"bletp", 512, NULL, 15, &ble_tp_task_h) == pdPASS) {
|
||||
created_tp_task = 1;
|
||||
BT_WARN("Create throughput tx task success");
|
||||
} else {
|
||||
created_tp_task = 0;
|
||||
BT_WARN("Create throughput tx taskfail");
|
||||
}
|
||||
} else {
|
||||
if (created_tp_task) {
|
||||
BT_WARN("Delete throughput tx task");
|
||||
vTaskDelete(ble_tp_task_h);
|
||||
created_tp_task = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*************************************************************************
|
||||
* DEFINE : attrs
|
||||
*/
|
||||
static struct bt_gatt_attr attrs[] = {
|
||||
BT_GATT_PRIMARY_SERVICE(BT_UUID_SVC_BLE_TP),
|
||||
|
||||
BT_GATT_CHARACTERISTIC(BT_UUID_CHAR_BLE_TP_RD,
|
||||
BT_GATT_CHRC_READ,
|
||||
BT_GATT_PERM_READ,
|
||||
ble_tp_recv_rd,
|
||||
NULL,
|
||||
NULL),
|
||||
|
||||
BT_GATT_CHARACTERISTIC(BT_UUID_CHAR_BLE_TP_WR,
|
||||
BT_GATT_CHRC_WRITE | BT_GATT_CHRC_WRITE_WITHOUT_RESP,
|
||||
BT_GATT_PERM_WRITE | BT_GATT_PERM_PREPARE_WRITE,
|
||||
NULL,
|
||||
ble_tp_recv_wr,
|
||||
NULL),
|
||||
|
||||
BT_GATT_CHARACTERISTIC(BT_UUID_CHAR_BLE_TP_IND,
|
||||
BT_GATT_CHRC_INDICATE,
|
||||
0,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL),
|
||||
|
||||
BT_GATT_CCC(ble_tp_ind_ccc_changed, BT_GATT_PERM_READ | BT_GATT_PERM_WRITE),
|
||||
|
||||
BT_GATT_CHARACTERISTIC(BT_UUID_CHAR_BLE_TP_NOT,
|
||||
BT_GATT_CHRC_NOTIFY,
|
||||
0,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL),
|
||||
|
||||
BT_GATT_CCC(ble_tp_notify_ccc_changed, BT_GATT_PERM_READ | BT_GATT_PERM_WRITE)
|
||||
|
||||
};
|
||||
|
||||
/*************************************************************************
|
||||
NAME
|
||||
get_attr
|
||||
*/
|
||||
struct bt_gatt_attr *get_attr(u8_t index)
|
||||
{
|
||||
return &attrs[index];
|
||||
}
|
||||
|
||||
static struct bt_gatt_service ble_tp_server = BT_GATT_SERVICE(attrs);
|
||||
|
||||
/*************************************************************************
|
||||
NAME
|
||||
ble_tp_init
|
||||
*/
|
||||
void ble_tp_init()
|
||||
{
|
||||
if (!isRegister) {
|
||||
isRegister = 1;
|
||||
bt_conn_cb_register(&ble_tp_conn_callbacks);
|
||||
bt_gatt_service_register(&ble_tp_server);
|
||||
k_sem_init(¬ify_poll_sem, 0, 1);
|
||||
}
|
||||
}
|
||||
38
source/Core/BSP/Pinecilv2/ble_peripheral_tp_server.h
Normal file
38
source/Core/BSP/Pinecilv2/ble_peripheral_tp_server.h
Normal file
@@ -0,0 +1,38 @@
|
||||
/****************************************************************************
|
||||
FILE NAME
|
||||
ble_peripheral_tp_server.h
|
||||
|
||||
DESCRIPTION
|
||||
NOTES
|
||||
*/
|
||||
/****************************************************************************/
|
||||
|
||||
#ifndef _BLE_TP_SVC_H_
|
||||
#define _BLE_TP_SVC_H_
|
||||
|
||||
#include "ble_config.h"
|
||||
|
||||
//07af27a5-9c22-11ea-9afe-02fcdc4e7412
|
||||
#define BT_UUID_SVC_BLE_TP BT_UUID_DECLARE_128(BT_UUID_128_ENCODE(0x07af27a5, 0x9c22, 0x11ea, 0x9afe, 0x02fcdc4e7412))
|
||||
//07af27a6-9c22-11ea-9afe-02fcdc4e7412
|
||||
#define BT_UUID_CHAR_BLE_TP_RD BT_UUID_DECLARE_128(BT_UUID_128_ENCODE(0x07af27a6, 0x9c22, 0x11ea, 0x9afe, 0x02fcdc4e7412))
|
||||
//07af27a7-9c22-11ea-9afe-02fcdc4e7412
|
||||
#define BT_UUID_CHAR_BLE_TP_WR BT_UUID_DECLARE_128(BT_UUID_128_ENCODE(0x07af27a7, 0x9c22, 0x11ea, 0x9afe, 0x02fcdc4e7412))
|
||||
//07af27a8-9c22-11ea-9afe-02fcdc4e7412
|
||||
#define BT_UUID_CHAR_BLE_TP_IND BT_UUID_DECLARE_128(BT_UUID_128_ENCODE(0x07af27a8, 0x9c22, 0x11ea, 0x9afe, 0x02fcdc4e7412))
|
||||
//07af27a9-9c22-11ea-9afe-02fcdc4e7412
|
||||
#define BT_UUID_CHAR_BLE_TP_NOT BT_UUID_DECLARE_128(BT_UUID_128_ENCODE(0x07af27a9, 0x9c22, 0x11ea, 0x9afe, 0x02fcdc4e7412))
|
||||
|
||||
//read value handle offset 2
|
||||
#define BT_CHAR_BLE_TP_RD_ATTR_VAL_INDEX (2)
|
||||
//write value handle offset 4
|
||||
#define BT_CHAR_BLE_TP_WR_ATTR_VAL_INDEX (4)
|
||||
//indicate value handle offset 6
|
||||
#define BT_CHAR_BLE_TP_IND_ATTR_VAL_INDEX (6)
|
||||
//notity value handle offset 9
|
||||
#define BT_CHAR_BLE_TP_NOT_ATTR_VAL_INDEX (9)
|
||||
|
||||
void ble_tp_init();
|
||||
struct bt_gatt_attr *get_attr(u8_t index);
|
||||
|
||||
#endif
|
||||
Reference in New Issue
Block a user