• Home
  • History
  • Annotate
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /* Copyright (c) 2016, The Linux Foundation. All rights reserved.
2  *
3  * Redistribution and use in source and binary forms, with or without
4  * modification, are permitted provided that the following conditions are
5  * met:
6  *     * Redistributions of source code must retain the above copyright
7  *       notice, this list of conditions and the following disclaimer.
8  *     * Redistributions in binary form must reproduce the above
9  *       copyright notice, this list of conditions and the following
10  *       disclaimer in the documentation and/or other materials provided
11  *       with the distribution.
12  *     * Neither the name of The Linux Foundation nor the names of its
13  *       contributors may be used to endorse or promote products derived
14  *       from this software without specific prior written permission.
15  *
16  * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
17  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
18  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
19  * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
20  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
21  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
22  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
23  * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
24  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
25  * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
26  * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27  *
28  * Changes from Qualcomm Innovation Center are provided under the following license:
29  *
30  * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
31  *
32  * Redistribution and use in source and binary forms, with or without
33  * modification, are permitted (subject to the limitations in the
34  * disclaimer below) provided that the following conditions are met:
35  *
36  *    * Redistributions of source code must retain the above copyright
37  *      notice, this list of conditions and the following disclaimer.
38  *
39  *    * Redistributions in binary form must reproduce the above
40  *      copyright notice, this list of conditions and the following
41  *      disclaimer in the documentation and/or other materials provided
42  *      with the distribution.
43  *
44  *    * Neither the name of Qualcomm Innovation Center, Inc. nor the names of its
45  *      contributors may be used to endorse or promote products derived
46  *      from this software without specific prior written permission.
47  *
48  * NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE
49  * GRANTED BY THIS LICENSE. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT
50  * HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED
51  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
52  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
53  * IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
54  * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
55  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
56  * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
57  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
58  * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
59  * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
60  * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
61  */
62 
63 #include <netlink/object-api.h>
64 #include <linux/pkt_sched.h>
65 #include <dlfcn.h>
66 #include <dirent.h>
67 #include <string.h>
68 #include "common.h"
69 #include "driver_cmd_nl80211_extn.h"
70 
71 #define QCA_NL80211_VENDOR_SUBCMD_DIAG_DATA 201
72 #define MAX_OEM_LIBS 5
73 #define MAX_LIB_NAME_SIZE 30
74 #define CB_SUFFIX "_cb"
75 static wpa_driver_oem_cb_table_t oem_cb_array[MAX_OEM_LIBS + 1];
76 
wpa_msg_handler(struct wpa_driver_nl80211_data * drv,char * msg,u32 subcmd)77 void wpa_msg_handler(struct wpa_driver_nl80211_data *drv, char *msg, u32 subcmd) {
78     if (subcmd == QCA_NL80211_VENDOR_SUBCMD_CONFIG_TWT) {
79 	wpa_msg(drv->ctx, MSG_INFO, "%s", msg);
80     }
81 }
82 
wpa_driver_oem_initialize(wpa_driver_oem_cb_table_t ** oem_cb_table)83 int wpa_driver_oem_initialize(wpa_driver_oem_cb_table_t **oem_cb_table)
84 {
85 	wpa_driver_oem_get_cb_table_t *get_oem_table;
86 	wpa_driver_oem_cb_table_t *oem_cb_table_local;
87 	struct dirent *entry;
88 	void *oem_handle_n;
89 	char cb_sym_name[MAX_LIB_NAME_SIZE], *tmp;
90 	DIR *oem_lib_dir;
91 	unsigned int lib_n;
92 #ifdef ANDROID
93 #if __WORDSIZE == 64
94 	char *oem_lib_path = "/vendor/lib64/";
95 #else
96 	char *oem_lib_path  = "/vendor/lib/";
97 #endif
98 #else
99 	char *oem_lib_path  = "/usr/lib/";
100 #endif
101 	/* Return the callback table if it is already initialized*/
102 	if (*oem_cb_table)
103 		return WPA_DRIVER_OEM_STATUS_SUCCESS;
104 
105 	for (lib_n = 0; lib_n < MAX_OEM_LIBS; lib_n++) {
106 		oem_cb_array[lib_n].wpa_driver_driver_cmd_oem_cb = NULL;
107 		oem_cb_array[lib_n].wpa_driver_nl80211_driver_oem_event = NULL;
108 		oem_cb_array[lib_n].wpa_driver_oem_feature_check_cb = NULL;
109 	}
110 
111 	oem_lib_dir = opendir(oem_lib_path);
112 	if (!oem_lib_dir) {
113 		wpa_printf(MSG_ERROR, "%s: Unable to open %s", __FUNCTION__, oem_lib_path);
114 		return WPA_DRIVER_OEM_STATUS_FAILURE;
115 	}
116 
117 	lib_n = 0;
118 	while((entry = readdir(oem_lib_dir)) != NULL) {
119 		if (strncmp(entry->d_name, "libwpa_drv_oem", 14))
120 			continue;
121 
122 		wpa_printf(MSG_DEBUG, "%s: Opening lib %s", __FUNCTION__, entry->d_name);
123 		oem_handle_n = dlopen(entry->d_name, RTLD_NOW);
124 
125 		if (!oem_handle_n) {
126 			wpa_printf(MSG_ERROR, "%s: Could not load %s", __FUNCTION__, entry->d_name);
127 			/* let's not worry much, continue with others */
128 			continue;
129 		}
130 
131 		if (strlen(entry->d_name)  >= (sizeof(cb_sym_name) - sizeof(CB_SUFFIX))) {
132 			wpa_printf(MSG_ERROR, "%s: libname (%s) too lengthy", __FUNCTION__, entry->d_name);
133 			continue;
134 		}
135 
136 		os_strlcpy(cb_sym_name, entry->d_name, sizeof(cb_sym_name));
137 		tmp = strchr(cb_sym_name, '.');
138 		if (!tmp) {
139 			wpa_printf(MSG_ERROR, "%s: libname (%s) incorrect?", __FUNCTION__, entry->d_name);
140 			continue;
141 		}
142 
143 		os_strlcpy(tmp, CB_SUFFIX, sizeof(CB_SUFFIX));
144 		wpa_printf(MSG_DEBUG, "%s: Loading sym %s", __FUNCTION__, cb_sym_name);
145 
146 		/* Get the lib's function table callback */
147 		get_oem_table = (wpa_driver_oem_get_cb_table_t *)dlsym(oem_handle_n,
148 				cb_sym_name);
149 
150 		if (!get_oem_table) {
151 			wpa_printf(MSG_ERROR, "%s: Could not get sym table", __FUNCTION__);
152 			continue;
153 		}
154 
155 		oem_cb_table_local = get_oem_table();
156 
157 		oem_cb_array[lib_n].wpa_driver_driver_cmd_oem_cb =
158 			oem_cb_table_local->wpa_driver_driver_cmd_oem_cb;
159 		oem_cb_array[lib_n].wpa_driver_nl80211_driver_oem_event =
160 			oem_cb_table_local->wpa_driver_nl80211_driver_oem_event;
161 		oem_cb_array[lib_n].wpa_driver_driver_wpa_msg_oem_cb =
162 			oem_cb_table_local->wpa_driver_driver_wpa_msg_oem_cb;
163 		oem_cb_array[lib_n].wpa_driver_oem_feature_check_cb =
164 			oem_cb_table_local->wpa_driver_oem_feature_check_cb;
165 
166 		/* Register wpa message callback with the oem library */
167 		if(oem_cb_array[lib_n].wpa_driver_driver_wpa_msg_oem_cb) {
168 			oem_cb_array[lib_n].wpa_driver_driver_wpa_msg_oem_cb(wpa_msg_handler);
169 		}
170 
171 		lib_n++;
172 
173 		if (lib_n == MAX_OEM_LIBS) {
174 			wpa_printf(MSG_DEBUG, "%s: Exceeded max libs %d", __FUNCTION__, lib_n);
175 			break;
176 		}
177 	}
178 
179 	oem_cb_array[lib_n].wpa_driver_driver_cmd_oem_cb = NULL;
180 	*oem_cb_table = oem_cb_array;
181 	wpa_printf(MSG_DEBUG, "%s: OEM lib initialized\n", __func__);
182 	closedir(oem_lib_dir);
183 
184 	return WPA_DRIVER_OEM_STATUS_SUCCESS;
185 }
186