简介

介绍sig mesh蓝牙协议里面,“地址”的作用及分类及用法。

地址的分类

未分配地址(unassigned address)——即未经配置的元素的地址,不可用于信息发送

单播地址(unicast address)——节点在入网过程中,配网器会为每个元素都会分配一个唯一的地址,并发布给节点(注意,节点首元素的地址,即是该节点的地址)

虚拟地址(virtual address)——不懂。。

群组地址(group address)——分为动态和固定地址,动态的用来做一般的“组播”,固定地址用来做一些协议规定的功能。

  • 动态地址
    • 范围:0xC000-0xFEFF
  • 固定地址
    • 保留:0xFF00-0xFFFB
    • 发送到启用代理(proxy)功能的所有节点: 0xFFFC
    • 发送到启用friend功能的所有节点:0xFFFD
    • 发送到启用中继(relay)功能的所有节点:0xFFFE
    • 发送到所有节点:0xFFFF

单播功能

单播(unicast)——端对端的发送信息给节点(元素)
单播 (1).png
上图,节点A直接通过指定发送地址0x0001,发送开关命令到0x0001的开关模型
例子:【PHY6252-SDK-blemesh】vendor模型的应用示例(透传+publish)

发布,订阅功能(Publish , Subscribe)

发布(Publish)——往元素”主动”发送信息!发布信息前,需要调用API配置”目标地址”。
订阅(Subscribe)——“被动”的处理元素接收到的信息!订阅信息前,需要调用API去指定接收”目标地址”。
发布订阅 (1).png
上图,节点B的开关模型“订阅”了地址“0xCFFF”的信息响应,当节点A“发布”开关命令到地址“0XCFFF”,节点B即可收到相应的命令,并进行处理。
例子:【PHY6252-SDK-blemesh】generic模型的应用示例(订阅、发布)

SDK代码参考

地址的分配(gateway节点):
获取地址列表,增加地址后再发送到配网中的设备

  1. case PROV_EVT_PROVDATA_INFO_REQ:
  2. CONSOLE_OUT ("Recvd PROV_EVT_PROVDATA_INFO_REQ\n");
  3. CONSOLE_OUT ("Status - 0x%04X\n", event_result);
  4. /* Send Provisioning Data */
  5. CONSOLE_OUT ("Send Provisioning Data...\n");
  6. /* Update the next device address if provisioned devices are present in database */
  7. retval = MS_access_cm_get_prov_devices_list
  8. (
  9. &prov_dev_list[0],
  10. &num_entries,
  11. &pointer_entries
  12. );
  13. if ((API_SUCCESS == retval) /*&&
  14. (0 != num_entries)*/)
  15. {
  16. // UI_prov_data.uaddr = prov_dev_list[num_entries - 1].uaddr +
  17. // prov_dev_list[num_entries - 1].num_elements;
  18. UI_prov_data.uaddr = pointer_entries;//地址分配
  19. }
  20. printf("Updating Provisioning Start Addr to 0x%04X\n", UI_prov_data.uaddr);
  21. //Get network key
  22. MS_access_cm_get_netkey_at_offset(0,0,UI_prov_data.netkey);
  23. //Get key refresh state
  24. MS_access_cm_get_key_refresh_phase(0,&key_refresh_state);
  25. key_refresh_state = (MS_ACCESS_KEY_REFRESH_PHASE_2 == key_refresh_state) ? 0x01 : 0x00;
  26. UI_prov_data.ivindex = ms_iv_index.iv_index;
  27. UI_prov_data.flags = ((ms_iv_index.iv_update_state & 0x01) << 1) | key_refresh_state;
  28. blebrr_scan_pl(FALSE); //by hq
  29. retval = MS_prov_data (phandle, &UI_prov_data);//发送给配网的设备
  30. CONSOLE_OUT ("Retval - 0x%04X\n", retval);
  31. break;


Publish和Subscribe
Publish(gateway节点):

  1. UI_prov_data.uaddr = 0xCFFF;
  2. UI_set_publish_address(UI_prov_data.uaddr, UI_generic_onoff_client_model_handle,MS_FALSE);
  3. UI_set_publish_address(UI_prov_data.uaddr, UI_vendor_defined_client_model_handle,MS_FALSE);

Subscribe(light节点):

  1. void vm_subscriptiong_delete (MS_NET_ADDR addr)
  2. {
  3. MS_ACCESS_ADDRESS sub_addr;
  4. sub_addr.use_label=0;
  5. sub_addr.addr=addr;
  6. MS_access_ps_store_disable(MS_TRUE);
  7. MS_access_cm_delete_model_subscription(UI_generic_onoff_server_model_handle,&sub_addr);
  8. #ifdef USE_LIGHTNESS
  9. MS_access_cm_delete_model_subscription(UI_light_lightness_server_model_handle,&sub_addr);
  10. #endif
  11. #ifdef USE_CTL
  12. MS_access_cm_delete_model_subscription(UI_light_ctl_server_model_handle,&sub_addr);
  13. MS_access_cm_delete_model_subscription(UI_light_ctl_setup_server_model_handle,&sub_addr);
  14. #endif
  15. #ifdef USE_HSL
  16. MS_access_cm_delete_model_subscription(UI_light_hsl_server_model_handle,&sub_addr);
  17. MS_access_cm_delete_model_subscription(UI_light_hsl_setup_server_model_handle,&sub_addr);
  18. #endif
  19. #ifdef USE_SCENE
  20. MS_access_cm_delete_model_subscription(UI_scene_server_model_handle,&sub_addr);
  21. MS_access_cm_delete_model_subscription(UI_scene_setup_server_model_handle,&sub_addr);
  22. #endif
  23. MS_access_ps_store_disable(MS_FALSE);
  24. MS_access_ps_store_all_record();
  25. }