383 lines
10 KiB
C
383 lines
10 KiB
C
/**
|
|
****************************************************************************************
|
|
*
|
|
* @file app_gapc.c
|
|
*
|
|
* @brief App SubTask of GAP Controller Message - Example
|
|
*
|
|
* < If want to modify it, recommend to copy the file to 'user porject'/src >
|
|
****************************************************************************************
|
|
*/
|
|
|
|
/*
|
|
* INCLUDE FILES
|
|
****************************************************************************************
|
|
*/
|
|
|
|
#include "bledef.h"
|
|
#include "app.h"
|
|
|
|
#if (DBG_GAPC)
|
|
#include "dbg.h"
|
|
#define DEBUG(format, ...) debug("<%s,%d>" format "\r\n", __MODULE__, __LINE__, ##__VA_ARGS__)
|
|
#else
|
|
#define DEBUG(format, ...)
|
|
#define debugHex(dat,len)
|
|
#endif
|
|
|
|
|
|
/*
|
|
* DEFINES
|
|
****************************************************************************************
|
|
*/
|
|
|
|
|
|
/*
|
|
* MESSAGE HANDLERS
|
|
****************************************************************************************
|
|
*/
|
|
|
|
APP_MSG_HANDLER(gapc_cmp_evt)
|
|
{
|
|
// Command complete, may ignore
|
|
DEBUG("CMP_EVT(op:%d,sta:0x%x)", param->operation, param->status);
|
|
}
|
|
|
|
APP_MSG_HANDLER(gapc_connection_req_ind)
|
|
{
|
|
#if (DBG_GAPC)
|
|
uint8_t conidx = TASK_IDX(src_id);
|
|
#endif
|
|
|
|
DEBUG("gapc_connection_req_ind(cid:%d,chdl:%d,conn[intv:%d,late:%d,to:%d],acc:%d,caddr:%d)", conidx, param->conhdl,
|
|
param->con_interval, param->con_latency, param->sup_to, param->clk_accuracy, param->peer_addr_type);
|
|
debugHex(param->peer_addr.addr, GAP_BD_ADDR_LEN);
|
|
|
|
// Indicate Connect_Req_Pkt be send, need wait to sync (try 6 times of conn_event).
|
|
// If synced, goto gapc_connection_ind. Otherwise, goto gapc_disconnect_ind(reason=0x3E)
|
|
//app_conn_fsm(BLE_CONNECTING, conidx, param);
|
|
}
|
|
|
|
APP_MSG_HANDLER(gapc_connection_ind)
|
|
{
|
|
uint8_t conidx = TASK_IDX(src_id);
|
|
|
|
DEBUG("gapc_connection_ind(cid:%d,chdl:%d,role:%d)", conidx, param->conhdl, param->role);
|
|
|
|
// Connection established, update from v1.3
|
|
app_conn_fsm(BLE_CONNECTED, conidx, param);
|
|
}
|
|
|
|
APP_MSG_HANDLER(gapc_disconnect_ind)
|
|
{
|
|
uint8_t conidx = TASK_IDX(src_id);
|
|
|
|
DEBUG("gapc_disconnect_ind(cid:%d,hdl:%d,reason:0x%X)", conidx, param->conhdl, param->reason);
|
|
|
|
app_conn_fsm(BLE_DISCONNECTED, conidx, param);
|
|
}
|
|
|
|
APP_MSG_HANDLER(gapc_param_update_req_ind)
|
|
{
|
|
uint8_t conidx = TASK_IDX(src_id);
|
|
|
|
DEBUG("param_update(cid:%d,invM:%d,invI:%d,late:%d,timo:%d)", conidx,
|
|
param->intv_max, param->intv_min, param->latency, param->time_out);
|
|
|
|
// Connection param accept or reject
|
|
gapc_param_update_rsp(conidx, true, 0x2, 0x4);
|
|
}
|
|
|
|
APP_MSG_HANDLER(gapc_param_updated_ind)
|
|
{
|
|
DEBUG("param_updated_ind(cid:%d,intv:%d,late:%d,timo:%d)", TASK_IDX(src_id),
|
|
param->con_interval, param->con_latency, param->sup_to);
|
|
|
|
// Current param, may update to slaves
|
|
|
|
}
|
|
|
|
APP_MSG_HANDLER(gapc_le_pkt_size_ind)
|
|
{
|
|
DEBUG("le_pkt_size_ind(cid:%d,txB:%d,txT:%d,rxB:%d,rxT:%d)", TASK_IDX(src_id),
|
|
param->max_tx_octets, param->max_tx_time, param->max_rx_octets, param->max_rx_time);
|
|
}
|
|
|
|
#if (BLE_EN_SMP)
|
|
APP_MSG_HANDLER(gapc_bond_req_ind)
|
|
{
|
|
uint8_t conidx = TASK_IDX(src_id);
|
|
|
|
DEBUG("bond_req_ind(req:%d)", param->request);
|
|
|
|
switch (param->request)
|
|
{
|
|
case (GAPC_PAIRING_REQ):
|
|
{
|
|
struct gapc_pairing feat;
|
|
|
|
// Retrieve pairing feature to response
|
|
app_pairing_get(&feat);
|
|
gapc_smp_pairing_rsp(conidx, &feat);
|
|
|
|
DEBUG("PAIRING_REQ(auth:0x%X)", param->data.auth_req);
|
|
debugHex((uint8_t *)&feat, sizeof(struct gapc_pairing));
|
|
} break;
|
|
|
|
case (GAPC_LTK_EXCH):
|
|
{
|
|
struct gapc_ltk ltk;
|
|
|
|
// Generate all rand values to exchange
|
|
app_ltk_gen(conidx, <k);
|
|
gapc_smp_pairing_ltk_exch(conidx, <k);
|
|
|
|
DEBUG("LTK_EXCH(size:%d)", param->data.key_size);
|
|
debugHex((uint8_t *)<k, sizeof(struct gapc_ltk));
|
|
} break;
|
|
|
|
case (GAPC_IRK_EXCH):
|
|
{
|
|
DEBUG("IRK_EXCH");
|
|
|
|
// Load IRK
|
|
//memcpy(&(data.irk.irk), gapm_get_irk(), GAP_KEY_LEN);
|
|
|
|
// load device address
|
|
//memcpy(&(data.irk.addr.addr), gapm_get_bdaddr(), GAP_BD_ADDR_LEN);
|
|
//data.irk.addr.addr_type = (data.irk.addr.addr.addr[5] & 0xC0) ? ADDR_RAND : ADDR_PUBLIC;
|
|
} break;
|
|
|
|
case (GAPC_TK_EXCH):
|
|
{
|
|
DEBUG("TK_EXCH(type:%d)", param->data.tk_type);
|
|
|
|
if (param->data.tk_type == GAP_TK_OOB)
|
|
{
|
|
DEBUG("TK_OOB>>>");
|
|
return;
|
|
}
|
|
else if (param->data.tk_type == GAP_TK_DISPLAY)
|
|
{
|
|
struct gap_sec_key tk;
|
|
// Generate a PIN Code- (Between 100000 and 999999)
|
|
uint32_t pin_code = (100000 + (rand_word() % 900000));
|
|
// Set the TK value
|
|
memset(&tk.key, 0, GAP_KEY_LEN);
|
|
write32p(&tk.key, pin_code);
|
|
|
|
DEBUG("TK_DISPLAY:%06d", pin_code);
|
|
gapc_smp_pairing_tk_exch(conidx, true, &tk);
|
|
}
|
|
else //if (param->data.tk_type == GAP_TK_KEY_ENTRY)
|
|
{
|
|
DEBUG("TK_KEY_ENTRY>>>");
|
|
return;
|
|
}
|
|
} break;
|
|
|
|
case (GAPC_CSRK_EXCH):
|
|
{
|
|
struct gap_sec_key csrk;
|
|
DEBUG("CSRK_EXCH");
|
|
memset(&csrk.key, 0, GAP_KEY_LEN);
|
|
gapc_smp_pairing_csrk_exch(conidx, &csrk);
|
|
} break;
|
|
|
|
#if (SEC_CON_ENB)
|
|
case (GAPC_OOB_EXCH):
|
|
{
|
|
DEBUG("OOB_EXCH(conf,rand)>>>");
|
|
debugHex(param->data.oob_data.conf, GAP_KEY_LEN);
|
|
debugHex(param->data.oob_data.rand, GAP_KEY_LEN);
|
|
|
|
return;
|
|
} //break;
|
|
|
|
case (GAPC_NC_EXCH):
|
|
{
|
|
DEBUG("NC_EXCH(%06d)", read32p(param->data.nc_data.value));
|
|
gapc_smp_pairing_nc_exch(conidx, true);
|
|
} break;
|
|
#endif //(SEC_CON_ENB)
|
|
|
|
default:
|
|
{
|
|
// not happen
|
|
} break;
|
|
}
|
|
}
|
|
|
|
APP_MSG_HANDLER(gapc_bond_ind)
|
|
{
|
|
uint8_t conidx = TASK_IDX(src_id);
|
|
DEBUG("bond_ind(info:%d)", param->info);
|
|
|
|
switch (param->info)
|
|
{
|
|
case (GAPC_PAIRING_SUCCEED):
|
|
{
|
|
DEBUG("PAIRING_SUCCEED(auth:%X,ltk:%d)", param->data.auth.info, param->data.auth.ltk_present);
|
|
// Update the bonding status
|
|
app_conn_fsm(BLE_BONDED, conidx, param);
|
|
} break;
|
|
|
|
case (GAPC_PAIRING_FAILED):
|
|
{
|
|
DEBUG("PAIRING_FAILED(reason:0x%X)", param->data.reason);
|
|
//gapc_smp_security_req(conidx, GAP_AUTH_REQ_NO_MITM_NO_BOND);
|
|
} break;
|
|
|
|
case (GAPC_REPEATED_ATTEMPT):
|
|
{
|
|
DEBUG("REPEATED_ATTEMPT");
|
|
gapc_disconnect(conidx);
|
|
} break;
|
|
|
|
case (GAPC_IRK_EXCH):
|
|
{
|
|
DEBUG("IRK_EXCH(irk,addr)");
|
|
debugHex(param->data.irk.irk.key, GAP_KEY_LEN);
|
|
debugHex(param->data.irk.addr.addr.addr, GAP_BD_ADDR_LEN);
|
|
// Store peer identity
|
|
} break;
|
|
|
|
// In Secure Connections we get BOND_IND with SMPC calculated LTK
|
|
case (GAPC_LTK_EXCH) :
|
|
{
|
|
DEBUG("Bond LTK_EXCH(size:%d)", param->data.ltk.key_size);
|
|
debugHex(param->data.ltk.ltk.key, sizeof(struct gapc_ltk));
|
|
|
|
// Store peer LTK
|
|
// if ((gapc_auth_get(conidx) & GAP_AUTH_SEC_CON) || (gapc_get_role(conidx) == ROLE_MASTER))
|
|
// {
|
|
// app_ltk_save(conidx, ¶m->data.ltk);
|
|
// }
|
|
} break;
|
|
|
|
default:
|
|
break;
|
|
}
|
|
}
|
|
|
|
APP_MSG_HANDLER(gapc_encrypt_req_ind)
|
|
{
|
|
uint8_t conidx = TASK_IDX(src_id);
|
|
|
|
DEBUG("encrypt_req_ind(ediv:0x%X,rand)", param->ediv);
|
|
debugHex(param->rand_nb.nb, GAP_RAND_NB_LEN);
|
|
|
|
// Check if the provided EDIV and Rand Nb values match with the stored values
|
|
struct gap_sec_key *ltk = (struct gap_sec_key *)app_ltk_find(param->ediv, param->rand_nb.nb);
|
|
if (ltk != NULL)
|
|
{
|
|
DEBUG("->Find Same LTK");
|
|
gapc_smp_encrypt_cfm(conidx, GAP_KEY_LEN, ltk);
|
|
}
|
|
else
|
|
{
|
|
// bonded with another device, disconnect the link
|
|
DEBUG("->Find Diff LTK");
|
|
gapc_smp_encrypt_cfm(conidx, 0, NULL);
|
|
//gapc_smp_security_req(conidx, GAP_AUTH_REQ_NO_MITM_BOND);
|
|
gapc_disconnect(conidx);
|
|
}
|
|
}
|
|
|
|
APP_MSG_HANDLER(gapc_encrypt_ind)
|
|
{
|
|
uint8_t conidx = TASK_IDX(src_id);
|
|
DEBUG("encryp_ind(auth:%d)", param->auth);
|
|
|
|
// encryption/ re-encryption succeeded
|
|
app_conn_fsm(BLE_ENCRYPTED, conidx, param);
|
|
}
|
|
|
|
APP_MSG_HANDLER(gapc_security_ind)
|
|
{
|
|
// slave request security
|
|
DEBUG("security_ind(auth:%d)", param->auth);
|
|
}
|
|
#endif //(BLE_EN_SMP)
|
|
|
|
/**
|
|
****************************************************************************************
|
|
* @brief SubTask Handler of GAP controller Message.
|
|
****************************************************************************************
|
|
*/
|
|
APP_SUBTASK_HANDLER(gapc_msg)
|
|
{
|
|
switch (msgid)
|
|
{
|
|
case GAPC_CMP_EVT:
|
|
{
|
|
APP_MSG_FUNCTION(gapc_cmp_evt);
|
|
} break;
|
|
|
|
case GAPC_CONNECTION_REQ_IND:
|
|
{
|
|
APP_MSG_FUNCTION(gapc_connection_req_ind);
|
|
} break;
|
|
|
|
case GAPC_CONNECTION_IND:
|
|
{
|
|
// Connection established, update from v1.3
|
|
APP_MSG_FUNCTION(gapc_connection_ind);
|
|
} break;
|
|
|
|
case GAPC_DISCONNECT_IND:
|
|
{
|
|
APP_MSG_FUNCTION(gapc_disconnect_ind);
|
|
} break;
|
|
|
|
case GAPC_PARAM_UPDATE_REQ_IND:
|
|
{
|
|
APP_MSG_FUNCTION(gapc_param_update_req_ind);
|
|
} break;
|
|
|
|
case GAPC_PARAM_UPDATED_IND:
|
|
{
|
|
APP_MSG_FUNCTION(gapc_param_updated_ind);
|
|
} break;
|
|
|
|
#if (BLE_EN_SMP)
|
|
case GAPC_BOND_REQ_IND:
|
|
{
|
|
APP_MSG_FUNCTION(gapc_bond_req_ind);
|
|
} break;
|
|
|
|
case GAPC_BOND_IND:
|
|
{
|
|
APP_MSG_FUNCTION(gapc_bond_ind);
|
|
} break;
|
|
|
|
case GAPC_ENCRYPT_REQ_IND:
|
|
{
|
|
APP_MSG_FUNCTION(gapc_encrypt_req_ind);
|
|
} break;
|
|
|
|
case GAPC_ENCRYPT_IND:
|
|
{
|
|
APP_MSG_FUNCTION(gapc_encrypt_ind);
|
|
} break;
|
|
|
|
case GAPC_SECURITY_IND:
|
|
{
|
|
APP_MSG_FUNCTION(gapc_security_ind);
|
|
} break;
|
|
#endif //(BLE_EN_SMP)
|
|
|
|
case GAPC_LE_PKT_SIZE_IND:
|
|
{
|
|
APP_MSG_FUNCTION(gapc_le_pkt_size_ind);
|
|
} break;
|
|
|
|
default:
|
|
{
|
|
DEBUG("Unknow MsgId:0x%X", msgid);
|
|
} break;
|
|
}
|
|
|
|
return (MSG_STATUS_FREE);
|
|
}
|