| /* 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 |
| |