两份 使用比较工具阅读 指导修改点
原理
https://www.cnblogs.com/suoloveyou/archive/2012/04/25/2470292.html
方案是在服务中 这个版本是做bool的
源码
typedef struct
{
ble_nus_c_evt_handler_t evt_handler;
} ble_nus_c_init_t;
struct ble_nus_c_s
{
uint8_t uuid_type; /**< UUID type. */
uint16_t conn_handle; /**< Handle of the current connection. Set with @ref ble_nus_c_handles_assign when connected. */
ble_nus_c_handles_t handles; /**< Handles on the connected peer device needed to interact with it. */
ble_nus_c_evt_handler_t evt_handler; /**< Application event handler to be called when there is an event related to the NUS. */
};
static void nus_c_init(void)
{
ret_code_t err_code;
ble_nus_c_init_t init;
init.evt_handler = ble_nus_c_evt_handler;
for (uint32_t i = 0; i < NRF_SDH_BLE_CENTRAL_LINK_COUNT; i++)
{
err_code = ble_nus_c_init(&m_ble_nus_c[i], &init);
APP_ERROR_CHECK(err_code);
}
}
uint32_t ble_nus_c_init(ble_nus_c_t * p_ble_nus_c, ble_nus_c_init_t * p_ble_nus_c_init)
{
p_ble_nus_c->conn_handle = BLE_CONN_HANDLE_INVALID;
p_ble_nus_c->orcode = p_ble_nus_c_init->orcode;
p_ble_nus_c->evt_handler = p_ble_nus_c_init->evt_handler;
p_ble_nus_c->handles.nus_tx_handle = BLE_GATT_HANDLE_INVALID;
p_ble_nus_c->handles.nus_rx_handle = BLE_GATT_HANDLE_INVALID;
return ble_db_discovery_evt_register(&uart_uuid);
}
此时orcode已经到了每一个nus里面
后面处理ble_nus_c_evt_handler三次交互 就在里面可以使用orcode的
那么设置在哪里
就在第一次 的ble_nus_c_handles_assign
你认真看三次交互的流程
第一次发现完成-给RTC-使能
case BLE_NUS_C_EVT_DISCOVERY_COMPLETE:
err_code = ble_nus_c_handles_assign(p_ble_nus_c, p_ble_nus_evt->conn_handle, &p_ble_nus_evt->handles);
第二次收到数据-给出返回
case BLE_NUS_C_EVT_NUS_TX_EVT:
第三次断开
case BLE_NUS_C_EVT_DISCONNECTED:
在这里做赋值
uint32_t ble_nus_c_handles_assign(ble_nus_c_t * p_ble_nus,
uint16_t conn_handle,
ble_nus_c_handles_t const * p_peer_handles)
{
VERIFY_PARAM_NOT_NULL(p_ble_nus);
p_ble_nus->conn_handle = conn_handle;
if (p_peer_handles != NULL)
{
p_ble_nus->handles.nus_tx_cccd_handle = p_peer_handles->nus_tx_cccd_handle;
p_ble_nus->handles.nus_tx_handle = p_peer_handles->nus_tx_handle;
p_ble_nus->handles.nus_rx_handle = p_peer_handles->nus_rx_handle;
}
NRF_LOG_DEBUG("ble_nus_c_handles_assign %04x:%04x:%04x:%04x",\
p_ble_nus->conn_handle,\
p_ble_nus->handles.nus_tx_cccd_handle,\
p_ble_nus->handles.nus_tx_handle,\
p_ble_nus->handles.nus_rx_handle);
return NRF_SUCCESS;
}
typedef struct
{
uint16_t nus_tx_handle; /**< Handle of the NUS TX characteristic as provided by a discovery. */
uint16_t nus_tx_cccd_handle; /**< Handle of the CCCD of the NUS TX characteristic as provided by a discovery. */
uint16_t nus_rx_handle; /**< Handle of the NUS RX characteristic as provided by a discovery. */
} ble_nus_c_handles_t;
前面就是发现的时候的赋值
ble_nus_c_on_db_disc_evt
void ble_nus_c_on_db_disc_evt(ble_nus_c_t * p_ble_nus_c, ble_db_discovery_evt_t * p_evt)
{
ble_nus_c_evt_t nus_c_evt;
memset(&nus_c_evt,0,sizeof(ble_nus_c_evt_t));
ble_gatt_db_char_t * p_chars = p_evt->params.discovered_db.charateristics;
// Check if the NUS was discovered.
if ( (p_evt->evt_type == BLE_DB_DISCOVERY_COMPLETE)
&& (p_evt->params.discovered_db.srv_uuid.uuid == BLE_UUID_NUS_SERVICE)
&& (p_evt->params.discovered_db.srv_uuid.type == p_ble_nus_c->uuid_type))
{
for (uint32_t i = 0; i < p_evt->params.discovered_db.char_count; i++)
{
switch (p_chars[i].characteristic.uuid.uuid)
{
case BLE_UUID_NUS_RX_CHARACTERISTIC:
nus_c_evt.handles.nus_rx_handle = p_chars[i].characteristic.handle_value;
break;
case BLE_UUID_NUS_TX_CHARACTERISTIC:
nus_c_evt.handles.nus_tx_handle = p_chars[i].characteristic.handle_value;
nus_c_evt.handles.nus_tx_cccd_handle = p_chars[i].cccd_handle;
break;
default:
break;
}
}
if (p_ble_nus_c->evt_handler != NULL)
{
nus_c_evt.conn_handle = p_evt->conn_handle;
nus_c_evt.evt_type = BLE_NUS_C_EVT_DISCOVERY_COMPLETE;
p_ble_nus_c->evt_handler(p_ble_nus_c, &nus_c_evt);
}
}
}
#define BLE_UUID_NUS_SERVICE 0x0001 /**< The UUID of the Nordic UART Service. */
#define BLE_UUID_NUS_RX_CHARACTERISTIC 0x0002 /**< The UUID of the RX Characteristic. */
#define BLE_UUID_NUS_TX_CHARACTERISTIC 0x0003 /**< The UUID of the TX Characteristic. */
NRF_LOG_INFO("[BLE-EVENT]: New data ??%d??",p_ble_nus_c->orcode);
新码
typedef struct
{
ble_nus_c_evt_handler_t evt_handler;
uint8_t orcode;
} ble_nus_c_init_t;
struct ble_nus_c_s
{
uint8_t uuid_type; /**< UUID type. */
uint8_t orcode;
uint16_t conn_handle; /**< Handle of the current connection. Set with @ref ble_nus_c_handles_assign when connected. */
ble_nus_c_handles_t handles; /**< Handles on the connected peer device needed to interact with it. */
ble_nus_c_evt_handler_t evt_handler; /**< Application event handler to be called when there is an event related to the NUS. */
};
static void nus_c_init(void)
{
ret_code_t err_code;
ble_nus_c_init_t init;
init.evt_handler = ble_nus_c_evt_handler;
init.orcode = 0;
for (uint32_t i = 0; i < NRF_SDH_BLE_CENTRAL_LINK_COUNT; i++)
{
err_code = ble_nus_c_init(&m_ble_nus_c[i], &init);
APP_ERROR_CHECK(err_code);
}
}
uint32_t ble_nus_c_init(ble_nus_c_t * p_ble_nus_c, ble_nus_c_init_t * p_ble_nus_c_init)
{
p_ble_nus_c->conn_handle = BLE_CONN_HANDLE_INVALID;
p_ble_nus_c->orcode = p_ble_nus_c_init->orcode;
p_ble_nus_c->evt_handler = p_ble_nus_c_init->evt_handler;
p_ble_nus_c->handles.nus_tx_handle = BLE_GATT_HANDLE_INVALID;
p_ble_nus_c->handles.nus_rx_handle = BLE_GATT_HANDLE_INVALID;
return ble_db_discovery_evt_register(&uart_uuid);
}
uint32_t ble_nus_c_handles_assign(ble_nus_c_t * p_ble_nus,
uint16_t conn_handle,
ble_nus_c_handles_t const * p_peer_handles)
{
VERIFY_PARAM_NOT_NULL(p_ble_nus);
p_ble_nus->conn_handle = conn_handle;
if (p_peer_handles != NULL)
{
p_ble_nus->orcode = p_peer_handles->nus_code_handle;
p_ble_nus->handles.nus_tx_cccd_handle = p_peer_handles->nus_tx_cccd_handle;
p_ble_nus->handles.nus_tx_handle = p_peer_handles->nus_tx_handle;
p_ble_nus->handles.nus_rx_handle = p_peer_handles->nus_rx_handle;
}
NRF_LOG_DEBUG("ble_nus_c_handles_assign %04x:%04x:%04x:%04x",\
p_ble_nus->conn_handle,\
p_ble_nus->handles.nus_tx_cccd_handle,\
p_ble_nus->handles.nus_tx_handle,\
p_ble_nus->handles.nus_rx_handle,\
p_ble_nus->orcode);
return NRF_SUCCESS;
}
typedef struct
{
uint16_t nus_tx_handle; /**< Handle of the NUS TX characteristic as provided by a discovery. */
uint16_t nus_tx_cccd_handle; /**< Handle of the CCCD of the NUS TX characteristic as provided by a discovery. */
uint16_t nus_rx_handle; /**< Handle of the NUS RX characteristic as provided by a discovery. */
uint16_t nus_code_handle;
} ble_nus_c_handles_t;
void ble_nus_c_on_db_disc_evt(ble_nus_c_t * p_ble_nus_c, ble_db_discovery_evt_t * p_evt)
{
ble_nus_c_evt_t nus_c_evt;
memset(&nus_c_evt,0,sizeof(ble_nus_c_evt_t));
ble_gatt_db_char_t * p_chars = p_evt->params.discovered_db.charateristics;
// Check if the NUS was discovered.
if ( (p_evt->evt_type == BLE_DB_DISCOVERY_COMPLETE)
&& (p_evt->params.discovered_db.srv_uuid.uuid == BLE_UUID_NUS_SERVICE)
&& (p_evt->params.discovered_db.srv_uuid.type == p_ble_nus_c->uuid_type))
{
NRF_LOG_ERROR("char_count=%d\r\n", p_evt->params.discovered_db.char_count);
for (uint32_t i = 0; i < p_evt->params.discovered_db.char_count; i++)
{
switch (p_chars[i].characteristic.uuid.uuid)
{
case BLE_UUID_NUS_RX_CHARACTERISTIC:
nus_c_evt.handles.nus_rx_handle = p_chars[i].characteristic.handle_value;
break;
case BLE_UUID_NUS_TX_CHARACTERISTIC:
nus_c_evt.handles.nus_tx_handle = p_chars[i].characteristic.handle_value;
nus_c_evt.handles.nus_tx_cccd_handle = p_chars[i].cccd_handle;
break;
case BLE_UUID_NUS_CODE_CHARACTERISTIC:
nus_c_evt.handles.nus_code_handle = 1;
break;
default:
break;
}
NRF_LOG_ERROR("[%d]-%[%4x]\r\n", i,p_chars[i].characteristic.handle_value);
}
if (p_ble_nus_c->evt_handler != NULL)
{
nus_c_evt.conn_handle = p_evt->conn_handle;
nus_c_evt.evt_type = BLE_NUS_C_EVT_DISCOVERY_COMPLETE;
p_ble_nus_c->evt_handler(p_ble_nus_c, &nus_c_evt);
}
}
}
#define BLE_UUID_NUS_SERVICE 0x0001 /**< The UUID of the Nordic UART Service. */
#define BLE_UUID_NUS_RX_CHARACTERISTIC 0x0002 /**< The UUID of the RX Characteristic. */
#define BLE_UUID_NUS_TX_CHARACTERISTIC 0x0003 /**< The UUID of the TX Characteristic. */
#define BLE_UUID_NUS_CODE_CHARACTERISTIC 0x0004 /**< The UUID of the TX Characteristic. */
在修改dialog的代码
\DA145xx_SDK_for_handover\DA145xx_SDK\old\projects\Izar\src\Node_Dialog_DA14531_SHENNONG\inc\custom_profile\user_custs1_def.h
源码
#define DEF_SVC1_UUID_128 {0x9E, 0xCA, 0xDC, 0x24, 0x0E, 0xE5, 0xA9, 0xE0, 0x93, 0xF3, 0xA3, 0xB5, 0x01, 0x00, 0x40, 0x6E}
#define DEF_SVC1_RX_CTRL_UUID_128 {0x9E, 0xCA, 0xDC, 0x24, 0x0E, 0xE5, 0xA9, 0xE0, 0x93, 0xF3, 0xA3, 0xB5, 0x02, 0x00, 0x40, 0x6E}
#define DEF_SVC1_TX_CTRL_UUID_128 {0x9E, 0xCA, 0xDC, 0x24, 0x0E, 0xE5, 0xA9, 0xE0, 0x93, 0xF3, 0xA3, 0xB5, 0x03, 0x00, 0x40, 0x6E}
enum
{
// Custom Service 1
SVC1_IDX_SVC = 0,
SVC1_IDX_RX_CTRL_CHAR,
SVC1_IDX_RX_CONTROL_VAL,
//SVC1_IDX_RX_CONTROL_USER_DESC,
SVC1_IDX_TX_CTRL_CHAR,
SVC1_IDX_TX_CTRL_VAL,
SVC1_IDX_TX_CTRL_NTF_CFG,
SVC1_IDX_TX_CTRL_USER_DESC,
CUSTS1_IDX_NB
};
/// Full CUSTS1 Database Description - Used to add attributes into the database
const struct attm_desc_128 custs1_att_db[CUSTS1_IDX_NB] =
{
// Service 1 Declaration
[SVC1_IDX_SVC] = {(uint8_t*)&att_decl_svc, ATT_UUID_128_LEN, PERM(RD, ENABLE),
sizeof(custs1_svc1), sizeof(custs1_svc1), (uint8_t*)&custs1_svc1},
// Control Point Characteristic Declaration
[SVC1_IDX_RX_CTRL_CHAR] = {(uint8_t*)&att_decl_char, ATT_UUID_16_LEN, PERM(RD, ENABLE),
0, 0, NULL},
// Control Point Characteristic Value
#if 0
[SVC1_IDX_RX_CONTROL_VAL] = {SVC1_RX_CTRL_UUID_128, ATT_UUID_128_LEN, PERM(WR, ENABLE) | PERM(WRITE_REQ, ENABLE),
DEF_SVC1_RX_CTRL_CHAR_LEN, 0, NULL},
#else
[SVC1_IDX_RX_CONTROL_VAL] = {SVC1_RX_CTRL_UUID_128, ATT_UUID_128_LEN, PERM(WR, ENABLE) | PERM(WRITE_REQ, ENABLE) | PERM(WRITE_COMMAND, ENABLE),
DEF_SVC1_RX_CTRL_CHAR_LEN, 0, NULL},
#endif
// Control Point Characteristic User Description
#if 0
[SVC1_IDX_RX_CONTROL_USER_DESC] = {(uint8_t*)&att_desc_user_desc, ATT_UUID_16_LEN, PERM(RD, ENABLE),
sizeof(DEF_SVC1_RX_CTRL_USER_DESC) - 1, sizeof(DEF_SVC1_RX_CTRL_USER_DESC) - 1,
(uint8_t *) DEF_SVC1_RX_CTRL_USER_DESC},
#endif
// ADC Value 1 Characteristic Declaration
[SVC1_IDX_TX_CTRL_CHAR] = {(uint8_t*)&att_decl_char, ATT_UUID_16_LEN, PERM(RD, ENABLE),
//[SVC1_IDX_TX_CTRL_CHAR] = {(uint8_t*)&att_dec2_char, ATT_UUID_16_LEN, PERM(RD, ENABLE),
0, 0, NULL},
// ADC Value 1 Characteristic Value
[SVC1_IDX_TX_CTRL_VAL] = {SVC1_TX_CTRL_UUID_128, ATT_UUID_128_LEN, PERM(RD, ENABLE) | PERM(NTF, ENABLE),
DEF_SVC1_TX_CTRL_CHAR_LEN, 0, NULL},
// ADC Value 1 Client Characteristic Configuration Descriptor
[SVC1_IDX_TX_CTRL_NTF_CFG] = {(uint8_t*)&att_desc_cfg, ATT_UUID_16_LEN, PERM(RD, ENABLE) | PERM(WR, ENABLE) | PERM(WRITE_REQ, ENABLE),
sizeof(uint16_t), 0, NULL},
// ADC Value 1 Characteristic User Description
[SVC1_IDX_TX_CTRL_USER_DESC] = {(uint8_t*)&att_desc_user_desc, ATT_UUID_16_LEN, PERM(RD, ENABLE),
sizeof(DEF_SVC1_TX_CTRL_USER_DESC) - 1, sizeof(DEF_SVC1_TX_CTRL_USER_DESC) - 1,
(uint8_t *) DEF_SVC1_TX_CTRL_USER_DESC},
};
新码
#define DEF_SVC1_UUID_128 {0x9E, 0xCA, 0xDC, 0x24, 0x0E, 0xE5, 0xA9, 0xE0, 0x93, 0xF3, 0xA3, 0xB5, 0x01, 0x00, 0x40, 0x6E}
#define DEF_SVC1_RX_CTRL_UUID_128 {0x9E, 0xCA, 0xDC, 0x24, 0x0E, 0xE5, 0xA9, 0xE0, 0x93, 0xF3, 0xA3, 0xB5, 0x02, 0x00, 0x40, 0x6E}
#define DEF_SVC1_TX_CTRL_UUID_128 {0x9E, 0xCA, 0xDC, 0x24, 0x0E, 0xE5, 0xA9, 0xE0, 0x93, 0xF3, 0xA3, 0xB5, 0x03, 0x00, 0x40, 0x6E}
#define DEF_SVC1_CODE_UUID_128 {0x9E, 0xCA, 0xDC, 0x24, 0x0E, 0xE5, 0xA9, 0xE0, 0x93, 0xF3, 0xA3, 0xB5, 0x04, 0x00, 0x40, 0x6E}
enum
{
// Custom Service 1
SVC1_IDX_SVC = 0,
SVC1_IDX_RX_CTRL_CHAR,
SVC1_IDX_RX_CONTROL_VAL,
//SVC1_IDX_RX_CONTROL_USER_DESC,
SVC1_IDX_TX_CTRL_CHAR,
SVC1_IDX_TX_CTRL_VAL,
SVC1_IDX_TX_CTRL_NTF_CFG,
SVC1_IDX_TX_CTRL_USER_DESC,
SVC1_IDX_CODE_CHAR,
SVC1_IDX_CODE_VAL,
CUSTS1_IDX_NB
};
static const uint8_t SVC1_CODE_UUID_128[ATT_UUID_128_LEN] = DEF_SVC1_CODE_UUID_128;
/// Full CUSTS1 Database Description - Used to add attributes into the database
const struct attm_desc_128 custs1_att_db[CUSTS1_IDX_NB] =
{
// Service 1 Declaration
[SVC1_IDX_SVC] = {(uint8_t*)&att_decl_svc, ATT_UUID_128_LEN, PERM(RD, ENABLE),
sizeof(custs1_svc1), sizeof(custs1_svc1), (uint8_t*)&custs1_svc1},
// Control Point Characteristic Declaration
[SVC1_IDX_RX_CTRL_CHAR] = {(uint8_t*)&att_decl_char, ATT_UUID_16_LEN, PERM(RD, ENABLE),
0, 0, NULL},
// Control Point Characteristic Value
[SVC1_IDX_RX_CONTROL_VAL] = {SVC1_RX_CTRL_UUID_128, ATT_UUID_128_LEN, PERM(WR, ENABLE) | PERM(WRITE_REQ, ENABLE) | PERM(WRITE_COMMAND, ENABLE),
DEF_SVC1_RX_CTRL_CHAR_LEN, 0, NULL},
// ADC Value 1 Characteristic Declaration
[SVC1_IDX_TX_CTRL_CHAR] = {(uint8_t*)&att_decl_char, ATT_UUID_16_LEN, PERM(RD, ENABLE),
//[SVC1_IDX_TX_CTRL_CHAR] = {(uint8_t*)&att_dec2_char, ATT_UUID_16_LEN, PERM(RD, ENABLE),
0, 0, NULL},
// ADC Value 1 Characteristic Value
[SVC1_IDX_TX_CTRL_VAL] = {SVC1_TX_CTRL_UUID_128, ATT_UUID_128_LEN, PERM(RD, ENABLE) | PERM(NTF, ENABLE),
DEF_SVC1_TX_CTRL_CHAR_LEN, 0, NULL},
// ADC Value 1 Client Characteristic Configuration Descriptor
[SVC1_IDX_TX_CTRL_NTF_CFG] = {(uint8_t*)&att_desc_cfg, ATT_UUID_16_LEN, PERM(RD, ENABLE) | PERM(WR, ENABLE) | PERM(WRITE_REQ, ENABLE),
sizeof(uint16_t), 0, NULL},
// ADC Value 1 Characteristic User Description
[SVC1_IDX_TX_CTRL_USER_DESC] = {(uint8_t*)&att_desc_user_desc, ATT_UUID_16_LEN, PERM(RD, ENABLE),
sizeof(DEF_SVC1_TX_CTRL_USER_DESC) - 1, sizeof(DEF_SVC1_TX_CTRL_USER_DESC) - 1,
(uint8_t *) DEF_SVC1_TX_CTRL_USER_DESC},
[SVC1_IDX_CODE_CHAR] = {(uint8_t*)&att_decl_char, ATT_UUID_16_LEN, PERM(RD, ENABLE),
0, 0, NULL},
[SVC1_IDX_CODE_VAL] = {SVC1_CODE_UUID_128, ATT_UUID_128_LEN, PERM(RD, ENABLE),
1, 0, NULL},
};
开始测试LOG
此时网关更新 node都没有更新
[00:01:44.919,952] <error> ble_nus_c: char_count=2
[00:01:44.919,952] <error> ble_nus_c: [0]- C]
[00:01:44.919,952] <error> ble_nus_c: [1]- E]
此时网关更新 node更新
[00:07:46.387,329] <error> ble_nus_c: char_count=3
[00:07:46.387,329] <error> ble_nus_c: [0]- C]
[00:07:46.387,359] <error> ble_nus_c: [1]- E]
[00:07:46.387,359] <error> ble_nus_c: [2]- 12]
[00:01:17.848,327] <info> app: [BLE-EVENT]: New data ??1??
此时基本大功告成 网关开启
#define CODE 1
bool crc_check_failed = false; // CRC check flag, if check failed send nack
if(p_ble_nus_c->orcode)
{
node还需要修改
#define USER_DEVICE_NAME "KOSON"
SHORTNAME 0
CODE 1
网关需要修改
#define NAME_FILTER "KOSON" //这个必须在短名字的后面 才能2种都WORK SDK的bug------------
nrf_ble_scan_short_name_t MY_NAME_FILTER={"MC_NXIN_04X",6};
err_code = nrf_ble_scan_filter_set(&m_scan, SCAN_SHORT_NAME_FILTER, &MY_NAME_FILTER);
APP_ERROR_CHECK(err_code);
err_code = nrf_ble_scan_filters_enable(&m_scan, NRF_BLE_SCAN_SHORT_NAME_FILTER, false);
APP_ERROR_CHECK(err_code);
err_code = nrf_ble_scan_filter_set(&m_scan, SCAN_NAME_FILTER, NAME_FILTER);
APP_ERROR_CHECK(err_code);
err_code = nrf_ble_scan_filters_enable(&m_scan, NRF_BLE_SCAN_NAME_FILTER, false);
APP_ERROR_CHECK(err_code);
adv_name_compare
ble_advdata_name_find
//太严格 需要一模一样
+++++++++++++++++++++++++++++++++++++++ADD++++++++++++++++++++++++++++++++
能不能不要bool 去拿到node的这个uuid的值呢?
先写node在思考吧
提交一次 手机可以互动的 收到手机的消息
node完成手机APP测试但是网关不能做出APP效果
注意 这一轮思考已经提交 下面再次思考
本次思考 不能直接notify消息 需要一个配置notifu的东西
[SVC1_IDX_CODE_CHAR] = {(uint8_t*)&att_decl_char, ATT_UUID_16_LEN, PERM(RD, ENABLE),
0, 0, NULL},
[SVC1_IDX_CODE_VAL] = {SVC1_CODE_UUID_128, ATT_UUID_128_LEN, PERM(RD, ENABLE) | PERM(NTF, ENABLE),
1, 0, NULL},
[SVC1_IDX_CODE_NTF_CFG] = {(uint8_t*)&att_desc_cfg, ATT_UUID_16_LEN, PERM(RD, ENABLE) | PERM(WR, ENABLE) | PERM(WRITE_REQ, ENABLE),
sizeof(uint16_t), 0, NULL},
enum
{
// Custom Service 1
SVC1_IDX_SVC = 0,
SVC1_IDX_RX_CTRL_CHAR,
SVC1_IDX_RX_CONTROL_VAL,
//SVC1_IDX_RX_CONTROL_USER_DESC,
SVC1_IDX_TX_CTRL_CHAR,
SVC1_IDX_TX_CTRL_VAL,
SVC1_IDX_TX_CTRL_NTF_CFG,
SVC1_IDX_TX_CTRL_USER_DESC,
SVC1_IDX_CODE_CHAR,
SVC1_IDX_CODE_VAL,
SVC1_IDX_CODE_NTF_CFG,
CUSTS1_IDX_NB
};
void user_catch_rest_hndl(ke_msg_id_t const msgid,
void const *param,
ke_task_id_t const dest_id,
ke_task_id_t const src_id)
{
switch(msgid)
{
case CUSTS1_VAL_WRITE_IND:
{
struct custs1_val_write_ind const *msg_param = (struct custs1_val_write_ind const *)(param);
switch (msg_param->handle)
{
case SVC1_IDX_RX_CONTROL_VAL:
user_svc1_rx_wr_ind_handler(msgid, msg_param, dest_id, src_id);
break;
case SVC1_IDX_TX_CTRL_NTF_CFG:
case SVC1_IDX_CODE_NTF_CFG:
user_svc1_tx_ntf_cfg_ind_handler(msgid, msg_param, dest_id, src_id);
break;
case SVC1_IDX_CODE_VAL:
user_svc1_code_wr_ind_handler(msgid, msg_param, dest_id, src_id);
break;
default:
break;
}
} break;
void user_svc1_tx_ntf_cfg_ind_handler(ke_msg_id_t const msgid,
struct custs1_val_write_ind const *param,
ke_task_id_t const dest_id,
ke_task_id_t const src_id)
{
cannot_logout_count[1][0]=param->length;
memcpy(&cannot_logout_count[1][1],(uint8_t *)param->value,MIN(LOGLEN,param->length));
uint8_t val = 0;
memcpy(&val, ¶m->value[0], param->length);
open = val;
}
可以看到 我们的手机APP可以使能它
然后我们notify消息 我发现还是需要定时器 不能只是发一次 不然APP收不到
就设计一个bool在RTC里面
void tx(void)
{
static uint8_t VAL='0';
req = KE_MSG_ALLOC_DYN(CUSTS1_VAL_NTF_REQ,
prf_get_task_from_id(TASK_ID_CUSTS1),
TASK_APP,
custs1_val_ntf_ind_req,
1);
req->handle = SVC1_IDX_CODE_VAL;//SVC1_IDX_TX_CTRL_VAL;
req->length = 1;
req->notification = true;
memcpy(req->value, &VAL, sizeof(uint8_t)* req->length );
if(++VAL=='9')VAL='0';
ke_msg_send(req);
}
static void app_data_handler(void)
{
if(open)tx();
此时可以看到APP在更新了!!!!
测试完成
也就是和开发板一样的 手机App发出使能 然后从机一直周期发消息
下面和nordic测试notify一次 我发一次回答
准备add一个handle 操作cccd
err_code = ble_nus_c_code_notif_enable(p_ble_nus_c);
APP_ERROR_CHECK(err_code);
从机收到使能信号!!
从机可以直接返回消息
void tx(void)
{
static uint8_t VAL='3';
req = KE_MSG_ALLOC_DYN(CUSTS1_VAL_NTF_REQ,
prf_get_task_from_id(TASK_ID_CUSTS1),
TASK_APP,
custs1_val_ntf_ind_req,
1);
req->handle = SVC1_IDX_CODE_VAL;//SVC1_IDX_TX_CTRL_VAL;
req->length = 1;
req->notification = true;
memcpy(req->value, &VAL, sizeof(uint8_t)* req->length );
// if(++VAL=='9')VAL='3';
ke_msg_send(req);
mc_debug("\r\nsend %c ",VAL);
}
void user_svc1_code_ntf_cfg_ind_handler(ke_msg_id_t const msgid,
struct custs1_val_write_ind const *param,
ke_task_id_t const dest_id,
ke_task_id_t const src_id)
{
// ble_nus_c_code_notif_enable 发送数组 只有第一个成员有意义
cannot_logout_count[0][0]=param->length;
memcpy(&cannot_logout_count[0][1],(uint8_t *)param->value,MIN(LOGLEN,param->length));
if(param->value[0])//马上给出回答
{
tx();
}
// open = param->value[0];//异步给出回答
}
主机需要接受 需要修改一些
BLE_NUS_C_EVT_NUS_TX_EVT
这个句柄需要+1
static void on_hvx(ble_nus_c_t * p_ble_nus_c, ble_evt_t const * p_ble_evt)
{
// HVX can only occur from client sending.
if ( (p_ble_nus_c->handles.nus_tx_handle != BLE_GATT_HANDLE_INVALID)
&& (p_ble_evt->evt.gattc_evt.params.hvx.handle == p_ble_nus_c->handles.nus_tx_handle)
&& (p_ble_nus_c->evt_handler != NULL))
{
ble_nus_c_evt_t ble_nus_c_evt;
ble_nus_c_evt.evt_type = BLE_NUS_C_EVT_NUS_TX_EVT;
ble_nus_c_evt.p_data = (uint8_t *)p_ble_evt->evt.gattc_evt.params.hvx.data;
ble_nus_c_evt.data_len = p_ble_evt->evt.gattc_evt.params.hvx.len;
p_ble_nus_c->evt_handler(p_ble_nus_c, &ble_nus_c_evt);
}
if ( (p_ble_nus_c->handles.nus_code_handle != BLE_GATT_HANDLE_INVALID)
&& (p_ble_evt->evt.gattc_evt.params.hvx.handle == p_ble_nus_c->handles.nus_code_handle)
&& (p_ble_nus_c->evt_handler != NULL))
{
ble_nus_c_evt_t ble_nus_c_evt;
ble_nus_c_evt.evt_type = BLE_NUS_C_EVT_NUS_TX_EVT;
ble_nus_c_evt.p_data = (uint8_t *)p_ble_evt->evt.gattc_evt.params.hvx.data;
ble_nus_c_evt.data_len = p_ble_evt->evt.gattc_evt.params.hvx.len;
p_ble_nus_c->evt_handler(p_ble_nus_c, &ble_nus_c_evt);
}
}
这样就可以收到
测试有严重问题 连续2次去使能从机ntf会死机 报错是busy
源码
static void ble_nus_c_evt_handler(ble_nus_c_t * p_ble_nus_c, ble_nus_c_evt_t const * p_ble_nus_evt)
{
ret_code_t err_code;
NRF_LOG_ERROR("[ble_nus_c_evt_handler in] p_ble_nus_c=%08x",p_ble_nus_c);
for(int i=0;i<NRF_SDH_BLE_CENTRAL_LINK_COUNT;i++)
NRF_LOG_ERROR("[%d]ADD=%08x",i,&m_ble_nus_c[i]);
NRF_LOG_DEBUG("[ble_nus_c_evt_handler in] conn_handle=%04x::%04x",p_ble_nus_c->conn_handle,p_ble_nus_evt->conn_handle);
switch (p_ble_nus_evt->evt_type)
{
// Found node by BLE
case BLE_NUS_C_EVT_DISCOVERY_COMPLETE:
NRF_LOG_INFO("[BLE] Discovery complete.");
err_code = ble_nus_c_handles_assign(p_ble_nus_c, p_ble_nus_evt->conn_handle, &p_ble_nus_evt->handles);
APP_ERROR_CHECK(err_code);
err_code = ble_nus_c_code_notif_enable(p_ble_nus_c);---------------------
APP_ERROR_CHECK(err_code);
if(time_sync_flag) {
struct tm ts;
rtc_sync_t utc_time; //UTO+0
ts = *localtime(&epoch);
utc_time.Year = ts.tm_year - 100;
utc_time.Month = ts.tm_mon + 1;
utc_time.Day = ts.tm_mday;
if (ts.tm_wday == 0)
utc_time.WDay = 7;
else
utc_time.WDay = ts.tm_wday;
utc_time.Hour = ts.tm_hour;
utc_time.Min = ts.tm_min;
utc_time.Sec = ts.tm_sec;
uint8_t send_pack[14]; //6 header + 8 payload
send_pack[0] = 0x11;
send_pack[1] = 0x01;
send_pack[2] = 0x00;
send_pack[3] = 8; //Payload length (time data length)
memcpy(&send_pack[4], &utc_time.Year, sizeof(rtc_sync_t));
send_pack[11] = 0x00; // reserve
err_code = ble_nus_c_string_send(p_ble_nus_c, send_pack,
//nrf_delay_ms(3);
//NRF_LOG_INFO("[BLE-PKG]: 2>Enable notification.");
//err_code = ble_nus_c_tx_notif_enable(p_ble_nus_c);--------------------------
//APP_ERROR_CHECK(err_code);
NRF_LOG_INFO("[BLE] 3>Connected Nordic UART Service.");//这里面的LOG很容易丢失 因为很快 往往值看到 Service.
break;
上面连续2次使能nof有问题
测试需要等待一个通讯周期 也就是等待第一个发出去 从机回答了 在去使能第二个
注销的代码放在后面
static void on_hvx(ble_nus_c_t * p_ble_nus_c, ble_evt_t const * p_ble_evt)
{
// HVX can only occur from client sending.
if ( (p_ble_nus_c->handles.nus_tx_handle != BLE_GATT_HANDLE_INVALID)
&& (p_ble_evt->evt.gattc_evt.params.hvx.handle == p_ble_nus_c->handles.nus_tx_handle)
&& (p_ble_nus_c->evt_handler != NULL))
{
ble_nus_c_evt_t ble_nus_c_evt;
ble_nus_c_evt.evt_type = BLE_NUS_C_EVT_NUS_TX_EVT;
ble_nus_c_evt.p_data = (uint8_t *)p_ble_evt->evt.gattc_evt.params.hvx.data;
ble_nus_c_evt.data_len = p_ble_evt->evt.gattc_evt.params.hvx.len;
p_ble_nus_c->evt_handler(p_ble_nus_c, &ble_nus_c_evt);
}
if ( (p_ble_nus_c->handles.nus_code_handle != BLE_GATT_HANDLE_INVALID)
&& (p_ble_evt->evt.gattc_evt.params.hvx.handle == p_ble_nus_c->handles.nus_code_handle)
&& (p_ble_nus_c->evt_handler != NULL))
{
ble_nus_c_evt_t ble_nus_c_evt;
ble_nus_c_evt.evt_type = BLE_NUS_C_EVT_NUS_CODE_EVT;
ble_nus_c_evt.p_data = (uint8_t *)p_ble_evt->evt.gattc_evt.params.hvx.data;
ble_nus_c_evt.data_len = p_ble_evt->evt.gattc_evt.params.hvx.len;
p_ble_nus_c->evt_handler(p_ble_nus_c, &ble_nus_c_evt);
}
}
这里在发
case BLE_NUS_C_EVT_NUS_TX_EVT:
NRF_LOG_INFO("[BLE] BLE NUS event.[%d][%d]",p_ble_nus_c->conn_handle,p_ble_nus_evt->conn_handle);
//ERROR ZHELI
ble_nus_chars_received_uart_print(p_ble_nus_c,p_ble_nus_evt->p_data, p_ble_nus_evt->data_len);
break;
case BLE_NUS_C_EVT_NUS_CODE_EVT:
NRF_LOG_INFO("[BLE] BLE_NUS_C_EVT_NUS_CODE_EVT[%d][%d]",p_ble_nus_c->conn_handle,p_ble_nus_evt->conn_handle);
NRF_LOG_INFO("[BLE-PKG]: 2>Enable notification.");
ret_code_t err_code;
err_code = ble_nus_c_tx_notif_enable(p_ble_nus_c);
APP_ERROR_CHECK(err_code);
break;