# Driver Message Mechanism Management - [When to Use](#section33014541954) - [Available APIs](#section538852311616) - [How to Develop](#section946912121153) ## When to Use When user-level applications need to interact with kernel-level drivers, the driver message mechanism of the HDF can be used. ## Available APIs The message mechanism provides the following features: 1. User-level applications send messages to drivers. 2. User-level applications receive events sent by the drivers. **Table 1** APIs for the driver message mechanism

Function

Description

struct HdfIoService *HdfIoServiceBind(const char *serviceName)

Obtains a specified driver service. After the service is obtained, the Dispatch function of the service is used to send messages to the driver.

void HdfIoServiceRecycle(struct HdfIoService *service);

Releases a specified driver service.

int HdfDeviceRegisterEventListener(struct HdfIoService *target, struct HdfDevEventlistener *listener);

Receives events sent by the drivers.

int HdfDeviceSendEvent(struct HdfDeviceObject *deviceObject, uint32_t id, struct HdfSBuf *data);

Sends events.

## How to Develop 1. Set the value of the **policy** field in the driver configuration information to **2** \(SERVICE\_POLICY\_CAPACITY, see [Driver Service Management](driver-service-management.md)\). ``` device_sample :: Device { policy = 2; ... } ``` 2. The **permission** field in the driver configuration information indicates the permission provided for the driver to create device nodes. The default value is **0666**. You can configure the value of this field based on the actual application scenario of the driver. 3. Implement the **Dispatch** function of the service base member **IDeviceIoService** during service implementation. ``` // Process messages delivered by user-level applications. int32_t SampleDriverDispatch(struct HdfDeviceObject *device, int cmdCode, struct HdfSBuf *data, struct HdfSBuf *reply) { HDF_LOGE("sample driver lite A dispatch"); return 0; } int32_t SampleDriverBind(struct HdfDeviceObject *device) { HDF_LOGE("test for lite os sample driver A Open!"); if (device == NULL) { HDF_LOGE("test for lite os sample driver A Open failed!"); return -1; } static struct ISampleDriverService sampleDriverA = { .ioService.Dispatch = SampleDriverDispatch, .ServiceA = SampleDriverServiceA, .ServiceB = SampleDriverServiceB, }; device->service = (struct IDeviceIoService *)(&sampleDriverA); return 0; } ``` 4. Define the CMD type in the message processing function. ``` #define SAMPLE_WRITE_READ 1 // Read and write operation 1 ``` 5. Enable the user-level application to obtain the service interface and send messages to the driver. ``` int SendMsg(const char *testMsg) { if (testMsg == NULL) { HDF_LOGE("test msg is null"); return -1; } struct HdfIoService *serv = HdfIoServiceBind("sample_driver"); if (serv == NULL) { HDF_LOGE("fail to get service"); return -1; } struct HdfSBuf *data = HdfSBufObtainDefaultSize(); if (data == NULL) { HDF_LOGE("fail to obtain sbuf data"); return -1; } struct HdfSBuf *reply = HdfSBufObtainDefaultSize(); if (reply == NULL) { HDF_LOGE("fail to obtain sbuf reply"); ret = HDF_DEV_ERR_NO_MEMORY; goto out; } if (!HdfSbufWriteString(data, testMsg)) { HDF_LOGE("fail to write sbuf"); ret = HDF_FAILURE; goto out; } int ret = serv->dispatcher->Dispatch(&serv->object, SAMPLE_WRITE_READ, data, reply); if (ret != HDF_SUCCESS) { HDF_LOGE("fail to send service call"); goto out; } out: HdfSBufRecycle(data); HdfSBufRecycle(reply); HdfIoServiceRecycle(serv); return ret; } ``` 6. Enable the user-level application to receive messages reported by the driver. 1. Enable the user-level application to compile the function for processing messages reported by the driver. ``` static int OnDevEventReceived(void *priv, uint32_t id, struct HdfSBuf *data) { OsalTimespec time; OsalGetTime(&time); HDF_LOGE("%s received event at %llu.%llu", (char *)priv, time.sec, time.usec); const char *string = HdfSbufReadString(data); if (string == NULL) { HDF_LOGE("fail to read string in event data"); return -1; } HDF_LOGE("%s: dev event received: %d %s", (char *)priv, id, string); return 0; } ``` 2. Enable the user-level application to register the function for receiving messages reported by the driver. ``` int RegisterListen() { struct HdfIoService *serv = HdfIoServiceBind("sample_driver"); if (serv == NULL) { HDF_LOGE("fail to get service"); return -1; } static struct HdfDevEventlistener listener = { .callBack = OnDevEventReceived, .priv ="Service0" }; if (HdfDeviceRegisterEventListener(serv, &listener) != 0) { HDF_LOGE("fail to register event listener"); return -1; } ...... HdfDeviceUnregisterEventListener(serv, &listener); HdfIoServiceRecycle(serv); return 0; } ``` 3. Enable the driver to report events. ``` int32_t SampleDriverDispatch(struct HdfDeviceObject *device, int cmdCode, struct HdfSBuf *data, struct HdfSBuf *reply) { ... // process api call here return HdfDeviceSendEvent(deviceObject, cmdCode, data); } ```