|
provison_send_state变为 STATE_DEV_CAPA_ACK后执行了下面代码:
case STATE_DEV_CAPA_ACK:
if(p_adv->transBear.bearAck.header.GPCF == TRANS_START &&
p_adv->transStart.data[0]== PRO_CAPABLI){
//接收到未配网设备发送的capabilities
memcpy(pro_input+1,&(p_rcv_str->capa.ele_num),11); //保存交互数据
prov_para.ele_cnt = p_rcv_str->capa.ele_num; //Number of Element
swap_mesh_pro_capa((mesh_pro_data_structer *)p_adv->transStart.data);
// swap the endiness for the capa data
mesh_adv_prov_capa_rcv(p_adv);
// get the capabilty para
memcpy(&prov_oob.capa , &p_rcv_str->capa,sizeof(p_rcv_str->capa));
//将值保存到prov_oob.capa中
get_pubkey_oob_info_by_capa(&prov_oob);
//根据 prov_oob->capa 中的值 得到 prov_oob 的值(OOB数据)
set_start_para_by_capa(&prov_oob);
//将 prov_oob 中的值 赋值给 prov_oob->start
mesh_adv_prov_send_start_cmd(p_send_str,&(prov_oob.start)); //发送Start
memcpy(pro_input+12,&(p_send_str->start.alogrithms),5); //保存交互数据
prov_para.provison_send_state = STATE_PRO_START_ACK;
}
break;
其中的 mesh_adv_prov_capa_rcv 和 mesh_send_provison_data 函数源码为:
void mesh_adv_prov_capa_rcv(pro_PB_ADV *p_adv)
{
SET_TC_FIFO(TSCRIPT_MESH_RX,(u8 *)p_adv,p_adv->length+1);
LOG_MSG_INFO(TL_LOG_PROVISION, 0, 0,"rcv capabilities",0);
set_rsp_ack_transnum(p_adv); //设置prov_para.rsp_ack_transnum
send_rcv_retry_clr(); //取消重传
mesh_send_provison_data(TRANS_ACK,0,0,0); //发送ACK
SET_TC_FIFO(TSCRIPT_MESH_TX,(u8 *)(&(pro_adv_pkt.len)),pro_adv_pkt.len+1);
}
u8 mesh_send_provison_data(u8 pdu_type,u8 bearCode,u8 *para,u8 para_len )
{
u8 trans_ack_flag =0;
pro_PB_ADV *p_pro_pb_adv;
p_pro_pb_adv = (pro_PB_ADV *)(&(pro_adv_pkt.len));
p_pro_pb_adv->ad_type = MESH_ADV_TYPE_PRO;
p_pro_pb_adv->transAck.GPCF = pdu_type;
switch(pdu_type){
case TRANS_ACK:
trans_ack_flag =1;
p_pro_pb_adv->length = 1+6;// no para
memcpy(p_pro_pb_adv->link_ID,(u8*)(&(prov_para.link_id)),4);
p_pro_pb_adv->transAck.rfu =0;
break;
}
if(trans_ack_flag){
p_pro_pb_adv->trans_num = prov_para.rsp_ack_transnum;
}
}
发送完ACK后调用 mesh_adv_prov_send_start_cmd 发送Start:
void mesh_adv_prov_send_start_cmd(mesh_pro_data_structer *p_send_str,pro_trans_start *p_start)
{
set_pro_start_simple(p_send_str,p_start); //将 p_start 中的值 赋值给 p_send_str->start
send_multi_type_data(PRO_START,para_pro);
SET_TC_FIFO(TSCRIPT_MESH_TX,(u8 *)(&(pro_adv_pkt.len)),pro_adv_pkt.len+1);
LOG_MSG_INFO(TL_LOG_PROVISION, 0, 0,"send prov start",0);
send_rcv_retry_set(PRO_START,0,1);
prov_para.trans_num_last = prov_para.trans_num; //将此次的Transaction Number保存,用于ack过滤
}
然后provison_send_state变为STATE_PRO_START_ACK,执行以下代码:
case STATE_PRO_START_ACK:
//ack and then send the public key cmd
if(p_adv->transAck.GPCF == TRANS_ACK&& p_adv->trans_num >= prov_para.trans_num_last){
//PB-ADV中的Transaction Number相同的ACK
mesh_adv_prov_start_ack(p_adv); //取消重传
mesh_adv_prov_pubkey_send(p_send_str,pro_ppk); //发送 public key 也就是 pro_ppk(EDCH坐标值 公钥)
prov_para.provison_send_state = STATE_PRO_PUB_KEY_ACK;
}
break;
调用mesh_adv_prov_pubkey_send函数:
void mesh_adv_prov_pubkey_send(mesh_pro_data_structer *p_send_str,u8 *ppk)
{
set_pro_pub_key(p_send_str,ppk,ppk+32); //将公钥的值赋值给p_send_str->pubkey
send_multi_type_data(PRO_PUB_KEY,para_pro);
send_rcv_retry_set(PRO_PUB_KEY,0,0);
LOG_MSG_INFO(TL_LOG_PROVISION, 0, 0,"send pub_key:",0);
prov_para.trans_num_last = prov_para.trans_num;
}
然后provison_send_state变为STATE_PRO_PUB_KEY_ACK,执行以下代码:
case STATE_PRO_PUB_KEY_ACK:
//wait the ack
if(p_adv->transAck.GPCF == TRANS_ACK&&p_adv->trans_num >= prov_para.trans_num_last){
//在capabilieies阶段prov_oob.start.pubKey = prov_oob->capa.pubKeyType
if(prov_oob.start.pubKey == MESH_PUB_KEY_WITH_OOB){ //提供OOB信息
// not need to exchange the part of the pubkey ,just need to send the pubkey
// only need to send the comfirm command
if(!mesh_prov_oob_auth_data(&prov_oob)){ //给 pro_auth 赋值
LOG_MSG_ERR(TL_LOG_PROVISION,0, 0 ,"prov oob is invalid",0);
return ;
}
send_rcv_retry_clr();
memcpy(pro_input+0x11,pro_ppk,sizeof(pro_ppk));
memcpy(pro_input+0x11+64,pub_key_with_oob,64);
if(prov_oob.start.authMeth == MESH_OUTPUT_OOB){
prov_oob.oob_out_tick = clock_time()|1;
prov_para.provison_send_state = STATE_DEV_PUB_KEY_OUTPUT_OOB ;
}else if (prov_oob.start.authMeth == MESH_INPUT_OOB){
prov_para.provison_send_state = STATE_DEV_PUB_KEY_INPUT_OOB;
}else{
send_comfirm_no_pubkey_cmd();
}
}else{ //不提供OOB信息(天猫)
prov_para.provison_send_state = STATE_DEV_PUB_KEY;
}
}n
break;
由于天猫精灵不提供OOB信息,所以收到ACK后直接将provison_send_state变成 STATE_DEV_PUB_KEY。
|
|