blob: 87c838002a3e74f033adbaf549bca11b7e3bc081 [file] [log] [blame]
xjde81d1d2021-11-25 15:01:52 +08001/* Copyright Statement:
2 *
3 * This software/firmware and related documentation ("MediaTek Software") are
4 * protected under relevant copyright laws. The information contained herein
5 * is confidential and proprietary to MediaTek Inc. and/or its licensors.
6 * Without the prior written permission of MediaTek inc. and/or its licensors,
7 * any reproduction, modification, use or disclosure of MediaTek Software,
8 * and information contained herein, in whole or in part, shall be strictly prohibited.
9 */
10/* MediaTek Inc. (C) 2010. All rights reserved.
11 *
12 * BY OPENING THIS FILE, RECEIVER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES
13 * THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK SOFTWARE")
14 * RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE PROVIDED TO RECEIVER ON
15 * AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY DISCLAIMS ANY AND ALL WARRANTIES,
16 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF
17 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR NONINFRINGEMENT.
18 * NEITHER DOES MEDIATEK PROVIDE ANY WARRANTY WHATSOEVER WITH RESPECT TO THE
19 * SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY, INCORPORATED IN, OR
20 * SUPPLIED WITH THE MEDIATEK SOFTWARE, AND RECEIVER AGREES TO LOOK ONLY TO SUCH
21 * THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO. RECEIVER EXPRESSLY ACKNOWLEDGES
22 * THAT IT IS RECEIVER'S SOLE RESPONSIBILITY TO OBTAIN FROM ANY THIRD PARTY ALL PROPER LICENSES
23 * CONTAINED IN MEDIATEK SOFTWARE. MEDIATEK SHALL ALSO NOT BE RESPONSIBLE FOR ANY MEDIATEK
24 * SOFTWARE RELEASES MADE TO RECEIVER'S SPECIFICATION OR TO CONFORM TO A PARTICULAR
25 * STANDARD OR OPEN FORUM. RECEIVER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND
26 * CUMULATIVE LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL BE,
27 * AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT ISSUE,
28 * OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY RECEIVER TO
29 * MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE.
30 *
31 * The following software/firmware and/or related documentation ("MediaTek Software")
32 * have been modified by MediaTek Inc. All revisions are subject to any receiver's
33 * applicable license agreements with MediaTek Inc.
34 */
35#include <vendor-ril/telephony/ril.h>
36#include <stdlib.h>
37#include <stdio.h>
38#include <cutils/jstring.h>
39#include <log/log.h>
40#include <unistd.h>
41#include <math.h>
42#include <vector>
43#include <string>
44#include <stdexcept>
45#include "common.h"
46#include "em/em.h"
47#include "ModemCategory.h"
48#include "Radio_capability_switch_util.h"
49#include "../util/utils.h"
50
51#if EM_MODE_SUPPORT
52
53#undef LOG_TAG
54#define LOG_TAG "EM_ANTENNA"
55
56static const int MSG_QUERY_ANTENNA_MODE = 1;
57static const int MSG_SET_ANTENNA_MODE = 2;
58static const int MSG_QUERY_ANTENNA_MODE_C2K = 4;
59static const int MSG_QUERY_ANTENNA_EGMC_4G = 5;
60static const int MSG_SET_ANTENNA_EGMC_4G = 6;
61static const int MSG_INIT_ANTENNA_EGMC_4G = 7;
62static const int MODE_INDEX_BASE_3G = 10;
63static const int MODE_EPCM_VALID = 0xFF;
64static const int CELL_2RX_LENGTH = 2;
65static const int CELL_4RX_LENGTH = 4;
66
67int mCurrentEmantennaFlag = 0;
68bool fgAntennaRead = true;
69static int fgget = -1;
70static int fgset = -1;
71int mAntennaMode = 0;
72char antennaretstring[128] = {0};
73
74static const std::vector<std::string> antenna_modes_4g {
75 "RX1&RX2",
76 "RX1",
77 "RX2"
78};
79
80static const std::vector<std::string> antenna_modes_3g {
81 "Please select a mode:",
82 "RX1",
83 "RX2",
84 "RX1&RX2",
85 "Resume default setting"
86};
87
88static const std::vector<std::string> antenna_modes_c2k_mode {
89 "Resume default setting",
90 "RX1",
91 "RX2",
92 "RX1&RX2"
93};
94
95static void sendATCommand(const char *cmd,int msg)
96{
97 mCurrentEmantennaFlag = msg;
98 emSendATCommand(cmd, Radio_capability_switch_util::get_main_capability_phone_id());
99 return ;
100}
101static void queryCurrentMode() {
102 char cmd_str[32] = {0};
103 sprintf(cmd_str,"%s","AT+ERXPATH?");
104 sendATCommand(cmd_str, MSG_QUERY_ANTENNA_MODE);
105}
106
107void queryCurrentCdmaMode() {
108 if (utils::is93Modem()) {
109 sendATCommand("AT+ERXTESTMODE?", MSG_QUERY_ANTENNA_MODE_C2K);
110 } else {
111 android::emResultNotify(RET_STRING_ANTENNATEST_FAIL);
112 RLOGD("don't support");
113 }
114}
115
116static void setMode(int mode) {
117 char cmd_str[32] = {0};
118 sprintf(cmd_str,"%s%d","AT+ERXPATH=",mode);
119 sendATCommand(cmd_str, MSG_SET_ANTENNA_MODE);
120}
121
122static void setCdmaMode(int mode) {
123 std::string str("AT+ERXTESTMODE=");
124 str.append(std::to_string(mode));
125 if (utils::is93Modem()) {
126 sendATCommand(str.c_str(), MSG_SET_ANTENNA_MODE);
127 } else {
128 android::emResultNotify(RET_STRING_ANTENNATEST_FAIL);
129 RLOGD("don't support");
130 }
131}
132
133static void parseCurrentMode(char* data) {
134 RLOGD("parseCurrentMode(%d):%s",fgget, data);
135 std::vector<std::string> out;
136 utils::tokenize(string(data), "\n", out);
137 std::string str;
138 str.clear();
139 if(fgget == 0 || fgget == 1) {
140 for(auto i: out) {
141 if(i.find("+ERXPATH:") != std::string::npos) {
142 try {
143 int mode = std::stoi(i.substr(std::string("+ERXPATH:").size()));
144 if (mode < 0 || (mode >= antenna_modes_4g.size()
145 && mode >= MODE_INDEX_BASE_3G + mode >= antenna_modes_4g.size()
146 && mode != MODE_EPCM_VALID)) {
147 android::emResultNotify(RET_STRING_ANTENNATEST_FAIL);
148 RLOGD("Modem returned invalid mode(%d): %s",mode, data);
149 return ;
150 } else {
151 if (mode == MODE_EPCM_VALID) {
152 android::emResultNotify(RET_STRING_ANTENNATEST_FAIL);
153 } else if (mode >= MODE_INDEX_BASE_3G) {
154 if(ModemCategory::getModemType() != ModemCategory::MODEM_TD) {
155 int pos = mode - MODE_INDEX_BASE_3G + 1;
156 RLOGD("parseCurrent3GMode is: %d", pos);
157 str.append("3G:");
158 str.append(antenna_modes_3g[pos]);
159 str.append(" ");
160 }
161 } else {
162 if (ModemCategory::isLteSupport()) {
163 RLOGD("parseCurrentLteMode is: %d", mode);
164 str.append("4G:");
165 str.append(antenna_modes_4g[mode]);
166 str.append(" ");
167 }
168 }
169 }
170 str.append("\ndone\n");
171 } catch (const out_of_range &e) {
172 android::emResultNotify(RET_STRING_ANTENNATEST_FAIL);
173 RLOGD("out of range: %s", e.what());
174 return;
175 } catch (const invalid_argument &e) {
176 android::emResultNotify(RET_STRING_ANTENNATEST_FAIL);
177 RLOGD("invalid argument: %s", e.what());
178 return;
179 }
180 }
181 }
182 android::emResultNotify(str.c_str());
183 } else if (fgget == 2) {
184 for(auto i: out) {
185 if(i.find("+ERXTESTMODE:") != std::string::npos) {
186 try {
187 int mode = std::stoi(i.substr(std::string("+ERXTESTMODE:").size()));
188 if (mode < 0 || mode >= antenna_modes_c2k_mode.size()) {
189 android::emResultNotify(RET_STRING_ANTENNATEST_FAIL);
190 RLOGD("Modem returned invalid mode(%d): %s",mode, data);
191 return;
192 } else {
193 RLOGD("parseCurrentC2KMode is: %d", mode);
194 str.append("CDMA:");
195 str.append(antenna_modes_c2k_mode[mode]);
196 str.append(" ");
197 }
198 str.append("\ndone\n");
199 } catch (const out_of_range &e) {
200 android::emResultNotify(RET_STRING_ANTENNATEST_FAIL);
201 RLOGD("out of range: %s", e.what());
202 return;
203 } catch (const invalid_argument &e) {
204 android::emResultNotify(RET_STRING_ANTENNATEST_FAIL);
205 RLOGD("invalid argument: %s", e.what());
206 return;
207 }
208 }
209 }
210 android::emResultNotify(str.c_str());
211 } else {
212 RLOGE("error choose!!!");
213 android::emResultNotify(RET_STRING_ANTENNATEST_FAIL);
214 }
215 return;
216}
217
218
219static void emAntennaAtCmdHandle(char*response, int responselen) {
220 switch (mCurrentEmantennaFlag) {
221 case MSG_QUERY_ANTENNA_MODE:
222 case MSG_QUERY_ANTENNA_MODE_C2K:
223 //parse antenna mode.
224 if ((responselen > 0) && (response != NULL)) {
225 RLOGD("Get mode %s", response);
226 parseCurrentMode(response);
227 } else {
228 RLOGD("Query antenna mode failed.");
229 sprintf(antennaretstring, "%s%s", ("Query antenna mode failed."),
230 RET_STRING_ANTENNATEST_FAIL);
231 android::emResultNotify(antennaretstring);
232 }
233 android::unregisterNetwork();
234 break;
235 case MSG_SET_ANTENNA_MODE:
236 memset(antennaretstring, 0, sizeof(antennaretstring));
237 if ((responselen > 0) && (response != NULL)) {
238 RLOGD("Set successful.");
239 sprintf(antennaretstring, "%s\n%s", ("Set successful."),
240 RET_STRING_ANTENNATEST_SUCCESS);
241 } else {
242 RLOGD("Set failed.");
243 sprintf(antennaretstring, "%s\n%s", ("Set failed."),
244 RET_STRING_ANTENNATEST_FAIL);
245 }
246 android::unregisterNetwork();
247 android::emResultNotify(antennaretstring);
248 break;
249 default:
250 RLOGD("error(%d)", mCurrentEmantennaFlag);
251 break;
252 }
253}
254
255
256//create thread to send command
257static void * emAntennaTestThread(void* arg)
258{
259 if(fgAntennaRead){
260 if(fgget == 0) { //4G
261 if (ModemCategory::isLteSupport()) {
262 queryCurrentMode();
263 } else {
264 android::emResultNotify("Antenna test don't support for 4G \ndone\n");
265 }
266 } else if (fgget == 1){ //3G
267 if (ModemCategory::getModemType() == ModemCategory::MODEM_TD) {
268 android::emResultNotify("Antenna test don't support for 3G \ndone\n");
269 } else {
270 queryCurrentMode();
271 }
272 } else if (fgget == 2) { //C2K
273 if(ModemCategory::isCdma()) {
274 queryCurrentCdmaMode();
275 } else {
276 android::emResultNotify("Antenna test don't support for C2K \ndone\n");
277 }
278 } else {
279 android::emResultNotify("Antenna test index error \ndone\n");
280 }
281
282 }else{
283 if(fgset == 0) { //4G
284 if (ModemCategory::isLteSupport()) {
285 setMode(mAntennaMode);
286 } else {
287 android::emResultNotify("Antenna test don't support for 4G \ndone\n");
288 }
289 } else if (fgset == 1){ //3G
290 if (ModemCategory::getModemType() == ModemCategory::MODEM_TD) {
291 android::emResultNotify("Antenna test don't support for 3G \ndone\n");
292 } else {
293 setMode(mAntennaMode);
294 }
295 } else if (fgset == 2) { //C2K
296 if(ModemCategory::isCdma()) {
297 setCdmaMode(mAntennaMode);
298 } else {
299 android::emResultNotify("Antenna test don't support for C2K \ndone\n");
300 }
301 } else {
302 android::emResultNotify("Antenna test index error \ndone\n");
303 }
304 }
305 pthread_exit(0);
306}
307
308int emAntennaTestStart(int argc, int *item,char *value)
309{
310 RLOGD("emAntennaTestStart called");
311 if(argc < 2){
312 RLOGD("please select AntennaTest get or set :");
313 return -1;
314 }
315 mCurrentEmantennaFlag = 0;
316 int classid = item[0];
317 int operatorid = item[1];
318 if((item[0] != 0 ) && (item[0] != 1) && (item[0] != 2)){ // 0 4G 1 3G
319 RLOGD("emAntennaTestStart: invalid parameter %d, operatorid: %d",item[0], operatorid);
320 android::emResultNotify(RET_STRING_ANTENNATEST_FAIL);
321 return -1;
322 }
323 switch(operatorid){
324 case 0://get
325 {
326 fgAntennaRead = true;
327 fgget = classid;
328 break;
329 }
330 case 1://set
331 {
332 printf("argc: %d, fgset: %d\n", argc, classid);
333 printf("itme[2]: %d\n", item[2]);
334 fgset = classid;
335 if(classid == 0){ // 4G
336 mAntennaMode = item[2];
337 } else if(classid == 1) { //3G
338 mAntennaMode = item[2]+ MODE_INDEX_BASE_3G;
339 } else if (classid == 2) { //C2K
340 mAntennaMode = item[2];
341 } else { // other
342 RLOGW("error classid");
343 android::emResultNotify(RET_STRING_ANTENNATEST_FAIL);
344 }
345 fgAntennaRead = false;
346 break;
347 }
348 }
349 android::registerForATcmdResponse(emAntennaAtCmdHandle);
350 pthread_t emantenna_thread;
351 pthread_create(&emantenna_thread,NULL, emAntennaTestThread, NULL);
352 return (0);
353}
354#endif
355