1 /*
2 * Copyright (c) 2023 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16 #include "audio_adapter_vdi.h"
17
18 #include <limits.h>
19 #include "osal_mem.h"
20 #include "securec.h"
21 #include <hdf_base.h>
22 #include "audio_uhdf_log.h"
23 #include "audio_capture_vdi.h"
24 #include "audio_common_vdi.h"
25 #include "audio_render_vdi.h"
26 #include "audio_dfx.h"
27 #include "v5_0/iaudio_callback.h"
28 #include "stub_collector.h"
29
30 #define HDF_LOG_TAG HDF_AUDIO_PRIMARY_IMPL
31 static pthread_rwlock_t g_rwAdapterLock = PTHREAD_RWLOCK_INITIALIZER;
32
33 struct AudioAdapterInfo {
34 struct IAudioAdapterVdi *vdiAdapter;
35 struct IAudioAdapter *adapter;
36 uint32_t refCnt;
37 char *adapterName;
38 };
39
40 struct AudioAdapterPrivVdi {
41 struct AudioAdapterInfo adapterInfo[AUDIO_VDI_ADAPTER_NUM_MAX];
42 struct IAudioCallback *callback;
43 bool isRegCb;
44 };
45
46 static struct AudioAdapterPrivVdi g_audioAdapterVdi;
47
AudioAdapterGetPrivVdi(void)48 static struct AudioAdapterPrivVdi *AudioAdapterGetPrivVdi(void)
49 {
50 return &g_audioAdapterVdi;
51 }
52
AudioGetVdiAdapterByDescIndexVdi(uint32_t descIndex)53 struct IAudioAdapterVdi *AudioGetVdiAdapterByDescIndexVdi(uint32_t descIndex)
54 {
55 struct AudioAdapterPrivVdi *priv = AudioAdapterGetPrivVdi();
56
57 if (descIndex >= AUDIO_VDI_ADAPTER_NUM_MAX) {
58 AUDIO_FUNC_LOGE("get vdiAdapter error, descIndex=%{public}d", descIndex);
59 return NULL;
60 }
61
62 return priv->adapterInfo[descIndex].vdiAdapter;
63 }
64
AudioGetVdiAdapterVdi(const struct IAudioAdapter * adapter)65 static struct IAudioAdapterVdi *AudioGetVdiAdapterVdi(const struct IAudioAdapter *adapter)
66 {
67 struct AudioAdapterPrivVdi *priv = AudioAdapterGetPrivVdi();
68
69 if (adapter == NULL) {
70 AUDIO_FUNC_LOGE("get vdiAdapter error");
71 return NULL;
72 }
73
74 for (uint32_t i = 0; i < AUDIO_VDI_ADAPTER_NUM_MAX; i++) {
75 if (adapter == priv->adapterInfo[i].adapter) {
76 return priv->adapterInfo[i].vdiAdapter;
77 }
78 }
79
80 AUDIO_FUNC_LOGE("audio get vdiadapter fail");
81 return NULL;
82 }
83
AudioGetAdapterNameVdi(const struct IAudioAdapter * adapter)84 static char *AudioGetAdapterNameVdi(const struct IAudioAdapter *adapter)
85 {
86 struct AudioAdapterPrivVdi *priv = AudioAdapterGetPrivVdi();
87
88 if (adapter == NULL) {
89 AUDIO_FUNC_LOGE("get AdapterName error");
90 return NULL;
91 }
92
93 for (uint32_t i = 0; i < AUDIO_VDI_ADAPTER_NUM_MAX; i++) {
94 if (adapter == priv->adapterInfo[i].adapter) {
95 return priv->adapterInfo[i].adapterName;
96 }
97 }
98
99 AUDIO_FUNC_LOGE("audio get adapterName fail");
100 return NULL;
101 }
102
AudioInitAllPortsVdi(struct IAudioAdapter * adapter)103 static int32_t AudioInitAllPortsVdi(struct IAudioAdapter *adapter)
104 {
105 pthread_rwlock_rdlock(&g_rwAdapterLock);
106 int32_t ret = HDF_SUCCESS;
107 if (adapter == NULL) {
108 AUDIO_FUNC_LOGE("invalid param");
109 ret = HDF_ERR_INVALID_PARAM;
110 goto EXIT;
111 }
112
113 struct IAudioAdapterVdi *vdiAdapter = AudioGetVdiAdapterVdi(adapter);
114 if (vdiAdapter == NULL || vdiAdapter->InitAllPorts == NULL) {
115 AUDIO_FUNC_LOGE("invalid param");
116 ret = HDF_ERR_INVALID_PARAM;
117 goto EXIT;
118 }
119
120 HdfAudioStartTrace("Hdi:Audio:InitAllPorts", 0);
121 ret = vdiAdapter->InitAllPorts(vdiAdapter);
122 HdfAudioFinishTrace();
123
124 if (ret != HDF_SUCCESS) {
125 AUDIO_FUNC_LOGE("audio vdiAdapter InitAllPorts fail, ret=%{public}d", ret);
126 ret = HDF_FAILURE;
127 goto EXIT;
128 }
129 EXIT:
130 pthread_rwlock_unlock(&g_rwAdapterLock);
131 return ret;
132 }
133
VerifyParamsOfAudioCreateRenderVdi(struct IAudioAdapter * adapter,const struct AudioDeviceDescriptor * desc,const struct AudioSampleAttributes * attrs,struct IAudioRender ** render,uint32_t * renderId)134 static int32_t VerifyParamsOfAudioCreateRenderVdi(struct IAudioAdapter *adapter,
135 const struct AudioDeviceDescriptor *desc, const struct AudioSampleAttributes *attrs,
136 struct IAudioRender **render, uint32_t *renderId)
137 {
138 CHECK_NULL_PTR_RETURN_VALUE(adapter, HDF_ERR_INVALID_PARAM);
139 CHECK_NULL_PTR_RETURN_VALUE(desc, HDF_ERR_INVALID_PARAM);
140 CHECK_NULL_PTR_RETURN_VALUE(attrs, HDF_ERR_INVALID_PARAM);
141 CHECK_NULL_PTR_RETURN_VALUE(render, HDF_ERR_INVALID_PARAM);
142 CHECK_NULL_PTR_RETURN_VALUE(renderId, HDF_ERR_INVALID_PARAM);
143
144 if (desc->pins == PIN_OUT_LINEOUT || desc->pins == PIN_NONE || desc->pins >= PIN_IN_MIC) {
145 AUDIO_FUNC_LOGE("invalid pin [%{public}d]", desc->pins);
146 return HDF_FAILURE;
147 }
148 return HDF_SUCCESS;
149 }
150
CreateRenderPre(struct IAudioAdapterVdi * vdiAdapter,const struct AudioDeviceDescriptor * desc,const struct AudioSampleAttributes * attrs,uint32_t * renderId,struct IAudioRenderVdi ** vdiRender)151 static int32_t CreateRenderPre(struct IAudioAdapterVdi *vdiAdapter,
152 const struct AudioDeviceDescriptor *desc, const struct AudioSampleAttributes *attrs,
153 uint32_t *renderId, struct IAudioRenderVdi **vdiRender)
154 {
155 struct AudioDeviceDescriptorVdi vdiDesc;
156 struct AudioSampleAttributesVdi vdiAttrs;
157 if (AudioCommonDevDescToVdiDevDescVdi(desc, &vdiDesc) != HDF_SUCCESS) {
158 AUDIO_FUNC_LOGE("desc to vdiDesc fail");
159 return HDF_FAILURE;
160 }
161 AudioCommonAttrsToVdiAttrsVdi(attrs, &vdiAttrs);
162
163 int32_t id = SetTimer("Hdi:CreateRender");
164 pthread_rwlock_wrlock(GetRenderLock());
165 struct timeval startTime = AudioDfxSysEventGetTimeStamp();
166 int32_t ret = vdiAdapter->CreateRender(vdiAdapter, &vdiDesc, &vdiAttrs, vdiRender);
167 AudioDfxSysEventError("CreateRender", startTime, TIME_THRESHOLD, ret);
168 pthread_rwlock_unlock(GetRenderLock());
169 CancelTimer(id);
170 OsalMemFree((void *)vdiDesc.desc);
171 if (ret != HDF_SUCCESS) {
172 AUDIO_FUNC_LOGE("audio vdiAdapter call CreateRender fail, ret=%{public}d", ret);
173 return ret;
174 }
175 (*vdiRender)->AddAudioEffect = NULL;
176 (*vdiRender)->RemoveAudioEffect = NULL;
177 (*vdiRender)->GetFrameBufferSize = NULL;
178 (*vdiRender)->IsSupportsPauseAndResume = NULL;
179
180 return HDF_SUCCESS;
181 }
182
AudioCreateRenderVdi(struct IAudioAdapter * adapter,const struct AudioDeviceDescriptor * desc,const struct AudioSampleAttributes * attrs,struct IAudioRender ** render,uint32_t * renderId)183 static int32_t AudioCreateRenderVdi(struct IAudioAdapter *adapter, const struct AudioDeviceDescriptor *desc,
184 const struct AudioSampleAttributes *attrs, struct IAudioRender **render, uint32_t *renderId)
185 {
186 pthread_rwlock_rdlock(&g_rwAdapterLock);
187 AUDIO_FUNC_LOGD("enter to %{public}s", __func__);
188
189 int32_t ret = VerifyParamsOfAudioCreateRenderVdi(adapter, desc, attrs, render, renderId);
190 if (ret != HDF_SUCCESS) {
191 AUDIO_FUNC_LOGE("invalid param");
192 goto EXIT;
193 }
194
195 struct IAudioAdapterVdi *vdiAdapter = AudioGetVdiAdapterVdi(adapter);
196 if (vdiAdapter == NULL || vdiAdapter->CreateRender == NULL || vdiAdapter->DestroyRender == NULL) {
197 AUDIO_FUNC_LOGE("invalid param");
198 ret = HDF_ERR_INVALID_PARAM;
199 goto EXIT;
200 }
201
202 char *adapterName = AudioGetAdapterNameVdi(adapter);
203 *render = FindRenderCreated(desc->pins, attrs, renderId, adapterName);
204 if (*render != NULL) {
205 AUDIO_FUNC_LOGE("already created");
206 ret = HDF_SUCCESS;
207 goto EXIT;
208 }
209 struct IAudioRenderVdi *vdiRender = NULL;
210 ret = CreateRenderPre(vdiAdapter, desc, attrs, renderId, &vdiRender);
211 if (ret != HDF_SUCCESS) {
212 AUDIO_FUNC_LOGE("CreateRenderPre failed, ret = [%{public}d]", ret);
213 goto EXIT;
214 }
215 *render = AudioCreateRenderByIdVdi(attrs, renderId, vdiRender, desc, adapterName);
216 if (*render == NULL) {
217 (void)vdiAdapter->DestroyRender(vdiAdapter, vdiRender);
218 AUDIO_FUNC_LOGE("Create audio render failed");
219 ret = HDF_FAILURE;
220 goto EXIT;
221 }
222 AUDIO_FUNC_LOGI("AudioCreateRenderVdi Success, renderId = [%{public}u]", *renderId);
223 EXIT:
224 pthread_rwlock_unlock(&g_rwAdapterLock);
225 return ret;
226 }
227
AudioDestroyRenderVdi(struct IAudioAdapter * adapter,uint32_t renderId)228 static int32_t AudioDestroyRenderVdi(struct IAudioAdapter *adapter, uint32_t renderId)
229 {
230 pthread_rwlock_rdlock(&g_rwAdapterLock);
231 AUDIO_FUNC_LOGD("enter to %{public}s", __func__);
232 int32_t ret = HDF_SUCCESS;
233 if (adapter == NULL) {
234 AUDIO_FUNC_LOGE("invalid param");
235 ret = HDF_ERR_INVALID_PARAM;
236 goto EXIT;
237 }
238 if (renderId < 0 || renderId > AUDIO_VDI_STREAM_NUM_MAX - 1) {
239 AUDIO_FUNC_LOGE("renderId is invalid[%{public}u] and return ret=%{public}d", renderId, ret);
240 ret = HDF_ERR_INVALID_PARAM;
241 goto EXIT;
242 }
243 if (DecreaseRenderUsrCount(renderId) > 0) {
244 AUDIO_FUNC_LOGE("render destroy: more than one usr");
245 ret = HDF_SUCCESS;
246 goto EXIT;
247 }
248 struct IAudioAdapterVdi *vdiAdapter = AudioGetVdiAdapterVdi(adapter);
249 if (vdiAdapter == NULL) {
250 AUDIO_FUNC_LOGE("invalid param");
251 ret = HDF_ERR_INVALID_PARAM;
252 goto EXIT;
253 }
254
255 struct IAudioRenderVdi *vdiRender = AudioGetVdiRenderByIdVdi(renderId);
256 if (vdiRender == NULL) {
257 AUDIO_FUNC_LOGE("vdiRender pointer is null");
258 ret = HDF_ERR_INVALID_PARAM;
259 goto EXIT;
260 }
261 if (vdiAdapter->DestroyRender == NULL) {
262 AUDIO_FUNC_LOGE("invalid param");
263 ret = HDF_ERR_INVALID_PARAM;
264 goto EXIT;
265 }
266 pthread_rwlock_wrlock(GetRenderLock());
267 ret = vdiAdapter->DestroyRender(vdiAdapter, vdiRender);
268 pthread_rwlock_unlock(GetRenderLock());
269 if (ret != HDF_SUCCESS) {
270 AUDIO_FUNC_LOGE("audio vdiAdapter call DestroyRender fail, ret=%{public}d", ret);
271 ret = HDF_FAILURE;
272 goto EXIT;
273 }
274 AudioDestroyRenderByIdVdi(renderId);
275 EXIT:
276 pthread_rwlock_unlock(&g_rwAdapterLock);
277 return ret;
278 }
279
CreateCapturePre(struct IAudioAdapterVdi * vdiAdapter,struct IAudioCapture ** capture,const struct AudioDeviceDescriptor * desc,const struct AudioSampleAttributes * attrs,uint32_t * captureId)280 static int32_t CreateCapturePre(struct IAudioAdapterVdi *vdiAdapter, struct IAudioCapture **capture,
281 const struct AudioDeviceDescriptor *desc, const struct AudioSampleAttributes *attrs, uint32_t *captureId)
282 {
283 struct IAudioCaptureVdi *vdiCapture = NULL;
284 struct AudioDeviceDescriptorVdi vdiDesc;
285 struct AudioSampleAttributesVdi vdiAttrs;
286 (void)memset_s((void *)&vdiDesc, sizeof(vdiDesc), 0, sizeof(vdiDesc));
287 (void)memset_s((void *)&vdiAttrs, sizeof(vdiAttrs), 0, sizeof(vdiAttrs));
288 if (AudioCommonDevDescToVdiDevDescVdi(desc, &vdiDesc) != HDF_SUCCESS) {
289 AUDIO_FUNC_LOGE("Desc to VdiDesc fail");
290 return HDF_FAILURE;
291 }
292 AudioCommonAttrsToVdiAttrsVdi(attrs, &vdiAttrs);
293
294 if (vdiAdapter == NULL || vdiAdapter->CreateCapture == NULL || vdiAdapter->DestroyCapture == NULL) {
295 AUDIO_FUNC_LOGE("invalid param");
296 OsalMemFree((void *)vdiDesc.desc);
297 return HDF_ERR_INVALID_PARAM;
298 }
299 int32_t id = SetTimer("Hdi:CreateCapture");
300 pthread_rwlock_wrlock(GetCaptureLock());
301 struct timeval startTime = AudioDfxSysEventGetTimeStamp();
302 int32_t ret = vdiAdapter->CreateCapture(vdiAdapter, &vdiDesc, &vdiAttrs, &vdiCapture);
303 AudioDfxSysEventError("CreateCapture", startTime, TIME_THRESHOLD, ret);
304 pthread_rwlock_unlock(GetCaptureLock());
305 CancelTimer(id);
306 OsalMemFree((void *)vdiDesc.desc);
307 if (ret != HDF_SUCCESS) {
308 AUDIO_FUNC_LOGE("audio vdiAdapter call CreateCapture fail, ret=%{public}d", ret);
309 return HDF_FAILURE;
310 }
311 vdiCapture->AddAudioEffect = NULL;
312 vdiCapture->RemoveAudioEffect = NULL;
313 vdiCapture->GetFrameBufferSize = NULL;
314 vdiCapture->IsSupportsPauseAndResume = NULL;
315 *capture = AudioCreateCaptureByIdVdi(attrs, captureId, vdiCapture, desc);
316 if (*capture == NULL) {
317 (void)vdiAdapter->DestroyCapture(vdiAdapter, vdiCapture);
318 AUDIO_FUNC_LOGE("create audio capture failed");
319 return HDF_ERR_INVALID_PARAM;
320 }
321 return HDF_SUCCESS;
322 }
323
AudioCreateCaptureVdi(struct IAudioAdapter * adapter,const struct AudioDeviceDescriptor * desc,const struct AudioSampleAttributes * attrs,struct IAudioCapture ** capture,uint32_t * captureId)324 static int32_t AudioCreateCaptureVdi(struct IAudioAdapter *adapter, const struct AudioDeviceDescriptor *desc,
325 const struct AudioSampleAttributes *attrs, struct IAudioCapture **capture, uint32_t *captureId)
326 {
327 pthread_rwlock_rdlock(&g_rwAdapterLock);
328 AUDIO_FUNC_LOGD("enter to %{public}s", __func__);
329 int32_t ret = HDF_SUCCESS;
330 struct IAudioAdapterVdi *vdiAdapter = AudioGetVdiAdapterVdi(adapter);
331 if (vdiAdapter == NULL || desc == NULL || attrs == NULL || capture == NULL || captureId == NULL) {
332 AUDIO_FUNC_LOGE("invalid param");
333 ret = HDF_ERR_INVALID_PARAM;
334 goto EXIT;
335 }
336 ret = CreateCapturePre(vdiAdapter, capture, desc, attrs, captureId);
337 if (*capture == NULL || ret != HDF_SUCCESS) {
338 AUDIO_FUNC_LOGE("create audio capture failed");
339 goto EXIT;
340 }
341 AUDIO_FUNC_LOGI("AudioCreateCaptureVdi Success, captureId = [%{public}u]", *captureId);
342 EXIT:
343 pthread_rwlock_unlock(&g_rwAdapterLock);
344 return ret;
345 }
346
AudioDestroyCaptureVdi(struct IAudioAdapter * adapter,uint32_t captureId)347 static int32_t AudioDestroyCaptureVdi(struct IAudioAdapter *adapter, uint32_t captureId)
348 {
349 pthread_rwlock_rdlock(&g_rwAdapterLock);
350 AUDIO_FUNC_LOGD("enter to %{public}s", __func__);
351 int32_t ret = HDF_SUCCESS;
352 if (adapter == NULL) {
353 AUDIO_FUNC_LOGE("invalid param");
354 ret = HDF_ERR_INVALID_PARAM;
355 goto EXIT;
356 }
357 if (captureId < 0 || captureId > AUDIO_VDI_STREAM_NUM_MAX - 1) {
358 AUDIO_FUNC_LOGE("captureId is invalid[%{public}u] and return ret=%{public}d", captureId, ret);
359 ret = HDF_ERR_INVALID_PARAM;
360 goto EXIT;
361 }
362 if (DecreaseCaptureUsrCount(captureId) > 0) {
363 AUDIO_FUNC_LOGE("capture destroy: more than one usr");
364 ret = HDF_SUCCESS;
365 goto EXIT;
366 }
367
368 struct IAudioAdapterVdi *vdiAdapter = AudioGetVdiAdapterVdi(adapter);
369 if (vdiAdapter == NULL) {
370 AUDIO_FUNC_LOGE("invalid param");
371 ret = HDF_ERR_INVALID_PARAM;
372 goto EXIT;
373 }
374
375 struct IAudioCaptureVdi *vdiCapture = AudioGetVdiCaptureByIdVdi(captureId);
376 if (vdiCapture == NULL || vdiAdapter->DestroyCapture == NULL) {
377 AUDIO_FUNC_LOGE("invalid parameter");
378 ret = HDF_ERR_INVALID_PARAM;
379 goto EXIT;
380 }
381 pthread_rwlock_wrlock(GetCaptureLock());
382 ret = vdiAdapter->DestroyCapture(vdiAdapter, vdiCapture);
383 pthread_rwlock_unlock(GetCaptureLock());
384 if (ret != HDF_SUCCESS) {
385 AUDIO_FUNC_LOGE("audio vdiAdapter call DestroyCapture fail, ret=%{public}d", ret);
386 ret = HDF_FAILURE;
387 goto EXIT;
388 }
389 AudioDestroyCaptureByIdVdi(captureId);
390 EXIT:
391 pthread_rwlock_unlock(&g_rwAdapterLock);
392 return ret;
393 }
394
AudioGetPortCapabilityVdi(struct IAudioAdapter * adapter,const struct AudioPort * port,struct AudioPortCapability * capability)395 static int32_t AudioGetPortCapabilityVdi(struct IAudioAdapter *adapter, const struct AudioPort *port,
396 struct AudioPortCapability* capability)
397 {
398 pthread_rwlock_rdlock(&g_rwAdapterLock);
399 int32_t ret = HDF_SUCCESS;
400 if (adapter == NULL || port == NULL || capability == NULL) {
401 AUDIO_FUNC_LOGE("invalid param");
402 ret = HDF_ERR_INVALID_PARAM;
403 goto EXIT;
404 }
405
406 struct IAudioAdapterVdi *vdiAdapter = AudioGetVdiAdapterVdi(adapter);
407 if (vdiAdapter == NULL || vdiAdapter->GetPortCapability == NULL) {
408 AUDIO_FUNC_LOGE("invalid param");
409 ret = HDF_ERR_INVALID_PARAM;
410 goto EXIT;
411 }
412 struct AudioPortCapabilityVdi vdiCap;
413 struct AudioPortVdi vdiPort;
414 (void)memset_s(&vdiCap, sizeof(vdiCap), 0, sizeof(vdiCap));
415 (void)memset_s(&vdiPort, sizeof(vdiPort), 0, sizeof(vdiPort));
416
417 ret = AudioCommonPortToVdiPortVdi(port, &vdiPort);
418 if (ret != HDF_SUCCESS) {
419 OsalMemFree((void *)vdiPort.portName);
420 AUDIO_FUNC_LOGE("audio vdiAdapter call PortCapToVdiPortCap fail, ret=%{public}d", ret);
421 goto EXIT;
422 }
423
424 ret = vdiAdapter->GetPortCapability(vdiAdapter, &vdiPort, &vdiCap);
425 OsalMemFree((void *)vdiPort.portName);
426 if (ret != HDF_SUCCESS) {
427 AUDIO_FUNC_LOGE("audio vdiAdapter call GetPortCapability fail, ret=%{public}d", ret);
428 goto EXIT;
429 }
430
431 AudioCommonVdiPortCapToPortCapVdi(&vdiCap, capability);
432 EXIT:
433 pthread_rwlock_unlock(&g_rwAdapterLock);
434 return ret;
435 }
436
AudioSetPassthroughModeVdi(struct IAudioAdapter * adapter,const struct AudioPort * port,enum AudioPortPassthroughMode mode)437 static int32_t AudioSetPassthroughModeVdi(struct IAudioAdapter *adapter, const struct AudioPort *port,
438 enum AudioPortPassthroughMode mode)
439 {
440 pthread_rwlock_rdlock(&g_rwAdapterLock);
441 int32_t ret = HDF_SUCCESS;
442 if (adapter == NULL || port == NULL) {
443 AUDIO_FUNC_LOGE("invalid param");
444 ret = HDF_ERR_INVALID_PARAM;
445 goto EXIT;
446 }
447
448 struct IAudioAdapterVdi *vdiAdapter = AudioGetVdiAdapterVdi(adapter);
449 if (vdiAdapter == NULL || vdiAdapter->SetPassthroughMode == NULL) {
450 AUDIO_FUNC_LOGE("invalid param");
451 ret = HDF_ERR_INVALID_PARAM;
452 goto EXIT;
453 }
454
455 struct AudioPortVdi vdiPort;
456 (void)memset_s((void *)&vdiPort, sizeof(vdiPort), 0, sizeof(vdiPort));
457 ret = AudioCommonPortToVdiPortVdi(port, &vdiPort);
458 if (ret != HDF_SUCCESS) {
459 OsalMemFree((void *)vdiPort.portName);
460 AUDIO_FUNC_LOGE("audio vdiAdapter call PortCapToVdiPortCap fail, ret=%{public}d", ret);
461 goto EXIT;
462 }
463
464 ret = vdiAdapter->SetPassthroughMode(vdiAdapter, &vdiPort, (enum AudioPortPassthroughModeVdi)mode);
465 OsalMemFree((void *)vdiPort.portName);
466 if (ret != HDF_SUCCESS) {
467 AUDIO_FUNC_LOGE("audio vdiAdapter call SetPassthroughMode fail, ret=%{public}d", ret);
468 ret = HDF_FAILURE;
469 goto EXIT;
470 }
471
472 EXIT:
473 pthread_rwlock_unlock(&g_rwAdapterLock);
474 return ret;
475 }
476
AudioGetPassthroughModeVdi(struct IAudioAdapter * adapter,const struct AudioPort * port,enum AudioPortPassthroughMode * mode)477 static int32_t AudioGetPassthroughModeVdi(struct IAudioAdapter *adapter, const struct AudioPort *port,
478 enum AudioPortPassthroughMode *mode)
479 {
480 pthread_rwlock_rdlock(&g_rwAdapterLock);
481 int32_t ret = HDF_SUCCESS;
482 if (adapter == NULL || port == NULL || mode == NULL) {
483 AUDIO_FUNC_LOGE("invalid param");
484 ret = HDF_ERR_INVALID_PARAM;
485 goto EXIT;
486 }
487
488 struct IAudioAdapterVdi *vdiAdapter = AudioGetVdiAdapterVdi(adapter);
489 if (vdiAdapter == NULL || vdiAdapter->GetPassthroughMode == NULL) {
490 AUDIO_FUNC_LOGE("invalid param");
491 ret = HDF_ERR_INVALID_PARAM;
492 goto EXIT;
493 }
494
495 struct AudioPortVdi vdiPort;
496 (void)memset_s((void *)&vdiPort, sizeof(vdiPort), 0, sizeof(vdiPort));
497 ret = AudioCommonPortToVdiPortVdi(port, &vdiPort);
498 if (ret != HDF_SUCCESS) {
499 OsalMemFree((void *)vdiPort.portName);
500 AUDIO_FUNC_LOGE("audio vdiAdapter call PortCapToVdiPortCap fail, ret=%{public}d", ret);
501 goto EXIT;
502 }
503
504 ret = vdiAdapter->GetPassthroughMode(vdiAdapter, &vdiPort, (enum AudioPortPassthroughModeVdi *)mode);
505 OsalMemFree((void *)vdiPort.portName);
506 if (ret != HDF_SUCCESS) {
507 AUDIO_FUNC_LOGE("audio vdiAdapter call GetPassthroughMode fail, ret=%{public}d", ret);
508 ret = HDF_FAILURE;
509 goto EXIT;
510 }
511
512 EXIT:
513 pthread_rwlock_unlock(&g_rwAdapterLock);
514 return ret;
515 }
516
AudioGetDeviceStatusVdi(struct IAudioAdapter * adapter,struct AudioDeviceStatus * status)517 static int32_t AudioGetDeviceStatusVdi(struct IAudioAdapter *adapter, struct AudioDeviceStatus *status)
518 {
519 pthread_rwlock_rdlock(&g_rwAdapterLock);
520 int32_t ret = HDF_SUCCESS;
521 if (adapter == NULL || status == NULL) {
522 AUDIO_FUNC_LOGE("invalid param");
523 ret = HDF_ERR_INVALID_PARAM;
524 goto EXIT;
525 }
526
527 struct IAudioAdapterVdi *vdiAdapter = AudioGetVdiAdapterVdi(adapter);
528 if (vdiAdapter == NULL || vdiAdapter->GetDeviceStatus == NULL) {
529 AUDIO_FUNC_LOGE("invalid param");
530 ret = HDF_ERR_INVALID_PARAM;
531 goto EXIT;
532 }
533
534 struct AudioDeviceStatusVdi vdiStatus;
535 (void)memset_s((void *)&vdiStatus, sizeof(vdiStatus), 0, sizeof(vdiStatus));
536 ret = vdiAdapter->GetDeviceStatus(vdiAdapter, &vdiStatus);
537 if (ret != HDF_SUCCESS) {
538 AUDIO_FUNC_LOGE("audio vdiAdapter call GetDeviceStatus fail, ret=%{public}d", ret);
539 ret = HDF_FAILURE;
540 goto EXIT;
541 }
542
543 status->pnpStatus = vdiStatus.pnpStatus;
544 EXIT:
545 pthread_rwlock_unlock(&g_rwAdapterLock);
546 return ret;
547 }
548
AudioUpdateAudioRouteVdi(struct IAudioAdapter * adapter,const struct AudioRoute * route,int32_t * routeHandle)549 static int32_t AudioUpdateAudioRouteVdi(struct IAudioAdapter *adapter,
550 const struct AudioRoute *route, int32_t *routeHandle)
551 {
552 pthread_rwlock_rdlock(&g_rwAdapterLock);
553 int32_t ret = HDF_SUCCESS;
554 if (adapter == NULL || route == NULL || routeHandle == NULL) {
555 AUDIO_FUNC_LOGE("invalid param");
556 ret = HDF_ERR_INVALID_PARAM;
557 goto EXIT;
558 }
559
560 if (route->sinksLen == 0 && route->sourcesLen == 0) {
561 AUDIO_FUNC_LOGE("invalid route value");
562 ret = HDF_FAILURE;
563 goto EXIT;
564 }
565
566 struct IAudioAdapterVdi *vdiAdapter = AudioGetVdiAdapterVdi(adapter);
567 if (vdiAdapter == NULL || vdiAdapter->UpdateAudioRoute == NULL) {
568 AUDIO_FUNC_LOGE("invalid param");
569 ret = HDF_ERR_INVALID_PARAM;
570 goto EXIT;
571 }
572
573 struct AudioRouteVdi vdiRoute;
574 (void)memset_s(&vdiRoute, sizeof(vdiRoute), 0, sizeof(vdiRoute));
575
576 ret = AudioCommonRouteToVdiRouteVdi(route, &vdiRoute);
577 if (ret != HDF_SUCCESS) {
578 AUDIO_FUNC_LOGE("audio vdiAdapter route To vdiRoute fail");
579 goto EXIT;
580 }
581
582 ret = vdiAdapter->UpdateAudioRoute(vdiAdapter, &vdiRoute, routeHandle);
583 AudioCommonFreeVdiRouteVdi(&vdiRoute);
584 if (ret != HDF_SUCCESS) {
585 AUDIO_FUNC_LOGE("audio vdiAdapter call UpdateAudioRoute fail, ret=%{public}d", ret);
586 ret = HDF_FAILURE;
587 goto EXIT;
588 }
589
590 EXIT:
591 pthread_rwlock_unlock(&g_rwAdapterLock);
592 return ret;
593 }
594
AudioReleaseAudioRouteVdi(struct IAudioAdapter * adapter,int32_t routeHandle)595 static int32_t AudioReleaseAudioRouteVdi(struct IAudioAdapter *adapter, int32_t routeHandle)
596 {
597 pthread_rwlock_rdlock(&g_rwAdapterLock);
598 int32_t ret = HDF_SUCCESS;
599 if (adapter == NULL) {
600 AUDIO_FUNC_LOGE("invalid param");
601 ret = HDF_ERR_INVALID_PARAM;
602 goto EXIT;
603 }
604
605 struct IAudioAdapterVdi *vdiAdapter = AudioGetVdiAdapterVdi(adapter);
606 if (vdiAdapter == NULL || vdiAdapter->ReleaseAudioRoute == NULL) {
607 AUDIO_FUNC_LOGE("invalid param");
608 ret = HDF_ERR_INVALID_PARAM;
609 goto EXIT;
610 }
611
612 ret = vdiAdapter->ReleaseAudioRoute(vdiAdapter, routeHandle);
613 if (ret != HDF_SUCCESS) {
614 AUDIO_FUNC_LOGE("audio vdiAdapter call ReleaseAudioRoute fail, ret=%{public}d", ret);
615 ret = HDF_FAILURE;
616 goto EXIT;
617 }
618
619 EXIT:
620 pthread_rwlock_unlock(&g_rwAdapterLock);
621 return ret;
622 }
623
AudioSetMicMuteVdi(struct IAudioAdapter * adapter,bool mute)624 static int32_t AudioSetMicMuteVdi(struct IAudioAdapter *adapter, bool mute)
625 {
626 pthread_rwlock_rdlock(&g_rwAdapterLock);
627 int32_t ret = HDF_SUCCESS;
628 if (adapter == NULL) {
629 AUDIO_FUNC_LOGE("invalid param");
630 ret = HDF_ERR_INVALID_PARAM;
631 goto EXIT;
632 }
633
634 struct IAudioAdapterVdi *vdiAdapter = AudioGetVdiAdapterVdi(adapter);
635 if (vdiAdapter == NULL || vdiAdapter->SetMicMute == NULL) {
636 AUDIO_FUNC_LOGE("invalid param");
637 ret = HDF_ERR_INVALID_PARAM;
638 goto EXIT;
639 }
640
641 ret = vdiAdapter->SetMicMute(vdiAdapter, mute);
642 if (ret != HDF_SUCCESS) {
643 AUDIO_FUNC_LOGE("audio vdiAdapter call SetMicMute fail, ret=%{public}d", ret);
644 ret = HDF_FAILURE;
645 goto EXIT;
646 }
647
648 EXIT:
649 pthread_rwlock_unlock(&g_rwAdapterLock);
650 return ret;
651 }
652
AudioGetMicMuteVdi(struct IAudioAdapter * adapter,bool * mute)653 static int32_t AudioGetMicMuteVdi(struct IAudioAdapter *adapter, bool *mute)
654 {
655 pthread_rwlock_rdlock(&g_rwAdapterLock);
656 int32_t ret = HDF_SUCCESS;
657 if (adapter == NULL || mute == NULL) {
658 AUDIO_FUNC_LOGE("invalid param");
659 ret = HDF_ERR_INVALID_PARAM;
660 goto EXIT;
661 }
662
663 struct IAudioAdapterVdi *vdiAdapter = AudioGetVdiAdapterVdi(adapter);
664 if (vdiAdapter == NULL || vdiAdapter->GetMicMute == NULL) {
665 AUDIO_FUNC_LOGE("invalid param");
666 ret = HDF_ERR_INVALID_PARAM;
667 goto EXIT;
668 }
669
670 ret = vdiAdapter->GetMicMute(vdiAdapter, mute);
671 if (ret != HDF_SUCCESS) {
672 AUDIO_FUNC_LOGE("audio vdiAdapter call GetMicMute fail, ret=%{public}d", ret);
673 ret = HDF_FAILURE;
674 goto EXIT;
675 }
676
677 EXIT:
678 pthread_rwlock_unlock(&g_rwAdapterLock);
679 return ret;
680 }
681
AudioSetVoiceVolumeVdi(struct IAudioAdapter * adapter,float volume)682 static int32_t AudioSetVoiceVolumeVdi(struct IAudioAdapter *adapter, float volume)
683 {
684 pthread_rwlock_rdlock(&g_rwAdapterLock);
685 int32_t ret = HDF_SUCCESS;
686 if (adapter == NULL) {
687 AUDIO_FUNC_LOGE("invalid param");
688 ret = HDF_ERR_INVALID_PARAM;
689 goto EXIT;
690 }
691
692 struct IAudioAdapterVdi *vdiAdapter = AudioGetVdiAdapterVdi(adapter);
693 if (vdiAdapter == NULL || vdiAdapter->SetVoiceVolume == NULL) {
694 AUDIO_FUNC_LOGE("invalid param");
695 ret = HDF_ERR_INVALID_PARAM;
696 goto EXIT;
697 }
698
699 ret = vdiAdapter->SetVoiceVolume(vdiAdapter, volume);
700 if (ret != HDF_SUCCESS) {
701 AUDIO_FUNC_LOGE("audio vdiAdapter call SetVoiceVolume fail, ret=%{public}d", ret);
702 ret = HDF_FAILURE;
703 goto EXIT;
704 }
705
706 EXIT:
707 pthread_rwlock_unlock(&g_rwAdapterLock);
708 return ret;
709 }
710
AudioSetExtraParamsVdi(struct IAudioAdapter * adapter,enum AudioExtParamKey key,const char * condition,const char * value)711 static int32_t AudioSetExtraParamsVdi(struct IAudioAdapter *adapter, enum AudioExtParamKey key, const char *condition,
712 const char *value)
713 {
714 pthread_rwlock_rdlock(&g_rwAdapterLock);
715 int32_t ret = HDF_SUCCESS;
716 if (adapter == NULL || condition == NULL || value == NULL) {
717 AUDIO_FUNC_LOGE("invalid param");
718 ret = HDF_ERR_INVALID_PARAM;
719 goto EXIT;
720 }
721
722 struct IAudioAdapterVdi *vdiAdapter = AudioGetVdiAdapterVdi(adapter);
723 if (vdiAdapter == NULL || vdiAdapter->SetExtraParams == NULL) {
724 AUDIO_FUNC_LOGE("invalid param");
725 ret = HDF_ERR_INVALID_PARAM;
726 goto EXIT;
727 }
728
729 ret = vdiAdapter->SetExtraParams(vdiAdapter, (enum AudioExtParamKeyVdi)key, condition, value);
730 if (ret != HDF_SUCCESS) {
731 AUDIO_FUNC_LOGE("audio vdiAdapter call SetExtraParams fail, ret=%{public}d", ret);
732 ret = HDF_FAILURE;
733 goto EXIT;
734 }
735
736 EXIT:
737 pthread_rwlock_unlock(&g_rwAdapterLock);
738 return ret;
739 }
740
AudioGetExtraParamsVdi(struct IAudioAdapter * adapter,enum AudioExtParamKey key,const char * condition,char * value,uint32_t valueLen)741 static int32_t AudioGetExtraParamsVdi(struct IAudioAdapter *adapter, enum AudioExtParamKey key, const char *condition,
742 char *value, uint32_t valueLen)
743 {
744 pthread_rwlock_rdlock(&g_rwAdapterLock);
745 int32_t ret = HDF_SUCCESS;
746 if (adapter == NULL || condition == NULL || value == NULL) {
747 AUDIO_FUNC_LOGE("invalid param");
748 ret = HDF_ERR_INVALID_PARAM;
749 goto EXIT;
750 }
751
752 struct IAudioAdapterVdi *vdiAdapter = AudioGetVdiAdapterVdi(adapter);
753 if (vdiAdapter == NULL || vdiAdapter->GetExtraParams == NULL) {
754 AUDIO_FUNC_LOGE("invalid param");
755 ret = HDF_ERR_INVALID_PARAM;
756 goto EXIT;
757 }
758
759 ret = vdiAdapter->GetExtraParams(vdiAdapter, (enum AudioExtParamKeyVdi)key, condition, value,
760 (int32_t)valueLen);
761 if (ret != HDF_SUCCESS) {
762 AUDIO_FUNC_LOGE("audio vdiAdapter call GetExtraParams fail, ret=%{public}d", ret);
763 ret = HDF_FAILURE;
764 goto EXIT;
765 }
766
767 EXIT:
768 pthread_rwlock_unlock(&g_rwAdapterLock);
769 return ret;
770 }
771
AudioInitAdapterInstanceVdi(struct IAudioAdapter * adapter)772 static void AudioInitAdapterInstanceVdi(struct IAudioAdapter *adapter)
773 {
774 adapter->InitAllPorts = AudioInitAllPortsVdi;
775 adapter->CreateRender = AudioCreateRenderVdi;
776 adapter->DestroyRender = AudioDestroyRenderVdi;
777 adapter->CreateCapture = AudioCreateCaptureVdi;
778 adapter->DestroyCapture = AudioDestroyCaptureVdi;
779
780 adapter->GetPortCapability = AudioGetPortCapabilityVdi;
781 adapter->SetPassthroughMode = AudioSetPassthroughModeVdi;
782 adapter->GetPassthroughMode = AudioGetPassthroughModeVdi;
783 adapter->GetDeviceStatus = AudioGetDeviceStatusVdi;
784 adapter->UpdateAudioRoute = AudioUpdateAudioRouteVdi;
785
786 adapter->ReleaseAudioRoute = AudioReleaseAudioRouteVdi;
787 adapter->SetMicMute = AudioSetMicMuteVdi;
788 adapter->GetMicMute = AudioGetMicMuteVdi;
789 adapter->SetVoiceVolume = AudioSetVoiceVolumeVdi;
790 adapter->SetExtraParams = AudioSetExtraParamsVdi;
791
792 adapter->GetExtraParams = AudioGetExtraParamsVdi;
793 }
794
AudioGetAdapterRefCntVdi(uint32_t descIndex)795 uint32_t AudioGetAdapterRefCntVdi(uint32_t descIndex)
796 {
797 pthread_rwlock_rdlock(&g_rwAdapterLock);
798 if (descIndex >= AUDIO_VDI_ADAPTER_NUM_MAX) {
799 AUDIO_FUNC_LOGE("get adapter ref error, descIndex=%{public}d", descIndex);
800 pthread_rwlock_unlock(&g_rwAdapterLock);
801 return UINT_MAX;
802 }
803
804 struct AudioAdapterPrivVdi *priv = AudioAdapterGetPrivVdi();
805 pthread_rwlock_unlock(&g_rwAdapterLock);
806 return priv->adapterInfo[descIndex].refCnt;
807 }
808
AudioIncreaseAdapterRefVdi(uint32_t descIndex,struct IAudioAdapter ** adapter)809 int32_t AudioIncreaseAdapterRefVdi(uint32_t descIndex, struct IAudioAdapter **adapter)
810 {
811 pthread_rwlock_wrlock(&g_rwAdapterLock);
812 int32_t ret = HDF_SUCCESS;
813 if (adapter == NULL) {
814 AUDIO_FUNC_LOGE("invalid param");
815 ret = HDF_ERR_INVALID_PARAM;
816 goto EXIT;
817 }
818 if (descIndex >= AUDIO_VDI_ADAPTER_NUM_MAX) {
819 AUDIO_FUNC_LOGE("increase adapter ref error, descIndex=%{public}d", descIndex);
820 ret = HDF_ERR_INVALID_PARAM;
821 goto EXIT;
822 }
823
824 struct AudioAdapterPrivVdi *priv = AudioAdapterGetPrivVdi();
825 if (priv->adapterInfo[descIndex].adapter == NULL) {
826 AUDIO_FUNC_LOGE("Invalid adapter param!");
827 ret = HDF_ERR_INVALID_PARAM;
828 goto EXIT;
829 }
830
831 priv->adapterInfo[descIndex].refCnt++;
832 *adapter = priv->adapterInfo[descIndex].adapter;
833 AUDIO_FUNC_LOGI("increase adapternameIndex[%{public}d], refCount[%{public}d]", descIndex,
834 priv->adapterInfo[descIndex].refCnt);
835
836 EXIT:
837 pthread_rwlock_unlock(&g_rwAdapterLock);
838 return ret;
839 }
840
AudioDecreaseAdapterRefVdi(uint32_t descIndex)841 void AudioDecreaseAdapterRefVdi(uint32_t descIndex)
842 {
843 pthread_rwlock_wrlock(&g_rwAdapterLock);
844 if (descIndex >= AUDIO_VDI_ADAPTER_NUM_MAX) {
845 AUDIO_FUNC_LOGE("decrease adapter ref error, descIndex=%{public}d", descIndex);
846 pthread_rwlock_unlock(&g_rwAdapterLock);
847 return;
848 }
849
850 struct AudioAdapterPrivVdi *priv = AudioAdapterGetPrivVdi();
851 if (priv->adapterInfo[descIndex].refCnt == 0) {
852 AUDIO_FUNC_LOGE("Invalid adapterInfo[%{public}d] had released", descIndex);
853 pthread_rwlock_unlock(&g_rwAdapterLock);
854 return;
855 }
856 priv->adapterInfo[descIndex].refCnt--;
857 AUDIO_FUNC_LOGI("decrease adapternameIndex[%{public}d], refCount[%{public}d]", descIndex,
858 priv->adapterInfo[descIndex].refCnt);
859 pthread_rwlock_unlock(&g_rwAdapterLock);
860 return;
861 }
862
AudioEnforceClearAdapterRefCntVdi(uint32_t descIndex)863 void AudioEnforceClearAdapterRefCntVdi(uint32_t descIndex)
864 {
865 pthread_rwlock_wrlock(&g_rwAdapterLock);
866 if (descIndex >= AUDIO_VDI_ADAPTER_NUM_MAX) {
867 AUDIO_FUNC_LOGE("decrease adapter descIndex error, descIndex=%{public}d", descIndex);
868 pthread_rwlock_unlock(&g_rwAdapterLock);
869 return;
870 }
871
872 struct AudioAdapterPrivVdi *priv = AudioAdapterGetPrivVdi();
873 priv->adapterInfo[descIndex].refCnt = 0;
874 AUDIO_FUNC_LOGI("clear adapter ref count zero");
875 pthread_rwlock_unlock(&g_rwAdapterLock);
876 }
877
AudioCreateAdapterVdi(uint32_t descIndex,struct IAudioAdapterVdi * vdiAdapter,char * adapterName)878 struct IAudioAdapter *AudioCreateAdapterVdi(uint32_t descIndex, struct IAudioAdapterVdi *vdiAdapter,
879 char *adapterName)
880 {
881 pthread_rwlock_wrlock(&g_rwAdapterLock);
882 if (descIndex >= AUDIO_VDI_ADAPTER_NUM_MAX) {
883 AUDIO_FUNC_LOGE("create adapter error, descIndex=%{public}d", descIndex);
884 pthread_rwlock_unlock(&g_rwAdapterLock);
885 return NULL;
886 }
887
888 if (vdiAdapter == NULL) {
889 AUDIO_FUNC_LOGE("audio vdiAdapter is null");
890 pthread_rwlock_unlock(&g_rwAdapterLock);
891 return NULL;
892 }
893
894 struct AudioAdapterPrivVdi *priv = AudioAdapterGetPrivVdi();
895 struct IAudioAdapter *adapter = priv->adapterInfo[descIndex].adapter;
896 if (adapter != NULL) {
897 pthread_rwlock_unlock(&g_rwAdapterLock);
898 return adapter;
899 }
900
901 adapter = (struct IAudioAdapter *)OsalMemCalloc(sizeof(struct IAudioAdapter));
902 if (adapter == NULL) {
903 AUDIO_FUNC_LOGE("OsalMemCalloc adapter fail");
904 pthread_rwlock_unlock(&g_rwAdapterLock);
905 return NULL;
906 }
907
908 AudioInitAdapterInstanceVdi(adapter);
909 priv->adapterInfo[descIndex].vdiAdapter = vdiAdapter;
910 priv->adapterInfo[descIndex].adapter = adapter;
911 priv->adapterInfo[descIndex].refCnt = 1;
912 priv->adapterInfo[descIndex].adapterName = strdup(adapterName);
913 if (priv->adapterInfo[descIndex].adapterName == NULL) {
914 OsalMemFree((void *)priv->adapterInfo[descIndex].adapter);
915 priv->adapterInfo[descIndex].adapter = NULL;
916 pthread_rwlock_unlock(&g_rwAdapterLock);
917 return NULL;
918 }
919
920 AUDIO_FUNC_LOGI(" audio vdiAdapter create adapter success, refcount[1], adapterName=[%{public}s]", adapterName);
921 pthread_rwlock_unlock(&g_rwAdapterLock);
922 return adapter;
923 }
924
AudioReleaseAdapterVdi(uint32_t descIndex)925 void AudioReleaseAdapterVdi(uint32_t descIndex)
926 {
927 pthread_rwlock_wrlock(&g_rwAdapterLock);
928 if (descIndex >= AUDIO_VDI_ADAPTER_NUM_MAX) {
929 AUDIO_FUNC_LOGE("adapter release fail descIndex=%{public}d", descIndex);
930 pthread_rwlock_unlock(&g_rwAdapterLock);
931 return;
932 }
933
934 struct AudioAdapterPrivVdi *priv = AudioAdapterGetPrivVdi();
935 StubCollectorRemoveObject(IAUDIOADAPTER_INTERFACE_DESC, priv->adapterInfo[descIndex].adapter);
936 OsalMemFree((void *)priv->adapterInfo[descIndex].adapter);
937 priv->adapterInfo[descIndex].adapter = NULL;
938 priv->adapterInfo[descIndex].vdiAdapter = NULL;
939 priv->adapterInfo[descIndex].refCnt = UINT_MAX;
940 OsalMemFree((void *)priv->adapterInfo[descIndex].adapterName);
941 priv->adapterInfo[descIndex].adapterName = NULL;
942
943 priv->isRegCb = false;
944 priv->callback = NULL;
945
946 AUDIO_FUNC_LOGI(" audio vdiAdapter release adapter success");
947 pthread_rwlock_unlock(&g_rwAdapterLock);
948 }
949