DeviceVirtualization Kit(简称DV Kit)是华为提供的多设备虚拟化平台,通过该平台,将周边的设备或设备器件转换为手机的虚拟器件,能够将周边设备能力作为手机系统通用能力来提供和使用,同时能够实现多虚拟设备能力同步协同使用。

应用开发者通过集成DV Kit,可以便捷使用外部的设备,包括但不限于摄像头、扬声器、显示器、麦克风、穿戴等外部设备能力以及相关器件的能力,并可以支持灵活的控制和切换,充分使用外部设备的资源优势,致力为消费者打造更佳的协同体验。

您将建立什么

在这个Codelab中,你将创建Demo Project,并将DeviceVirtualization Kit集成到Demo Project中,以及完成DeviceVirtualization Kit服务的整体流程搭建,并在设备上实现启动,停止以及发现设备。

您将会学到什么

硬件要求

软件要求

需要的知识点

集成DeviceVirtualization Kit能力,需要完成以下准备工作:

具体操作,请按照《DeviceVirtualization Kit 接入准备》中详细说明来完成。

1.集成DeviceVirtualization Kit。

请依照《DeviceVirtualization Kit 接入准备》中第二步获取到DeviceVirtualization Kit的SDK软件包。

2.北向DVAgentListener注册接口适配:

// 以下为DVAgentListener需要注册的回调函数 void DVKIT_DataReceive(DV_AGENT_HANDLE handle, int dataType, char *data, uint32_t dataLen) { return; } void DVKIT_DeviceChange(DV_AGENT_HANDLE handle, const char *deviceId, uint32_t idLen, int state) { // 接收到状态106断开,异步线程进行删除调用DVAgentDestroyServiceHandle进行删除 return; } void DVKIT_DeviceServiceChange(DV_AGENT_HANDLE handle, const char *serviceId, uint32_t idLen, int state) { return; } void DVKIT_PinCode(const char *pinCode, uint32_t codeLen) { // 显示Pin码 return; } int32_t DVKIT_GetSecureFileSize(const char *filename) { // 获取存储认证信息的文件大小 return size; } int32_t DVKIT_ReadSecureFile(const char *filename, uint32_t offset, uint8_t *buf, uint32_t len) { // 读取存储认证信息的文件 return size; } int32_t DVKIT_WriteSecureFile(const char *filename, uint32_t offset, uint8_t *buf, uint32_t len) { // 往存储认证信息的文件写入内容,认证信息建议存储在安全存储区 return 0; } int32_t DVKIT_RemoveSecureFile(const char *filename) { // 删除存储认证信息的文件 return 0; }

3.北向初始化DV Kit:

DV_AGENT_HANDLE g_dvagentHandle = NULL; // 初始化DvKit void DVKIT_Init() { DVAgentConfig dvAgentConfig = {0}; dvAgentConfig.deviceInfo.connectAllowType = 0x1; dvAgentConfig.deviceInfo.vendorID = 0x1; // 获取BLE MAC,为6字节二进制,且此处MAC不可变,如果变了需要清除认证信息文件 GetMac((char*)dvAgentConfig.deviceInfo.brMac); memcpy_s(dvAgentConfig.deviceInfo.deviceId, strlen(DV_AGENT_DEVICE_ID) + 1, DV_AGENT_DEVICE_ID, strlen(DV_AGENT_DEVICE_ID)); dvAgentConfig.deviceInfo.idLen = strlen(DV_AGENT_DEVICE_ID); memcpy_s(dvAgentConfig.deviceInfo.deviceName, strlen(DV_AGENT_DEVICE_NAME) + 1, DV_AGENT_DEVICE_NAME, strlen(DV_AGENT_DEVICE_NAME)); dvAgentConfig.deviceInfo.nameLen = strlen(DV_AGENT_DEVICE_NAME); int32_t ret= DVAgentInit(&dvAgentConfig); if(ret != 0) { return; } DVAgentListener listener = {0}; listener.DataReceive = DVKIT_DataReceive; listener.DeviceChange = DVKIT_DeviceChange; listener.DeviceServiceChange = DVKIT_DeviceServiceChange; listener.GetSecureFileSize = DVKIT_GetSecureFileSize; listener.PinCode = DVKIT_PinCode; listener.ReadSecureFile = DVKIT_ReadSecureFile; listener.RemoveSecureFile = DVKIT_RemoveSecureFile; listener.WriteSecureFile = DVKIT_WriteSecureFile; ret = DVAgentRegisterListener(&listener); if(ret != 0) { return; } g_dvagentHandle = DVAgentCreateServiceHandle(); while (1) { sleep(1); } return; }

4.南向智能设备信息采集适配,DV Kit采集智能设备的设备类型、设备支持的服务能力及设备能力的状态,智能设备厂商需实现对应libdmsdpdevice.so,完成获取设备类型、设备服务能力及设备能力状态等接口,供DV kit调用。

int32_t DMSDPGetState(uint32_t *state) { if (state == NULL) { return DMSDP_ERR_NULLPTR; } /* if support DMSDP set AVAILABLE */ *state = DMSDP_AVAILABLE; return DMSDP_OK; } int32_t DMSDPGetDeviceType(uint32_t *type) { if (type == NULL) { return DMSDP_ERR_NULLPTR; } /* set the device type */ *type = DEVICE_TYPE_CAMERA; return DMSDP_OK; } int32_t DMSDPGetDeviceServiceCapability(uint32_t *serviceMask, uint32_t *stateMask) { if (serviceMask == NULL || stateMask == NULL) { return DMSDP_ERR_NULLPTR; } /* * get dmsdp deivce service capability * serviceMask: DMSDPServiceType mask, each bit specify a service type * for example : if support MIC and Speaker, mask will be SERVICE_TYPE_MIC | SERVICE_TYPE_SPEAKER * * stateMask: DMSDPServiceState mask, each 2bit specify a service state match to the service type mask * for example : if support MIC and Speaker, mask will be SERVICE_TYPE_MIC | SERVICE_TYPE_SPEAKER, * if MIC state is AVAILABLE and speaker is AVAILABLE, the the state mask will be * 0000 0000 0000 0000 0000 0000 0001 0100 : 0x00000014 */ *serviceMask = SERVICE_TYPE_CAMERA | SERVICE_TYPE_SPEAKER | SERVICE_TYPE_MIC; *stateMask = 0x00000015; return DMSDP_OK; } int32_t DMSDPDeviceRegisterListener(const DMSDPListener *listener) { /* regist service state/action listener */ (void)listener; return DMSDP_OK; } int32_t DMSDPGetDeviceCustomProps(DMSDPProps* props) { if (props == NULL || props->SetProp == NULL) { return DMSDP_ERR_NULLPTR; } props->nums = 1; props->SetProp(0, "10036", "xxxxx", props); return 0; }

5.南向设备Camera虚拟化接口适配,此类接口用于定义DV Kit对智能设备Camera硬件的调用接口,智能设备厂商需实现对应的libdmsdpcamerahandler.so。如果智能设备厂商不具备Camera硬件或者不需要将Camera硬件虚拟化,不需要关注该接口,默认不实现此so即可。

int32_t CameraRegisterSendDataCallback(const char *id, uint32_t idLen, const DMSDPSendBackDataCB cb) { /* regist callback for send data */ (void)id; (void)idLen; (void)cb; return DMSDP_OK; } int32_t OpenCamera(const DMSDPCameraParam *param) { /* open camera */ (void)param; return DMSDP_OK; } int32_t CloseCamera(const char *id, uint32_t idLen) { /* close camera, unregist senddata callback */ (void)id; (void)idLen; return DMSDP_OK; } int32_t CameraUpdateConfig(const char *id, uint32_t idLen, int32_t key, char *value, uint32_t valLen) { /* update camera config: fps */ (void)id; (void)idLen; (void)key; (void)value; (void)valLen; return DMSDP_OK; } void CameraRelease(int32_t type, void *ptr, uint32_t num) { /* release resource if any */ (void)type; (void)ptr; (void)num; return; } int32_t GetCameraCapability(DMSDPCameraCapabilities **capabilities, uint32_t *num) { /* * collect the camera capabilities, * CameraRelease will be called after the function to release the resource allocated */ (void)capabilities; (void)num; return DMSDP_OK; } const char *GetCameraCapabilityString(uint32_t *len) { /* reserved for ide automatic no need to impl */ (void)len; return NULL; } int32_t CameraRegisterListener(const DMSDPListener *listener) { /* regist service state/action listener */ (void)listener; return DMSDP_OK; } int32_t CameraBusinessControl(uint32_t cmd, void *inputPara, uint32_t inLen, void *outputPara, uint32_t outLen) { /* reserved */ (void)cmd; (void)inputPara; (void)inLen; (void)outputPara; (void)outLen; return DMSDP_OK; } int32_t DMSDPGetCameraHandler(DMSDPCameraHandler *cameraHandler) { if (cameraHandler == NULL) { return DMSDP_ERR_NULLPTR; } cameraHandler->RegisterSendDataCallback = CameraRegisterSendDataCallback; cameraHandler->OpenCamera = OpenCamera; cameraHandler->CloseCamera = CloseCamera; cameraHandler->UpdateConfig = CameraUpdateConfig; cameraHandler->GetCameraCapability = GetCameraCapability; cameraHandler->GetCameraCapabilityString = GetCameraCapabilityString; cameraHandler->Release = CameraRelease; cameraHandler->RegisterListener = CameraRegisterListener; cameraHandler->BusinessControl = CameraBusinessControl; return DMSDP_OK; }

6.发南向WiFi适配,智能设备厂商需根据自己驱动实现对应的能力。

static ChannelCallback *g_wifiCallback; static int InitWifi(constvoid *context, constchar *ifName) { /* 初始化WiFi信息 */ return RESULT_RET_OK; } static int DeinitWifi(constvoid *context) { /* 去初始化WiFi信息,移除GO */ return RESULT_RET_OK; } static int WifiGetParam(GetParamsType paramType, void *result) { if (paramType == GET_DEV_MAC) { /* 获取本地MAC地址 */ } else if (paramType == GET_WIFI_ABILITY) { /* 获取设备WiFi能力,支持2.4G/5G */ } else { printf("unknown paramtype\r\n"); return RESULT_RET_ERROR; } return RESULT_RET_OK; } static int WifiSetParam(SetParamsType paramType, constvoid *context) { if (paramType == SET_WIFI_LOCAL_IP) { /* 设置本地IP信息 */ /* 设置IP信息成功,上报EVENT_CONFIG_IP_SUCCESS事件 */ g_wifiCallback->ChannelStateChange(CHANNEL_P2P, EVENT_CONFIG_IP_SUCCESS, NULL, 0); } return RESULT_RET_OK; } static int WifiRegisterCallBack(const ChannelCallback *callback) { /* 注册WiFi回调 */ g_wifiCallback = (ChannelCallback *)callback; return RESULT_RET_OK; } static int WifiCreateAP(constvoid *priv, constvoid *wifiInfo) { /* 根据下发的频率启对应的GO*/ /* GO创建成功,上报EVENT_CREATE_WIFI_SUCCESS事件*/ if (g_wifiCallback != NULL) { g_wifiCallback->ChannelStateChange(CHANNEL_P2P, EVENT_CREATE_WIFI_SUCCESS, &apParams, sizeof(WifiParams)); } return RESULT_RET_OK; } const struct FcDriverAdaptOps g_fcDriverWifiOps = { .name = WIFI_DRIVER_NAME, .desc = "wifi driver", .Init = InitWifi, .Deinit = DeinitWifi, .SetParam = WifiSetParam, .GetParam = WifiGetParam, .RegisterChannelCallback = WifiRegisterCallBack, .CreateWifiChannel = WifiCreateAP, };

7.南向BLE适配,智能设备厂商需根据自己驱动实现对应的能力。

static ChannelCallback *g_bleCallback; static int BleDriverInit(const void *context, const char *ifName) { /*初始化BLE信息 */ /* 启蓝牙GATT服务 */ return 0; } static int BleDriverDeinit(const void *context) { /* 去初始化BLE信息 */ /* 停止蓝牙GATT服务 */ return 0; } static int BleSetParam(SetParamsType paramType, const void *paramValue) { return 0; } static int BleGetParam(GetParamsType paramType, void *result) { /* 获取设备名称 */ if (paramType == GET_DEV_NAME) { *name = "drives name"; } return 0; } static int BleStartAdv(const void *priv) { /* 设置广播参数,开始广播 */ return 0; } static int BleSetAdvData(const void *priv) { /* 设置广播数据 */ /* 设置扫描回复数据 */ return 0; } static int BleStopAdv(const void *priv) { /* 停止广播 */ return 0; } static int BleStartScan(const void *priv) { /* 开始BLE扫描 */ return 0; } static int BleStopScan(const void *priv) { /* 停止BLE扫描 */ return 0; } static int BleDisconnect(const void *priv) { /* BLE连接断开 */ return 0; } static int BleRegisterChannelCallback(const ChannelCallback *channelCallback) { /* 注册BLE回调 */ if (channelCallback) { g_bleCallback = channelCallback; return 0; } return -1; } static int BleNotifyData(const unsigned char *data, int dataLen, const void *priv) { /* server向client发送数据 */ return 0; } const struct FcDriverAdaptOps g_fcAdaptBleOps = { .name = "ble", .desc = "ble driver", .Init = BleDriverInit, .Deinit = BleDriverDeinit, .SetParam = BleSetParam, .GetParam = BleGetParam, .StartAdv = BleStartAdv, .StopAdv = BleStopAdv, .SetAdvData = BleSetAdvData, .StartScan = BleStartScan, .StopScan = BleStopScan, .Connect = BleConnect, .Disconnect = BleDisconnect, .SendData = BleSendData, .NotifyData = BleNotifyData, .RegisterChannelCallback = BleRegisterChannelCallback, };

干得好,你已经成功完成了Codelab并学到了:

您可以阅读下面链接,了解更多相关的信息。
相关文档

下载 source code

已复制代码