blob: ec3fac6383ffe9a7989cabf5087e0f92f002cccd [file] [log] [blame]
/* //device/system/rild/rild.c
**
** Copyright 2006 The Android Open Source Project
**
** Licensed under the Apache License, Version 2.0 (the "License");
** you may not use this file except in compliance with the License.
** You may obtain a copy of the License at
**
** http://www.apache.org/licenses/LICENSE-2.0
**
** Unless required by applicable law or agreed to in writing, software
** distributed under the License is distributed on an "AS IS" BASIS,
** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
** See the License for the specific language governing permissions and
** limitations under the License.
*/
#include <stdio.h>
#include <stdlib.h>
#include <dlfcn.h>
#include <string.h>
#include <stdint.h>
#include <unistd.h>
#include <fcntl.h>
#include <errno.h>
#include <malloc.h>
//xy.he add for platform 2023_08_18 start
#include <dlfcn.h>
//xy.he add for platform 2023_08_18 end
#include "mipc_msg_host.h"
#include <telephony/mtk_ril.h>
#define LOG_TAG "RILD"
#include <cutils/sockets.h>
#ifdef __ANDROID__
#include <sys/capability.h>
#include <cutils/android_filesystem_config.h>
#else
#include <linux/capability.h>
#endif
#include <sys/prctl.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <signal.h>
#include <librilmtk/ril_ex.h>
#ifdef MTK_SYSENV_SUPPORT
#include "sysenv_utils.h"
#endif
#include <mtk_log.h>
#include <mtk_properties.h>
#include <mtkconfigutils.h>
#include <mipc_trm.h>
#if defined(PRODUCT_COMPATIBLE_PROPERTY)
#define LIB_PATH_PROPERTY "vendor.rild.libpath"
#define LIB_ARGS_PROPERTY "vendor.rild.libargs"
#else
#define LIB_PATH_PROPERTY "rild.libpath"
#define LIB_ARGS_PROPERTY "rild.libargs"
#endif
#define MAX_LIB_ARGS 16
//xy.he add for platform 2023_08_18 start
#define DEBUG_MODE_CHECK
//xy.he add for platform 2023_08_18 end
static void usage(const char *argv0) {
fprintf(stderr, "Usage: %s -l <ril impl library> [-- <args for impl library>]\n", argv0);
exit(EXIT_FAILURE);
}
//extern char ril_service_name_base[MAX_SERVICE_NAME_LENGTH];
//extern char ril_service_name[MAX_SERVICE_NAME_LENGTH];
extern void RIL_register (const RIL_RadioFunctions *callbacks);
extern const RIL_RadioFunctions *RIL_Init(const struct RIL_Env *env, int argc __unused,
char **argv __unused);
extern void RIL_onRequestComplete(RIL_Token t, RIL_Errno e,
void *response, size_t responselen);
extern void RIL_onRequestAck(RIL_Token t);
#if defined(ANDROID_MULTI_SIM)
extern void RIL_onUnsolicitedResponse(int unsolResponse, const void *data,
size_t datalen, RIL_SOCKET_ID socket_id);
#else
extern void RIL_onUnsolicitedResponse(int unsolResponse, const void *data,
size_t datalen);
#endif
extern void RIL_requestTimedCallback (RIL_TimedCallback callback,
void *param, const struct timeval *relativeTime);
extern void RIL_onIssueLocalRequest(int request, void *data, int len, RIL_SOCKET_ID socket_id);
//xy.he add for platform 2023_08_18 start
int (*lynq_get_value)(char *file, char *section, char *key, char *tmp);
//xy.he add for platform 2023_08_18 end
static struct RIL_Env s_rilEnv = {
RIL_onRequestComplete,
RIL_onUnsolicitedResponse,
RIL_requestTimedCallback,
RIL_onRequestAck,
NULL,
NULL,
NULL,
/// MTK_RIL_ADAPTER @{
RIL_onIssueLocalRequest,
/// @}
};
extern void RIL_startEventLoop();
extern RIL_startNetagent(void);
static int isReseted = 0;
int isUserLoad() {
int isUserLoad = 0;
char property_value_emulation[MTK_PROPERTY_VALUE_MAX] = { 0 };
char property_value[MTK_PROPERTY_VALUE_MAX] = { 0 };
mtk_property_get("vendor.ril.emulation.userload", property_value_emulation, "0");
if(strcmp("1", property_value_emulation) == 0) {
return 1;
}
mtk_property_get("ro.build.type", property_value, "");
isUserLoad = (strcmp("user", property_value) == 0);
//mtkLogD(LOG_TAG, "isUserLoad: %d", isUserLoad);
return isUserLoad;
}
int isInternalLoad() {
#ifdef __PRODUCTION_RELEASE__
return 0;
#else
char property_value[MTK_PROPERTY_VALUE_MAX] = { 0 };
mtk_property_get("vendor.ril.emulation.production", property_value, "0");
return (strcmp("1", property_value) != 0);
#endif /* __PRODUCTION_RELEASE__ */
}
/*
* Purpose: Function responsible by all signal handlers treatment any new signal must be added here
* Input: param - signal ID
* Return: -
*/
void signal_treatment(int param)
{
mtkLogD(LOG_TAG, "signal_no=%d", param);
switch (param) {
case SIGUSR1:
mtkLogD(LOG_TAG, "SIGUSR1");
break;
case SIGUSR2:
mtkLogD(LOG_TAG, "SIGUSR2");
break;
case SIGSEGV:
case SIGPIPE:
if (!isReseted) {
mtkLogD(LOG_TAG, "SIGSEGV or SIGPIPE");
mtk_property_set("vendor.ril.mux.report.case","2");
mtk_property_set("vendor.ril.muxreport", "1");
mipc_reset();
isReseted = 1;
} else {
mtkLogD(LOG_TAG, "already reset");
}
break;
default:
exit(2);
break;
}
}
void mtkInit() {
//signals treatment
signal(SIGPIPE, signal_treatment);
signal(SIGUSR1, signal_treatment);
signal(SIGUSR2, signal_treatment);
if ((isInternalLoad() == 0) && (isUserLoad() == 1)) {
mtkLogD(LOG_TAG, "Setup SIGSEGV signal handling");
signal(SIGSEGV, signal_treatment);
}
}
static int make_argv(char * args, char ** argv) {
// Note: reserve argv[0]
int count = 1;
char * tok;
char * s = args;
while ((tok = strtok(s, " \0"))) {
argv[count] = tok;
s = NULL;
count++;
}
return count;
}
void setDynamicMsimConfig() {
char prop_value[MTK_PROPERTY_VALUE_MAX] = { 0 };
// update dynamic multisim config
#ifdef MTK_SYSENV_SUPPORT
const char *pSysenv = sysenv_get_static("msim_config");
#else
const char *pSysenv = NULL;
#endif
mtkLogD(LOG_TAG, "sysenv_get_static: %s\n", pSysenv);
if (pSysenv != NULL) {
// for META tool
FeatureValue featurevalue;
if (strcmp(pSysenv, "dsds") == 0) {
strncpy(featurevalue.value, "dsds", 10);
mtkSetFeature(CONFIG_SIM_MODE, &featurevalue);
mtk_property_set("persist.vendor.radio.msimmode", "dsds");
mtk_property_set("persist.vendor.radio.multisimslot", "2");
} else if (strcmp(pSysenv, "ss") == 0) {
strncpy(featurevalue.value, "ss", 10);
mtkSetFeature(CONFIG_SIM_MODE, &featurevalue);
mtk_property_set("persist.vendor.radio.msimmode", "ss");
mtk_property_set("persist.vendor.radio.multisimslot", "1");
}
} else {
// for EM
FeatureValue featurevalue;
memset(featurevalue.value, 0, sizeof(featurevalue.value));
mtkGetFeature(CONFIG_SIM_MODE, &featurevalue);
if (strcmp(featurevalue.value, "dsda") != 0) {
mtk_property_get("persist.vendor.radio.multisimslot", prop_value, "0");
if (prop_value[0] == '1') {
strncpy(featurevalue.value, "ss", 10);
mtkSetFeature(CONFIG_SIM_MODE, &featurevalue);
mtk_property_set("persist.vendor.radio.msimmode", "ss");
} else if (prop_value[0] == '2') {
strncpy(featurevalue.value, "dsds", 10);
mtkSetFeature(CONFIG_SIM_MODE, &featurevalue);
mtk_property_set("persist.vendor.radio.msimmode", "dsds");
} else if (prop_value[0] == '3') {
strncpy(featurevalue.value, "tsts", 10);
mtkSetFeature(CONFIG_SIM_MODE, &featurevalue);
mtk_property_set("persist.vendor.radio.msimmode", "tsts");
} else if (prop_value[0] == '4') {
strncpy(featurevalue.value, "qsqs", 10);
mtkSetFeature(CONFIG_SIM_MODE, &featurevalue);
mtk_property_set("persist.vendor.radio.msimmode", "qsqs");
}
}
}
}
void sleep_wait_md_ready(void *cb_priv) {
sleep(0.1);
}
//xy.he add for platform 2023_08_18 start
int lynq_get_debug_mode(){
void *dlHandle_uci = NULL;
char test[24] = "0";
//uci lib path
const char *lynqLibPath_uci = "/lib64/liblynq-uci.so";
int ret = -1;
// load lynq_get_value() fuction to load uci setting
dlHandle_uci = dlopen(lynqLibPath_uci, RTLD_NOW);
mtkLogI(LOG_TAG, "start load debug_mode");
if (dlHandle_uci == NULL)
{
mtkLogD(LOG_TAG, "dlopen dlHandle_uci failed: %s,use standard.", dlerror());
return 0;
}
else
{
mtkLogI(LOG_TAG, "dlopen dlHandle_uci success");
}
lynq_get_value = (int(*)(char *file, char *section, char *key, char *tmp))dlsym(dlHandle_uci, "lynq_get_value");
if (lynq_get_value == NULL)
{
mtkLogD(LOG_TAG, "dlopen lynq_get_value failed: %s use standard.", dlerror());
}
else
{
mtkLogI(LOG_TAG, "dlopen lynq_Get_value success");
ret = lynq_get_value("lynq_uci","debug_mode","rild_debug_status",test);
mtkLogI(LOG_TAG,"lynq_debug_mode_type ret is %d", ret);
if(ret != 0)
{
mtkLogI(LOG_TAG,"lynq_get_value failed,use standard");
}
}
mtkLogI(LOG_TAG,"lynq_debug_mode_type is %s", test);
dlclose(dlHandle_uci);
return atoi(test);
}
//xy.he add for platform 2023_08_18 end
int main(int argc, char **argv) {
// vendor ril lib path either passed in as -l parameter, or read from rild.libpath property
const char *rilLibPath = NULL;
// ril arguments either passed in as -- parameter, or read from rild.libargs property
char **rilArgv;
// handle for vendor ril lib
void *dlHandle;
// Pointer to ril init function in vendor ril
const RIL_RadioFunctions *(*rilInit)(const struct RIL_Env *, int, char **);
// Pointer to sap init function in vendor ril
const RIL_RadioFunctions *(*rilUimInit)(const struct RIL_Env *, int, char **);
const char *err_str = NULL;
// functions returned by ril init function in vendor ril
const RIL_RadioFunctions *funcs;
// lib path from rild.libpath property (if it's read)
char libPath[MTK_PROPERTY_VALUE_MAX];
// flat to indicate if -- parameters are present
unsigned char hasLibArgs = 0;
int i;
// ril/socket id received as -c parameter, otherwise set to 0
const char *clientId = NULL;
//mode 1 is debug, 0 is standard default 0
int mode = 0;
//mallopt(M_TOP_PAD, 0);
//mallopt(M_TRIM_THRESHOLD, 32*1024);
//mallopt(M_MMAP_THRESHOLD, 8*1024);
//mallopt(M_MXFAST, 0);
mtkLogI(LOG_TAG, "**RIL Proxy Started**");
mtkLogD(LOG_TAG, "**RILd param count=%d**", argc);
setDynamicMsimConfig();
mtkInit();
#if 0//for colgin test
mtk_property_set("persist.radio.default.sim","0");
mtk_property_set("ro.telephony.sim.count","2");
mtk_property_set("persist.radio.dsss.sim.disable","2");
mtk_property_set("persist.ril.client.num","1");
mtk_property_set("persist.radio.multisim.config","dsss");
#endif
umask(S_IRGRP | S_IWGRP | S_IXGRP | S_IROTH | S_IWOTH | S_IXOTH);
for (i = 1; i < argc ;) {
if (0 == strcmp(argv[i], "-l") && (argc - i > 1)) {
rilLibPath = argv[i + 1];
i += 2;
} else if (0 == strcmp(argv[i], "--")) {
i++;
hasLibArgs = 1;
break;
} else if (0 == strcmp(argv[i], "-c") && (argc - i > 1)) {
clientId = argv[i+1];
i += 2;
} else {
usage(argv[0]);
}
}
if (clientId == NULL) {
clientId = "0";
} else if (atoi(clientId) >= MAX_RILDS) {
mtkLogE(LOG_TAG, "Max Number of rild's supported is: %d", MAX_RILDS);
exit(0);
}
mtkLogD(LOG_TAG, "mipc init start");
WAIT_MD_READY_API(sleep_wait_md_ready,NULL);
SETCOM("/dev/ttyCMIPC7");
//xy.he add for platform 2023_08_18 start
#ifdef DEBUG_MODE_CHECK
mode = lynq_get_debug_mode();
if(mode == 1)
{
mtkLogD(LOG_TAG,"mode is debug");
mipc_init_debug("/var/log/rild");//enable mipc log
}
else
{
mtkLogD(LOG_TAG,"mode is standard");
mipc_init("rild");//enable mipc log
}
#else
mipc_init("rild");//enable mipc log
#endif
//xy.he add for platform 2023_08_18 end
mtkLogD(LOG_TAG, "mipc init done");
RIL_startEventLoop();
if (hasLibArgs) {
rilArgv = argv + i - 1;
argc = argc -i + 1;
} else {
static char * newArgv[MAX_LIB_ARGS];
static char args[MTK_PROPERTY_VALUE_MAX];
rilArgv = newArgv;
mtk_property_get(LIB_ARGS_PROPERTY, args, "");
argc = make_argv(args, rilArgv);
}
rilArgv[argc++] = "-c";
rilArgv[argc++] = (char*)clientId;
mtkLogD(LOG_TAG, "RIL_Init argc = %d clientId = %s", argc, rilArgv[argc-1]);
// Make sure there's a reasonable argv[0]
rilArgv[0] = argv[0];
funcs = RIL_Init(&s_rilEnv, argc, rilArgv);
mtkLogI(LOG_TAG, "RIL_Init completed %x",funcs);
RIL_register(funcs);
mtkLogI(LOG_TAG, "RIL_register completed");
mtkLogI(LOG_TAG, "start netagent");
RIL_startNetagent();
mtkLogI(LOG_TAG, "started netagent");
done:
mtkLogD(LOG_TAG, "RIL_Init starting sleep loop");
while (true) {
sleep(UINT32_MAX);
}
}