简介
介绍sig mesh蓝牙协议里面,“地址”的作用及分类及用法。
地址的分类
未分配地址(unassigned address)——即未经配置的元素的地址,不可用于信息发送
单播地址(unicast address)——节点在入网过程中,配网器会为每个元素都会分配一个唯一的地址,并发布给节点(注意,节点首元素的地址,即是该节点的地址)
虚拟地址(virtual address)——不懂。。
群组地址(group address)——分为动态和固定地址,动态的用来做一般的“组播”,固定地址用来做一些协议规定的功能。
- 动态地址
- 范围:0xC000-0xFEFF
- 固定地址
- 保留:0xFF00-0xFFFB
- 发送到启用代理(proxy)功能的所有节点: 0xFFFC
- 发送到启用friend功能的所有节点:0xFFFD
- 发送到启用中继(relay)功能的所有节点:0xFFFE
- 发送到所有节点:0xFFFF
单播功能
单播(unicast)——端对端的发送信息给节点(元素)
上图,节点A直接通过指定发送地址0x0001,发送开关命令到0x0001的开关模型
例子:【PHY6252-SDK-blemesh】vendor模型的应用示例(透传+publish)
发布,订阅功能(Publish , Subscribe)
发布(Publish)——往元素”主动”发送信息!发布信息前,需要调用API配置”目标地址”。
订阅(Subscribe)——“被动”的处理元素接收到的信息!订阅信息前,需要调用API去指定接收”目标地址”。
上图,节点B的开关模型“订阅”了地址“0xCFFF”的信息响应,当节点A“发布”开关命令到地址“0XCFFF”,节点B即可收到相应的命令,并进行处理。
例子:【PHY6252-SDK-blemesh】generic模型的应用示例(订阅、发布)
SDK代码参考
地址的分配(gateway节点):
获取地址列表,增加地址后再发送到配网中的设备
case PROV_EVT_PROVDATA_INFO_REQ:
CONSOLE_OUT ("Recvd PROV_EVT_PROVDATA_INFO_REQ\n");
CONSOLE_OUT ("Status - 0x%04X\n", event_result);
/* Send Provisioning Data */
CONSOLE_OUT ("Send Provisioning Data...\n");
/* Update the next device address if provisioned devices are present in database */
retval = MS_access_cm_get_prov_devices_list
(
&prov_dev_list[0],
&num_entries,
&pointer_entries
);
if ((API_SUCCESS == retval) /*&&
(0 != num_entries)*/)
{
// UI_prov_data.uaddr = prov_dev_list[num_entries - 1].uaddr +
// prov_dev_list[num_entries - 1].num_elements;
UI_prov_data.uaddr = pointer_entries;//地址分配
}
printf("Updating Provisioning Start Addr to 0x%04X\n", UI_prov_data.uaddr);
//Get network key
MS_access_cm_get_netkey_at_offset(0,0,UI_prov_data.netkey);
//Get key refresh state
MS_access_cm_get_key_refresh_phase(0,&key_refresh_state);
key_refresh_state = (MS_ACCESS_KEY_REFRESH_PHASE_2 == key_refresh_state) ? 0x01 : 0x00;
UI_prov_data.ivindex = ms_iv_index.iv_index;
UI_prov_data.flags = ((ms_iv_index.iv_update_state & 0x01) << 1) | key_refresh_state;
blebrr_scan_pl(FALSE); //by hq
retval = MS_prov_data (phandle, &UI_prov_data);//发送给配网的设备
CONSOLE_OUT ("Retval - 0x%04X\n", retval);
break;
Publish和Subscribe
Publish(gateway节点):
UI_prov_data.uaddr = 0xCFFF;
UI_set_publish_address(UI_prov_data.uaddr, UI_generic_onoff_client_model_handle,MS_FALSE);
UI_set_publish_address(UI_prov_data.uaddr, UI_vendor_defined_client_model_handle,MS_FALSE);
Subscribe(light节点):
void vm_subscriptiong_delete (MS_NET_ADDR addr)
{
MS_ACCESS_ADDRESS sub_addr;
sub_addr.use_label=0;
sub_addr.addr=addr;
MS_access_ps_store_disable(MS_TRUE);
MS_access_cm_delete_model_subscription(UI_generic_onoff_server_model_handle,&sub_addr);
#ifdef USE_LIGHTNESS
MS_access_cm_delete_model_subscription(UI_light_lightness_server_model_handle,&sub_addr);
#endif
#ifdef USE_CTL
MS_access_cm_delete_model_subscription(UI_light_ctl_server_model_handle,&sub_addr);
MS_access_cm_delete_model_subscription(UI_light_ctl_setup_server_model_handle,&sub_addr);
#endif
#ifdef USE_HSL
MS_access_cm_delete_model_subscription(UI_light_hsl_server_model_handle,&sub_addr);
MS_access_cm_delete_model_subscription(UI_light_hsl_setup_server_model_handle,&sub_addr);
#endif
#ifdef USE_SCENE
MS_access_cm_delete_model_subscription(UI_scene_server_model_handle,&sub_addr);
MS_access_cm_delete_model_subscription(UI_scene_setup_server_model_handle,&sub_addr);
#endif
MS_access_ps_store_disable(MS_FALSE);
MS_access_ps_store_all_record();
}