blob: 87c838002a3e74f033adbaf549bca11b7e3bc081 [file] [log] [blame]
/* Copyright Statement:
*
* This software/firmware and related documentation ("MediaTek Software") are
* protected under relevant copyright laws. The information contained herein
* is confidential and proprietary to MediaTek Inc. and/or its licensors.
* Without the prior written permission of MediaTek inc. and/or its licensors,
* any reproduction, modification, use or disclosure of MediaTek Software,
* and information contained herein, in whole or in part, shall be strictly prohibited.
*/
/* MediaTek Inc. (C) 2010. All rights reserved.
*
* BY OPENING THIS FILE, RECEIVER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES
* THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK SOFTWARE")
* RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE PROVIDED TO RECEIVER ON
* AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY DISCLAIMS ANY AND ALL WARRANTIES,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR NONINFRINGEMENT.
* NEITHER DOES MEDIATEK PROVIDE ANY WARRANTY WHATSOEVER WITH RESPECT TO THE
* SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY, INCORPORATED IN, OR
* SUPPLIED WITH THE MEDIATEK SOFTWARE, AND RECEIVER AGREES TO LOOK ONLY TO SUCH
* THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO. RECEIVER EXPRESSLY ACKNOWLEDGES
* THAT IT IS RECEIVER'S SOLE RESPONSIBILITY TO OBTAIN FROM ANY THIRD PARTY ALL PROPER LICENSES
* CONTAINED IN MEDIATEK SOFTWARE. MEDIATEK SHALL ALSO NOT BE RESPONSIBLE FOR ANY MEDIATEK
* SOFTWARE RELEASES MADE TO RECEIVER'S SPECIFICATION OR TO CONFORM TO A PARTICULAR
* STANDARD OR OPEN FORUM. RECEIVER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND
* CUMULATIVE LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL BE,
* AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT ISSUE,
* OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY RECEIVER TO
* MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE.
*
* The following software/firmware and/or related documentation ("MediaTek Software")
* have been modified by MediaTek Inc. All revisions are subject to any receiver's
* applicable license agreements with MediaTek Inc.
*/
#include <vendor-ril/telephony/ril.h>
#include <stdlib.h>
#include <stdio.h>
#include <cutils/jstring.h>
#include <log/log.h>
#include <unistd.h>
#include <math.h>
#include <vector>
#include <string>
#include <stdexcept>
#include "common.h"
#include "em/em.h"
#include "ModemCategory.h"
#include "Radio_capability_switch_util.h"
#include "../util/utils.h"
#if EM_MODE_SUPPORT
#undef LOG_TAG
#define LOG_TAG "EM_ANTENNA"
static const int MSG_QUERY_ANTENNA_MODE = 1;
static const int MSG_SET_ANTENNA_MODE = 2;
static const int MSG_QUERY_ANTENNA_MODE_C2K = 4;
static const int MSG_QUERY_ANTENNA_EGMC_4G = 5;
static const int MSG_SET_ANTENNA_EGMC_4G = 6;
static const int MSG_INIT_ANTENNA_EGMC_4G = 7;
static const int MODE_INDEX_BASE_3G = 10;
static const int MODE_EPCM_VALID = 0xFF;
static const int CELL_2RX_LENGTH = 2;
static const int CELL_4RX_LENGTH = 4;
int mCurrentEmantennaFlag = 0;
bool fgAntennaRead = true;
static int fgget = -1;
static int fgset = -1;
int mAntennaMode = 0;
char antennaretstring[128] = {0};
static const std::vector<std::string> antenna_modes_4g {
"RX1&RX2",
"RX1",
"RX2"
};
static const std::vector<std::string> antenna_modes_3g {
"Please select a mode:",
"RX1",
"RX2",
"RX1&RX2",
"Resume default setting"
};
static const std::vector<std::string> antenna_modes_c2k_mode {
"Resume default setting",
"RX1",
"RX2",
"RX1&RX2"
};
static void sendATCommand(const char *cmd,int msg)
{
mCurrentEmantennaFlag = msg;
emSendATCommand(cmd, Radio_capability_switch_util::get_main_capability_phone_id());
return ;
}
static void queryCurrentMode() {
char cmd_str[32] = {0};
sprintf(cmd_str,"%s","AT+ERXPATH?");
sendATCommand(cmd_str, MSG_QUERY_ANTENNA_MODE);
}
void queryCurrentCdmaMode() {
if (utils::is93Modem()) {
sendATCommand("AT+ERXTESTMODE?", MSG_QUERY_ANTENNA_MODE_C2K);
} else {
android::emResultNotify(RET_STRING_ANTENNATEST_FAIL);
RLOGD("don't support");
}
}
static void setMode(int mode) {
char cmd_str[32] = {0};
sprintf(cmd_str,"%s%d","AT+ERXPATH=",mode);
sendATCommand(cmd_str, MSG_SET_ANTENNA_MODE);
}
static void setCdmaMode(int mode) {
std::string str("AT+ERXTESTMODE=");
str.append(std::to_string(mode));
if (utils::is93Modem()) {
sendATCommand(str.c_str(), MSG_SET_ANTENNA_MODE);
} else {
android::emResultNotify(RET_STRING_ANTENNATEST_FAIL);
RLOGD("don't support");
}
}
static void parseCurrentMode(char* data) {
RLOGD("parseCurrentMode(%d):%s",fgget, data);
std::vector<std::string> out;
utils::tokenize(string(data), "\n", out);
std::string str;
str.clear();
if(fgget == 0 || fgget == 1) {
for(auto i: out) {
if(i.find("+ERXPATH:") != std::string::npos) {
try {
int mode = std::stoi(i.substr(std::string("+ERXPATH:").size()));
if (mode < 0 || (mode >= antenna_modes_4g.size()
&& mode >= MODE_INDEX_BASE_3G + mode >= antenna_modes_4g.size()
&& mode != MODE_EPCM_VALID)) {
android::emResultNotify(RET_STRING_ANTENNATEST_FAIL);
RLOGD("Modem returned invalid mode(%d): %s",mode, data);
return ;
} else {
if (mode == MODE_EPCM_VALID) {
android::emResultNotify(RET_STRING_ANTENNATEST_FAIL);
} else if (mode >= MODE_INDEX_BASE_3G) {
if(ModemCategory::getModemType() != ModemCategory::MODEM_TD) {
int pos = mode - MODE_INDEX_BASE_3G + 1;
RLOGD("parseCurrent3GMode is: %d", pos);
str.append("3G:");
str.append(antenna_modes_3g[pos]);
str.append(" ");
}
} else {
if (ModemCategory::isLteSupport()) {
RLOGD("parseCurrentLteMode is: %d", mode);
str.append("4G:");
str.append(antenna_modes_4g[mode]);
str.append(" ");
}
}
}
str.append("\ndone\n");
} catch (const out_of_range &e) {
android::emResultNotify(RET_STRING_ANTENNATEST_FAIL);
RLOGD("out of range: %s", e.what());
return;
} catch (const invalid_argument &e) {
android::emResultNotify(RET_STRING_ANTENNATEST_FAIL);
RLOGD("invalid argument: %s", e.what());
return;
}
}
}
android::emResultNotify(str.c_str());
} else if (fgget == 2) {
for(auto i: out) {
if(i.find("+ERXTESTMODE:") != std::string::npos) {
try {
int mode = std::stoi(i.substr(std::string("+ERXTESTMODE:").size()));
if (mode < 0 || mode >= antenna_modes_c2k_mode.size()) {
android::emResultNotify(RET_STRING_ANTENNATEST_FAIL);
RLOGD("Modem returned invalid mode(%d): %s",mode, data);
return;
} else {
RLOGD("parseCurrentC2KMode is: %d", mode);
str.append("CDMA:");
str.append(antenna_modes_c2k_mode[mode]);
str.append(" ");
}
str.append("\ndone\n");
} catch (const out_of_range &e) {
android::emResultNotify(RET_STRING_ANTENNATEST_FAIL);
RLOGD("out of range: %s", e.what());
return;
} catch (const invalid_argument &e) {
android::emResultNotify(RET_STRING_ANTENNATEST_FAIL);
RLOGD("invalid argument: %s", e.what());
return;
}
}
}
android::emResultNotify(str.c_str());
} else {
RLOGE("error choose!!!");
android::emResultNotify(RET_STRING_ANTENNATEST_FAIL);
}
return;
}
static void emAntennaAtCmdHandle(char*response, int responselen) {
switch (mCurrentEmantennaFlag) {
case MSG_QUERY_ANTENNA_MODE:
case MSG_QUERY_ANTENNA_MODE_C2K:
//parse antenna mode.
if ((responselen > 0) && (response != NULL)) {
RLOGD("Get mode %s", response);
parseCurrentMode(response);
} else {
RLOGD("Query antenna mode failed.");
sprintf(antennaretstring, "%s%s", ("Query antenna mode failed."),
RET_STRING_ANTENNATEST_FAIL);
android::emResultNotify(antennaretstring);
}
android::unregisterNetwork();
break;
case MSG_SET_ANTENNA_MODE:
memset(antennaretstring, 0, sizeof(antennaretstring));
if ((responselen > 0) && (response != NULL)) {
RLOGD("Set successful.");
sprintf(antennaretstring, "%s\n%s", ("Set successful."),
RET_STRING_ANTENNATEST_SUCCESS);
} else {
RLOGD("Set failed.");
sprintf(antennaretstring, "%s\n%s", ("Set failed."),
RET_STRING_ANTENNATEST_FAIL);
}
android::unregisterNetwork();
android::emResultNotify(antennaretstring);
break;
default:
RLOGD("error(%d)", mCurrentEmantennaFlag);
break;
}
}
//create thread to send command
static void * emAntennaTestThread(void* arg)
{
if(fgAntennaRead){
if(fgget == 0) { //4G
if (ModemCategory::isLteSupport()) {
queryCurrentMode();
} else {
android::emResultNotify("Antenna test don't support for 4G \ndone\n");
}
} else if (fgget == 1){ //3G
if (ModemCategory::getModemType() == ModemCategory::MODEM_TD) {
android::emResultNotify("Antenna test don't support for 3G \ndone\n");
} else {
queryCurrentMode();
}
} else if (fgget == 2) { //C2K
if(ModemCategory::isCdma()) {
queryCurrentCdmaMode();
} else {
android::emResultNotify("Antenna test don't support for C2K \ndone\n");
}
} else {
android::emResultNotify("Antenna test index error \ndone\n");
}
}else{
if(fgset == 0) { //4G
if (ModemCategory::isLteSupport()) {
setMode(mAntennaMode);
} else {
android::emResultNotify("Antenna test don't support for 4G \ndone\n");
}
} else if (fgset == 1){ //3G
if (ModemCategory::getModemType() == ModemCategory::MODEM_TD) {
android::emResultNotify("Antenna test don't support for 3G \ndone\n");
} else {
setMode(mAntennaMode);
}
} else if (fgset == 2) { //C2K
if(ModemCategory::isCdma()) {
setCdmaMode(mAntennaMode);
} else {
android::emResultNotify("Antenna test don't support for C2K \ndone\n");
}
} else {
android::emResultNotify("Antenna test index error \ndone\n");
}
}
pthread_exit(0);
}
int emAntennaTestStart(int argc, int *item,char *value)
{
RLOGD("emAntennaTestStart called");
if(argc < 2){
RLOGD("please select AntennaTest get or set :");
return -1;
}
mCurrentEmantennaFlag = 0;
int classid = item[0];
int operatorid = item[1];
if((item[0] != 0 ) && (item[0] != 1) && (item[0] != 2)){ // 0 4G 1 3G
RLOGD("emAntennaTestStart: invalid parameter %d, operatorid: %d",item[0], operatorid);
android::emResultNotify(RET_STRING_ANTENNATEST_FAIL);
return -1;
}
switch(operatorid){
case 0://get
{
fgAntennaRead = true;
fgget = classid;
break;
}
case 1://set
{
printf("argc: %d, fgset: %d\n", argc, classid);
printf("itme[2]: %d\n", item[2]);
fgset = classid;
if(classid == 0){ // 4G
mAntennaMode = item[2];
} else if(classid == 1) { //3G
mAntennaMode = item[2]+ MODE_INDEX_BASE_3G;
} else if (classid == 2) { //C2K
mAntennaMode = item[2];
} else { // other
RLOGW("error classid");
android::emResultNotify(RET_STRING_ANTENNATEST_FAIL);
}
fgAntennaRead = false;
break;
}
}
android::registerForATcmdResponse(emAntennaAtCmdHandle);
pthread_t emantenna_thread;
pthread_create(&emantenna_thread,NULL, emAntennaTestThread, NULL);
return (0);
}
#endif