1 /*
2  * Copyright (C) 2021 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 "../include/a2dp_sbc_dynamic_lib_ctrl.h"
17 
18 #include <dlfcn.h>
19 
20 #include "log.h"
21 
22 namespace OHOS {
23 namespace bluetooth {
24 #define CODEC_LIB_SBC "libbtsbc.z.so"
25 
A2dpSBCDynamicLibCtrl(bool isEncoder)26 A2dpSBCDynamicLibCtrl::A2dpSBCDynamicLibCtrl(bool isEncoder)
27 {
28     isEncoder_ = isEncoder;
29 }
30 
~A2dpSBCDynamicLibCtrl()31 A2dpSBCDynamicLibCtrl::~A2dpSBCDynamicLibCtrl()
32 {
33     isEncoder_ = false;
34 }
35 
LoadCodecSbcLib() const36 CODECSbcLib *A2dpSBCDynamicLibCtrl::LoadCodecSbcLib() const
37 {
38     CODECSbcLib *lib = new CODECSbcLib();
39     if (lib != nullptr) {
40         do {
41             lib->lib = dlopen(CODEC_LIB_SBC, RTLD_LAZY | RTLD_NODELETE);
42             if (lib->lib == nullptr) {
43                 LOG_ERROR("Load libbtsbc.z.so failed");
44                 break;
45             }
46             if (isEncoder_) {
47                 lib->sbcEncoder.createSbcEncode = (sbc::createSbcEncoder)dlsym(lib->lib, "CreateEncode");
48                 if (lib->sbcEncoder.createSbcEncode == nullptr) {
49                     LOG_ERROR("Load symbol create Sbc Encoder failed");
50                 }
51                 lib->sbcEncoder.destroySbcEncode = (sbc::destroySbcEncoder)dlsym(lib->lib, "DestroyEncode");
52                 if (lib->sbcEncoder.destroySbcEncode == nullptr) {
53                     LOG_ERROR("Load symbol destroy Sbc Encoder failed");
54                 }
55             } else {
56                 lib->sbcDecoder.createSbcDecode = (sbc::createSbcDecoder)dlsym(lib->lib, "CreateDecode");
57 
58                 if (lib->sbcDecoder.createSbcDecode == nullptr) {
59                     LOG_ERROR("Load symbol create Sbc Decoder failed");
60                 }
61 
62                 lib->sbcDecoder.destroySbcDecode = (sbc::destroySbcDecoder)dlsym(lib->lib, "DestroyDecode");
63                 if (lib->sbcDecoder.destroySbcDecode == nullptr) {
64                     LOG_ERROR("Load symbol destroy Sbc Decoder failed");
65                 }
66             }
67         } while (0);
68 
69         if (isEncoder_) {
70             if ((lib->lib == nullptr) ||
71                 (lib->sbcEncoder.createSbcEncode == nullptr) ||
72                 (lib->sbcEncoder.destroySbcEncode == nullptr)) {
73                     delete lib;
74                     lib = nullptr;
75             }
76         } else {
77             if ((lib->lib == nullptr) ||
78                 (lib->sbcDecoder.createSbcDecode == nullptr) ||
79                 (lib->sbcDecoder.destroySbcDecode == nullptr)) {
80                     delete lib;
81                     lib = nullptr;
82             }
83         }
84     }
85     return lib;
86 }
87 
UnloadCodecSbcLib(CODECSbcLib * lib) const88 void A2dpSBCDynamicLibCtrl::UnloadCodecSbcLib(CODECSbcLib *lib) const
89 {
90     if (isEncoder_) {
91         if (lib != nullptr) {
92             lib->sbcEncoder.createSbcEncode = nullptr;
93             lib->sbcEncoder.destroySbcEncode = nullptr;
94             if (lib->lib != nullptr) {
95                 dlclose(lib->lib);
96                 lib->lib = nullptr;
97             }
98             delete lib;
99         }
100     } else {
101         if (lib != nullptr) {
102             lib->sbcDecoder.createSbcDecode = nullptr;
103             lib->sbcDecoder.destroySbcDecode = nullptr;
104             if (lib->lib != nullptr) {
105                 dlclose(lib->lib);
106                 lib->lib = nullptr;
107             }
108             delete lib;
109         }
110     }
111 }
112 }  // namespace bluetooth
113 }  // namespace OHOS