#
Bluetooth Low Energy (BLE)を利用したESP32の開発.
ESP32のBLE対応状況
2017-04-04: API群とexampleが存在する. しかし、documentが無い. そして色々不備が指摘されてる.
www.esp32.com
esp-idf2.0で大改修なのかな?
掘り出しもんを見つけた
esp-idf内にHID Over GATT Profile関係…?
命名からして、hid_le_prf = HID Low Energy Profileぽいよね.
esp-idf/hid_le_prf.c at release/v2.0 · espressif/esp-idf · GitHub
Bluetooth のプロファイルについて調べたことのまとめ - Over&Out その後
GATT SERVER API
application callbacksの登録.
esp_ble_gatts_register_callback()
This function is called to register application callbacks with BTA GATTS module.
esp_ble_gap_register_callback()
This function is called to occur gap event, such as scan result.
serviceへのcharacteristic追加.
esp_ble_gatts_add_char()
GATT SERVER API
実体: https://github.com/espressif/esp-idf/blob/47b8f78cb0e15fa43647788a808dac353167a485/components/bt/bluedroid/api/esp_gatts_api.c
This function is called to add a characteristic into a service.
struct esp_attr_value_t
{
uint16_t attr_max_len,
uint16_t attr_len,
uint8_t *attr_value
}
esp_err_t esp_ble_gatts_add_char(uint16_t service_handle, esp_bt_uuid_t *char_uuid,
esp_gatt_perm_t perm, esp_gatt_char_prop_t property, esp_attr_value_t *char_val,
esp_attr_control_t *control){
...
memset(&arg, 0, sizeof(btc_ble_gatts_args_t));
msg.sig = BTC_SIG_API_CALL;
msg.pid = BTC_PID_GATTS;
msg.act = BTC_GATTS_ACT_ADD_CHAR;
arg.add_char.service_handle = service_handle;
arg.add_char.perm = perm;
arg.add_char.property = property;
if (char_val != NULL) {
arg.add_char.char_val.attr_max_len = char_val->attr_max_len;
arg.add_char.char_val.attr_len = char_val->attr_len;
arg.add_char.char_val.attr_value = char_val->attr_value;
}
if (control != NULL) { .. argument 5
arg.add_char.attr_control.auto_rsp = control->auto_rsp;
}
memcpy(&arg.add_char.char_uuid, char_uuid, sizeof(esp_bt_uuid_t));
return (btc_transfer_context(&msg, &arg, sizeof(btc_ble_gatts_args_t), btc_gatts_arg_deep_copy) == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL);
}
[https:
typedef struct btc_msg {
uint8_t sig;
uint8_t aid;
uint8_t pid;
uint8_t act;
void *arg;
} btc_msg_t;
[https:
bt_status_t btc_transfer_context(btc_msg_t *msg, void *arg, int arg_len, btc_arg_deep_copy_t copy_func)
{
btc_msg_t lmsg;
if (msg == NULL) {
return BT_STATUS_PARM_INVALID;
}
LOG_DEBUG("%s msg %u %u %u %p\n", __func__, msg->sig, msg->pid, msg->act, arg);
memcpy(&lmsg, msg, sizeof(btc_msg_t));
if (arg) {
lmsg.arg = (void *)GKI_getbuf(arg_len);
memset(lmsg.arg, 0x00, arg_len);
if (lmsg.arg == NULL) {
return BT_STATUS_NOMEM;
}
memcpy(lmsg.arg, arg, arg_len);
if (copy_func) {
copy_func(&lmsg, lmsg.arg, arg);
}
} else {
lmsg.arg = NULL;
}
return btc_task_post(&lmsg);
}
[https:
void btc_gatts_arg_deep_copy(btc_msg_t *msg, void *p_dest, void *p_src)
{
btc_ble_gatts_args_t *dst = (btc_ble_gatts_args_t *) p_dest;
btc_ble_gatts_args_t *src = (btc_ble_gatts_args_t *)p_src;
switch (msg->act) {
...
case BTC_GATTS_ACT_ADD_CHAR:{
if (src->add_char.char_val.attr_value != NULL){
dst->add_char.char_val.attr_value = (uint8_t *)GKI_getbuf(src->add_char.char_val.attr_len);
if(dst->add_char.char_val.attr_value != NULL){
memcpy(dst->add_char.char_val.attr_value, src->add_char.char_val.attr_value,
src->add_char.char_val.attr_len);
}else{
LOG_ERROR("%s %d no mem\n", __func__, msg->act);
}
}
break;
}
...
}
...
}
[https: