imei 是怎么生成及获取的,原理是什么,如果改码的话,怎样才是最简单的最有效的?
推荐个源码阅读网站:http://www.aospxref.com/
这个速度挺好的。
- framework 层的接口获取
首先掉到这里
android.telephony.TelephonyManager
public String getDeviceId() {
try {
ITelephony telephony = getITelephony();
if (telephony == null)
return null;
return telephony.getDeviceId(mContext.getOpPackageName());
} catch (RemoteException ex) {
return null;
} catch (NullPointerException ex) {
return null;
}
}
- 在追踪会走到 GsmCdmaPhone.java 这个类里面
代码路径:
1454 @Override
1455 public String getDeviceId() {
1456 if (isPhoneTypeGsm()) {
1457 return mImei;
1458 } else {
1459 CarrierConfigManager configManager = (CarrierConfigManager)
1460 mContext.getSystemService(Context.CARRIER_CONFIG_SERVICE);
1461 boolean force_imei = configManager.getConfigForSubId(getSubId())
1462 .getBoolean(CarrierConfigManager.KEY_FORCE_IMEI_BOOL);
1463 if (force_imei) return mImei;
1464
1465 String id = getMeid();
1466 if ((id == null) || id.matches("^0*$")) {
1467 loge("getDeviceId(): MEID is not initialized use ESN");
1468 id = getEsn();
1469 }
1470 return id;
1471 }
1472 }
而这个 mImei 是怎么来的?这个是回调传过来的;
237 @Override
2238 public void handleMessage(Message msg) {
2239 AsyncResult ar;
2240 Message onComplete;
2241
2242 switch (msg.what) {
2243 case EVENT_RADIO_AVAILABLE: {
2244 handleRadioAvailable();
2245 }
2246 break;
2247
2248 case EVENT_GET_DEVICE_IDENTITY_DONE:{
2249 ar = (AsyncResult)msg.obj;
2250
2251 if (ar.exception != null) {
2252 break;
2253 }
2254 String[] respId = (String[])ar.result;
2255 mImei = respId[0];
2256 mImeiSv = respId[1];
2257 mEsn = respId[2];
2258 mMeid = respId[3];
- 根据 EVENT_GET_DEVICE_IDENTITY_DONE 类型往上搜谁会传这个类型;
代码路径:
这些定义变量都在 Phone.java 类内:
路径:http://www.aospxref.com/android-9.0.0_r45/xref/frameworks/opt/telephony/src/java/com/android/internal/telephony/Phone.java#174
2200 private void handleRadioAvailable() {
2201 mCi.getBasebandVersion(obtainMessage(EVENT_GET_BASEBAND_VERSION_DONE));
2202
2203 mCi.getDeviceIdentity(obtainMessage(EVENT_GET_DEVICE_IDENTITY_DONE));
2204 mCi.getRadioCapability(obtainMessage(EVENT_GET_RADIO_CAPABILITY));
2205 startLceAfterRadioIsAvailable();
2206 }
然后跟踪 mCi.getDeviceIdentity 这个函数
- 搜索 getDeviceIdentity 函数,会进入 RIL.java 类内
代码路径:
2804 @Override
2805 public void getDeviceIdentity(Message result) {
2806 IRadio radioProxy = getRadioProxy(result);
2807 if (radioProxy != null) {
2808 RILRequest rr = obtainRequest(RIL_REQUEST_DEVICE_IDENTITY, result,
2809 mRILDefaultWorkSource);
2810
2811 if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
2812
2813 try {
2814 radioProxy.getDeviceIdentity(rr.mSerial);
2815 } catch (RemoteException | RuntimeException e) {
2816 handleRadioProxyExceptionForRR(rr, "getDeviceIdentity", e);
2817 }
2818 }
2819 }
- 往下继续走 getDeviceIdentity(int) 函数,这里全局搜索,发小会走到 ril_service.cpp 类内;
源码路径:
http://www.aospxref.com/android-9.0.0_r45/xref/hardware/ril/libril/ril_service.cpp
1894 Return<void> RadioImpl::getDeviceIdentity(int32_t serial) {
1895 #if VDBG
1896 RLOGD("getDeviceIdentity: serial %d", serial);
1897 #endif
1898 dispatchVoid(serial, mSlotId, RIL_REQUEST_DEVICE_IDENTITY);
1899 return Void();
1900 }
然后会走到 dispatchVoid 函数内;
538 bool dispatchVoid(int serial, int slotId, int request) {
539 RequestInfo *pRI = android::addRequestToList(serial, slotId, request);
540 if (pRI == NULL) {
541 return false;
542 }
543 CALL_ONREQUEST(request, NULL, 0, pRI, slotId);
544 return true;
545 }
而这里 CALL_ONREQUEST 函数的定义是
RIL_RadioFunctions *s_vendorFunctions = NULL;
#define CALL_ONREQUEST(a, b, c, d, e) s_vendorFunctions->onRequest((a), (b), (c), (d))
而 s_vendorFunctions 函数的来源呢?在这
代码地址:http://www.aospxref.com/android-9.0.0_r45/xref/hardware/ril/libril/ril_service.cpp#8506
8486 void radio::registerService(RIL_RadioFunctions *callbacks, CommandInfo *commands) {
8487 using namespace android::hardware;
8488 int simCount = 1;
8489 const char *serviceNames[] = {
8490 android::RIL_getServiceName()
8491 #if (SIM_COUNT >= 2)
8492 , RIL2_SERVICE_NAME
8493 #if (SIM_COUNT >= 3)
8494 , RIL3_SERVICE_NAME
8495 #if (SIM_COUNT >= 4)
8496 , RIL4_SERVICE_NAME
8497 #endif
8498 #endif
8499 #endif
8500 };
8501
8502 #if (SIM_COUNT >= 2)
8503 simCount = SIM_COUNT;
8504 #endif
8505
8506 s_vendorFunctions = callbacks;
- 这里要看 RIL_RadioFunctions 的 onRequest 函数,
RIL_RadioFunctions 结构体的定义是:
代码路径:http://www.aospxref.com/android-9.0.0_r45/xref/hardware/ril/reference-ril/ril.h#7126
7119 typedef struct {
7120 int version; /* set to RIL_VERSION */
7121 RIL_RequestFunc onRequest;
7122 RIL_RadioStateRequest onStateRequest;
7123 RIL_Supports supports;
7124 RIL_Cancel onCancel;
7125 RIL_GetVersion getVersion;
7126 } RIL_RadioFunctions;
- 接着第 6 步,所以需要追 registerService 函数,然后会追到 ril_service.cpp 类内
代码地址:
http://www.aospxref.com/android-9.0.0_r45/xref/hardware/ril/libril/ril.cpp#461
423 extern "C" void
424 RIL_register (const RIL_RadioFunctions *callbacks) {
425 RLOGI("SIM_COUNT: %d", SIM_COUNT);
426
427 if (callbacks == NULL) {
428 RLOGE("RIL_register: RIL_RadioFunctions * null");
429 return;
430 }
431 if (callbacks->version < RIL_VERSION_MIN) {
432 RLOGE("RIL_register: version %d is to old, min version is %d",
433 callbacks->version, RIL_VERSION_MIN);
.......
memcpy(&s_callbacks, callbacks, sizeof (RIL_RadioFunctions));
.......
461 radio::registerService(&s_callbacks, s_commands);
462 RLOGI("RILHIDL called registerService");
463
464 }
- 可以看到 s_callbacks 来自 callbacks 所以继续往上追;
追到 rild.c 内;
代码地址:
http://www.aospxref.com/android-9.0.0_r45/xref/hardware/ril/rild/rild.c#216
101 int main(int argc, char **argv) {
......
213 funcs = rilInit(&s_rilEnv, argc, rilArgv);
214 RLOGD("RIL_Init rilInit completed");
215
216 RIL_register(funcs);
217
218 RLOGD("RIL_Init RIL_register completed");
219
220 if (rilUimInit) {
221 RLOGD("RIL_register_socket started");
222 RIL_register_socket(rilUimInit, RIL_SAP_SOCKET, argc, rilArgv);
223 }
在这个函数没会调用 dlsym(dlHandle, "RIL_Init"); 函数来获取句柄,可以仔细去看完整的函数代码;
- 所以根据 "RIL_Init" 继续往上追,可以追到 reference-ril.c 内
代码地址:
http://www.aospxref.com/android-9.0.0_r45/xref/hardware/ril/reference-ril/reference-ril.c#3766
3766 const RIL_RadioFunctions *RIL_Init(const struct RIL_Env *env, int argc, char **argv)
3767 {
3768 int ret;
3769 int fd = -1;
......
3821 return &s_callbacks;
3822 }
这个函数会返回 s_callbacks,所以看下 s_callbacks 是什么;
198 static const RIL_RadioFunctions s_callbacks = {
199 RIL_VERSION,
200 onRequest,
201 currentState,
202 onSupports,
203 onCancel,
204 getVersion
205 };
可以看到 s_callbacks 结构体的定义,所以 onRequest 函数就是 RIL_RequestFunc 函数,对应第 6 步内;
- 所以应该分析 s_callbacks->onRequest 函数
代码地址:
http://www.aospxref.com/android-9.0.0_r45/xref/hardware/ril/reference-ril/reference-ril.c#onRequest
2344 static void
2345 onRequest (int request, void *data, size_t datalen, RIL_Token t)
2346 {
2347 ATResponse *p_response;
2348 int err;
2349 ......
2544 case RIL_REQUEST_GET_IMEI:
2545 p_response = NULL;
2546 err = at_send_command_numeric("AT+CGSN", &p_response);
2547
2548 if (err < 0 || p_response->success == 0) {
2549 RIL_onRequestComplete(t, RIL_E_GENERIC_FAILURE, NULL, 0);
2550 } else {
2551 RIL_onRequestComplete(t, RIL_E_SUCCESS,
2552 p_response->p_intermediates->line, sizeof(char *));
2553 }
2554 at_response_free(p_response);
2555 break;
2556
代码地址: http://www.aospxref.com/android-9.0.0_r45/xref/hardware/ril/reference-ril/reference-ril.c#2544
这里面有很多 case ,只单看 RIL_REQUEST_GET_IMEI 可以看到 imei 的获取方式是通过 "AT+CGSN" 的命令获取的;
搞 rom 开发改码,是不是可以在 这个 case 内把要改的值给返回呢?
而 "AT+CGSN" 背后的原理是什么呢?
- 贴个 at_send_command_numeric 命令
代码地址:http://www.aospxref.com/android-9.0.0_r45/xref/hardware/ril/reference-ril/atchannel.c#816
- 而 "AT+CGSN" 背后的原理是什么呢?
网友评论