1# Driver Message Mechanism Management<a name="EN-US_TOPIC_0000001052657065"></a> 2 3- [When to Use](#section33014541954) 4- [Available APIs](#section538852311616) 5- [How to Develop](#section946912121153) 6 7## When to Use<a name="section33014541954"></a> 8 9When user-level applications need to interact with kernel-level drivers, the driver message mechanism of the HDF can be used. 10 11## Available APIs<a name="section538852311616"></a> 12 13The message mechanism provides the following features: 14 151. User-level applications send messages to drivers. 162. User-level applications receive events sent by the drivers. 17 18**Table 1** APIs for the driver message mechanism 19 20<a name="table208212674114"></a> 21<table><thead align="left"><tr id="row08282618416"><th class="cellrowborder" valign="top" width="46.379999999999995%" id="mcps1.2.3.1.1"><p id="p382132664112"><a name="p382132664112"></a><a name="p382132664112"></a><strong id="b142817619332"><a name="b142817619332"></a><a name="b142817619332"></a>Function</strong></p> 22</th> 23<th class="cellrowborder" valign="top" width="53.620000000000005%" id="mcps1.2.3.1.2"><p id="p4826264419"><a name="p4826264419"></a><a name="p4826264419"></a><strong id="b201539486743916"><a name="b201539486743916"></a><a name="b201539486743916"></a>Description</strong></p> 24</th> 25</tr> 26</thead> 27<tbody><tr id="row1582426174114"><td class="cellrowborder" valign="top" width="46.379999999999995%" headers="mcps1.2.3.1.1 "><p id="p182341916144420"><a name="p182341916144420"></a><a name="p182341916144420"></a>struct HdfIoService *HdfIoServiceBind(const char *serviceName)</p> 28</td> 29<td class="cellrowborder" valign="top" width="53.620000000000005%" headers="mcps1.2.3.1.2 "><p id="p58272614113"><a name="p58272614113"></a><a name="p58272614113"></a>Obtains a specified driver service. After the service is obtained, the <strong id="b9799159433"><a name="b9799159433"></a><a name="b9799159433"></a>Dispatch</strong> function of the service is used to send messages to the driver.</p> 30</td> 31</tr> 32<tr id="row578565084913"><td class="cellrowborder" valign="top" width="46.379999999999995%" headers="mcps1.2.3.1.1 "><p id="p15786185024918"><a name="p15786185024918"></a><a name="p15786185024918"></a>void HdfIoServiceRecycle(struct HdfIoService *service);</p> 33</td> 34<td class="cellrowborder" valign="top" width="53.620000000000005%" headers="mcps1.2.3.1.2 "><p id="p47861750154912"><a name="p47861750154912"></a><a name="p47861750154912"></a>Releases a specified driver service.</p> 35</td> 36</tr> 37<tr id="row1382112617413"><td class="cellrowborder" valign="top" width="46.379999999999995%" headers="mcps1.2.3.1.1 "><p id="p482182611415"><a name="p482182611415"></a><a name="p482182611415"></a>int HdfDeviceRegisterEventListener(struct HdfIoService *target, struct HdfDevEventlistener *listener);</p> 38</td> 39<td class="cellrowborder" valign="top" width="53.620000000000005%" headers="mcps1.2.3.1.2 "><p id="p18825261412"><a name="p18825261412"></a><a name="p18825261412"></a>Receives events sent by the drivers.</p> 40</td> 41</tr> 42<tr id="row498956124019"><td class="cellrowborder" valign="top" width="46.379999999999995%" headers="mcps1.2.3.1.1 "><p id="p6412911184019"><a name="p6412911184019"></a><a name="p6412911184019"></a>int HdfDeviceSendEvent(struct HdfDeviceObject *deviceObject, uint32_t id, struct HdfSBuf *data);</p> 43</td> 44<td class="cellrowborder" valign="top" width="53.620000000000005%" headers="mcps1.2.3.1.2 "><p id="p1698915634018"><a name="p1698915634018"></a><a name="p1698915634018"></a>Sends events.</p> 45</td> 46</tr> 47</tbody> 48</table> 49 50## How to Develop<a name="section946912121153"></a> 51 521. Set the value of the **policy** field in the driver configuration information to **2** \(SERVICE\_POLICY\_CAPACITY, see [Driver Service Management](driver-hdf-servicemanage.md)\). 53 54 ``` 55 device_sample :: Device { 56 policy = 2; 57 ... 58 } 59 ``` 60 612. 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. 623. Implement the **Dispatch** function of the service base member **IDeviceIoService** during service implementation. 63 64 ``` 65 // Process messages delivered by user-level applications. 66 int32_t SampleDriverDispatch(struct HdfDeviceObject *device, int cmdCode, struct HdfSBuf *data, struct HdfSBuf *reply) 67 { 68 HDF_LOGE("sample driver lite A dispatch"); 69 return 0; 70 } 71 int32_t SampleDriverBind(struct HdfDeviceObject *device) 72 { 73 HDF_LOGE("test for lite os sample driver A Open!"); 74 if (device == NULL) { 75 HDF_LOGE("test for lite os sample driver A Open failed!"); 76 return -1; 77 } 78 static struct ISampleDriverService sampleDriverA = { 79 .ioService.Dispatch = SampleDriverDispatch, 80 .ServiceA = SampleDriverServiceA, 81 .ServiceB = SampleDriverServiceB, 82 }; 83 device->service = (struct IDeviceIoService *)(&sampleDriverA); 84 return 0; 85 } 86 ``` 87 884. Define the CMD type in the message processing function. 89 90 ``` 91 #define SAMPLE_WRITE_READ 1 // Read and write operation 1 92 ``` 93 945. Enable the user-level application to obtain the service interface and send messages to the driver. 95 96 ``` 97 int SendMsg(const char *testMsg) 98 { 99 if (testMsg == NULL) { 100 HDF_LOGE("test msg is null"); 101 return -1; 102 } 103 struct HdfIoService *serv = HdfIoServiceBind("sample_driver"); 104 if (serv == NULL) { 105 HDF_LOGE("fail to get service"); 106 return -1; 107 } 108 struct HdfSBuf *data = HdfSBufObtainDefaultSize(); 109 if (data == NULL) { 110 HDF_LOGE("fail to obtain sbuf data"); 111 return -1; 112 } 113 struct HdfSBuf *reply = HdfSBufObtainDefaultSize(); 114 if (reply == NULL) { 115 HDF_LOGE("fail to obtain sbuf reply"); 116 ret = HDF_DEV_ERR_NO_MEMORY; 117 goto out; 118 } 119 if (!HdfSbufWriteString(data, testMsg)) { 120 HDF_LOGE("fail to write sbuf"); 121 ret = HDF_FAILURE; 122 goto out; 123 } 124 int ret = serv->dispatcher->Dispatch(&serv->object, SAMPLE_WRITE_READ, data, reply); 125 if (ret != HDF_SUCCESS) { 126 HDF_LOGE("fail to send service call"); 127 goto out; 128 } 129 out: 130 HdfSBufRecycle(data); 131 HdfSBufRecycle(reply); 132 HdfIoServiceRecycle(serv); 133 return ret; 134 } 135 ``` 136 1376. Enable the user-level application to receive messages reported by the driver. 138 1. Enable the user-level application to compile the function for processing messages reported by the driver. 139 140 ``` 141 static int OnDevEventReceived(void *priv, uint32_t id, struct HdfSBuf *data) 142 { 143 OsalTimespec time; 144 OsalGetTime(&time); 145 HDF_LOGE("%s received event at %llu.%llu", (char *)priv, time.sec, time.usec); 146 147 const char *string = HdfSbufReadString(data); 148 if (string == NULL) { 149 HDF_LOGE("fail to read string in event data"); 150 return -1; 151 } 152 HDF_LOGE("%s: dev event received: %d %s", (char *)priv, id, string); 153 return 0; 154 } 155 ``` 156 157 2. Enable the user-level application to register the function for receiving messages reported by the driver. 158 159 ``` 160 int RegisterListen() 161 { 162 struct HdfIoService *serv = HdfIoServiceBind("sample_driver"); 163 if (serv == NULL) { 164 HDF_LOGE("fail to get service"); 165 return -1; 166 } 167 static struct HdfDevEventlistener listener = { 168 .callBack = OnDevEventReceived, 169 .priv ="Service0" 170 }; 171 if (HdfDeviceRegisterEventListener(serv, &listener) != 0) { 172 HDF_LOGE("fail to register event listener"); 173 return -1; 174 } 175 ...... 176 HdfDeviceUnregisterEventListener(serv, &listener); 177 HdfIoServiceRecycle(serv); 178 return 0; 179 } 180 ``` 181 182 3. Enable the driver to report events. 183 184 ``` 185 int32_t SampleDriverDispatch(struct HdfDeviceObject *device, int cmdCode, struct HdfSBuf *data, struct HdfSBuf *reply) 186 { 187 ... // process api call here 188 return HdfDeviceSendEvent(deviceObject, cmdCode, data); 189 } 190 ``` 191 192 193 194