Android 电话系统框架介绍
在android系统中rild运行在AP上,AP上的应用通过rild发送AT指令给BP,BP接收到信息后又通过rild传送给AP。AP与BP之间有两种通信方式:
1.Solicited Response:Ap向Bp发送请求,Bp给Ap发送回复,该类型的AT指令及其回调函数以数组的形式存放在Ril_commands.h文件中:
{数组中的索引号,请求回调函数,响应回调函数}
- {0, NULL, NULL}, //none
- {RIL_REQUEST_GET_SIM_STATUS, dispatchVoid, responseSimStatus},
- {RIL_REQUEST_ENTER_SIM_PIN, dispatchStrings, responseInts},
- {RIL_REQUEST_ENTER_SIM_PUK, dispatchStrings, responseInts},
- {RIL_REQUEST_ENTER_SIM_PIN2, dispatchStrings, responseInts},
- {RIL_REQUEST_ENTER_SIM_PUK2, dispatchStrings, responseInts},
- {RIL_REQUEST_CHANGE_SIM_PIN, dispatchStrings, responseInts},
- {RIL_REQUEST_CHANGE_SIM_PIN2, dispatchStrings, responseInts},
- {RIL_REQUEST_ENTER_NETWORK_DEPERSONALIZATION, dispatchStrings, responseInts},
- {RIL_REQUEST_GET_CURRENT_CALLS, dispatchVoid, responseCallList},
- {RIL_REQUEST_DIAL, dispatchDial, responseVoid},
- {RIL_REQUEST_GET_IMSI, dispatchStrings, responseString},
- {RIL_REQUEST_HANGUP, dispatchInts, responseVoid},
- {RIL_REQUEST_HANGUP_WAITING_OR_BACKGROUND, dispatchVoid, responseVoid},
- {RIL_REQUEST_HANGUP_FOREGROUND_RESUME_BACKGROUND, dispatchVoid, responseVoid},
- {RIL_REQUEST_SWITCH_WAITING_OR_HOLDING_AND_ACTIVE, dispatchVoid, responseVoid},
- {RIL_REQUEST_CONFERENCE, dispatchVoid, responseVoid},
- {RIL_REQUEST_UDUB, dispatchVoid, responseVoid},
- {RIL_REQUEST_LAST_CALL_FAIL_CAUSE, dispatchVoid, responseInts},
- {RIL_REQUEST_SIGNAL_STRENGTH, dispatchVoid, responseRilSignalStrength},
- {RIL_REQUEST_VOICE_REGISTRATION_STATE, dispatchVoid, responseStrings},
- {RIL_REQUEST_DATA_REGISTRATION_STATE, dispatchVoid, responseStrings},
- {RIL_REQUEST_OPERATOR, dispatchVoid, responseStrings},
- {RIL_REQUEST_RADIO_POWER, dispatchInts, responseVoid},
- {RIL_REQUEST_DTMF, dispatchString, responseVoid},
- {RIL_REQUEST_SEND_SMS, dispatchStrings, responseSMS},
- {RIL_REQUEST_SEND_SMS_EXPECT_MORE, dispatchStrings, responseSMS},
- {RIL_REQUEST_SETUP_DATA_CALL, dispatchDataCall, responseSetupDataCall},
- {RIL_REQUEST_SIM_IO, dispatchSIM_IO, responseSIM_IO},
- {RIL_REQUEST_SEND_USSD, dispatchString, responseVoid},
- {RIL_REQUEST_CANCEL_USSD, dispatchVoid, responseVoid},
- {RIL_REQUEST_GET_CLIR, dispatchVoid, responseInts},
- {RIL_REQUEST_SET_CLIR, dispatchInts, responseVoid},
- {RIL_REQUEST_QUERY_CALL_FORWARD_STATUS, dispatchCallForward, responseCallForwards},
- {RIL_REQUEST_SET_CALL_FORWARD, dispatchCallForward, responseVoid},
- {RIL_REQUEST_QUERY_CALL_WAITING, dispatchInts, responseInts},
- {RIL_REQUEST_SET_CALL_WAITING, dispatchInts, responseVoid},
- {RIL_REQUEST_SMS_ACKNOWLEDGE, dispatchInts, responseVoid},
- {RIL_REQUEST_GET_IMEI, dispatchVoid, responseString},
- {RIL_REQUEST_GET_IMEISV, dispatchVoid, responseString},
- {RIL_REQUEST_ANSWER,dispatchVoid, responseVoid},
- {RIL_REQUEST_DEACTIVATE_DATA_CALL, dispatchStrings, responseVoid},
- {RIL_REQUEST_QUERY_FACILITY_LOCK, dispatchStrings, responseInts},
- {RIL_REQUEST_SET_FACILITY_LOCK, dispatchStrings, responseInts},
- {RIL_REQUEST_CHANGE_BARRING_PASSWORD, dispatchStrings, responseVoid},
- {RIL_REQUEST_QUERY_NETWORK_SELECTION_MODE, dispatchVoid, responseInts},
- {RIL_REQUEST_SET_NETWORK_SELECTION_AUTOMATIC, dispatchVoid, responseVoid},
- {RIL_REQUEST_SET_NETWORK_SELECTION_MANUAL, dispatchString, responseVoid},
- {RIL_REQUEST_QUERY_AVAILABLE_NETWORKS , dispatchVoid, responseStrings},
- {RIL_REQUEST_DTMF_START, dispatchString, responseVoid},
- {RIL_REQUEST_DTMF_STOP, dispatchVoid, responseVoid},
- {RIL_REQUEST_BASEBAND_VERSION, dispatchVoid, responseString},
- {RIL_REQUEST_SEPARATE_CONNECTION, dispatchInts, responseVoid},
- {RIL_REQUEST_SET_MUTE, dispatchInts, responseVoid},
- {RIL_REQUEST_GET_MUTE, dispatchVoid, responseInts},
- {RIL_REQUEST_QUERY_CLIP, dispatchVoid, responseInts},
- {RIL_REQUEST_LAST_DATA_CALL_FAIL_CAUSE, dispatchVoid, responseInts},
- {RIL_REQUEST_DATA_CALL_LIST, dispatchVoid, responseDataCallList},
- {RIL_REQUEST_RESET_RADIO, dispatchVoid, responseVoid},
- {RIL_REQUEST_OEM_HOOK_RAW, dispatchRaw, responseRaw},
- {RIL_REQUEST_OEM_HOOK_STRINGS, dispatchStrings, responseStrings},
- {RIL_REQUEST_SCREEN_STATE, dispatchInts, responseVoid},
- {RIL_REQUEST_SET_SUPP_SVC_NOTIFICATION, dispatchInts, responseVoid},
- {RIL_REQUEST_WRITE_SMS_TO_SIM, dispatchSmsWrite, responseInts},
- {RIL_REQUEST_DELETE_SMS_ON_SIM, dispatchInts, responseVoid},
- {RIL_REQUEST_SET_BAND_MODE, dispatchInts, responseVoid},
- {RIL_REQUEST_QUERY_AVAILABLE_BAND_MODE, dispatchVoid, responseInts},
- {RIL_REQUEST_STK_GET_PROFILE, dispatchVoid, responseString},
- {RIL_REQUEST_STK_SET_PROFILE, dispatchString, responseVoid},
- {RIL_REQUEST_STK_SEND_ENVELOPE_COMMAND, dispatchString, responseString},
- {RIL_REQUEST_STK_SEND_TERMINAL_RESPONSE, dispatchString, responseVoid},
- {RIL_REQUEST_STK_HANDLE_CALL_SETUP_REQUESTED_FROM_SIM, dispatchInts, responseVoid},
- {RIL_REQUEST_EXPLICIT_CALL_TRANSFER, dispatchVoid, responseVoid},
- {RIL_REQUEST_SET_PREFERRED_NETWORK_TYPE, dispatchInts, responseVoid},
- {RIL_REQUEST_GET_PREFERRED_NETWORK_TYPE, dispatchVoid, responseInts},
- {RIL_REQUEST_GET_NEIGHBORING_CELL_IDS, dispatchVoid, responseCellList},
- {RIL_REQUEST_SET_LOCATION_UPDATES, dispatchInts, responseVoid},
- {RIL_REQUEST_CDMA_SET_SUBSCRIPTION_SOURCE, dispatchInts, responseVoid},
- {RIL_REQUEST_CDMA_SET_ROAMING_PREFERENCE, dispatchInts, responseVoid},
- {RIL_REQUEST_CDMA_QUERY_ROAMING_PREFERENCE, dispatchVoid, responseInts},
- {RIL_REQUEST_SET_TTY_MODE, dispatchInts, responseVoid},
- {RIL_REQUEST_QUERY_TTY_MODE, dispatchVoid, responseInts},
- {RIL_REQUEST_CDMA_SET_PREFERRED_VOICE_PRIVACY_MODE, dispatchInts, responseVoid},
- {RIL_REQUEST_CDMA_QUERY_PREFERRED_VOICE_PRIVACY_MODE, dispatchVoid, responseInts},
- {RIL_REQUEST_CDMA_FLASH, dispatchString, responseVoid},
- {RIL_REQUEST_CDMA_BURST_DTMF, dispatchStrings, responseVoid},
- {RIL_REQUEST_CDMA_VALIDATE_AND_WRITE_AKEY, dispatchString, responseVoid},
- {RIL_REQUEST_CDMA_SEND_SMS, dispatchCdmaSms, responseSMS},
- {RIL_REQUEST_CDMA_SMS_ACKNOWLEDGE, dispatchCdmaSmsAck, responseVoid},
- {RIL_REQUEST_GSM_GET_BROADCAST_SMS_CONFIG, dispatchVoid, responseGsmBrSmsCnf},
- {RIL_REQUEST_GSM_SET_BROADCAST_SMS_CONFIG, dispatchGsmBrSmsCnf, responseVoid},
- {RIL_REQUEST_GSM_SMS_BROADCAST_ACTIVATION, dispatchInts, responseVoid},
- {RIL_REQUEST_CDMA_GET_BROADCAST_SMS_CONFIG, dispatchVoid, responseCdmaBrSmsCnf},
- {RIL_REQUEST_CDMA_SET_BROADCAST_SMS_CONFIG, dispatchCdmaBrSmsCnf, responseVoid},
- {RIL_REQUEST_CDMA_SMS_BROADCAST_ACTIVATION, dispatchInts, responseVoid},
- {RIL_REQUEST_CDMA_SUBSCRIPTION, dispatchVoid, responseStrings},
- {RIL_REQUEST_CDMA_WRITE_SMS_TO_RUIM, dispatchRilCdmaSmsWriteArgs, responseInts},
- {RIL_REQUEST_CDMA_DELETE_SMS_ON_RUIM, dispatchInts, responseVoid},
- {RIL_REQUEST_DEVICE_IDENTITY, dispatchVoid, responseStrings},
- {RIL_REQUEST_EXIT_EMERGENCY_CALLBACK_MODE, dispatchVoid, responseVoid},
- {RIL_REQUEST_GET_SMSC_ADDRESS, dispatchVoid, responseString},
- {RIL_REQUEST_SET_SMSC_ADDRESS, dispatchString, responseVoid},
- {RIL_REQUEST_REPORT_SMS_MEMORY_STATUS, dispatchInts, responseVoid},
- {RIL_REQUEST_REPORT_STK_SERVICE_IS_RUNNING, dispatchVoid, responseVoid},
- {RIL_REQUEST_CDMA_GET_SUBSCRIPTION_SOURCE, dispatchCdmaSubscriptionSource, responseInts},
- {RIL_REQUEST_ISIM_AUTHENTICATION, dispatchString, responseString},
- {RIL_REQUEST_ACKNOWLEDGE_INCOMING_GSM_SMS_WITH_PDU, dispatchStrings, responseVoid},
- {RIL_REQUEST_STK_SEND_ENVELOPE_WITH_STATUS, dispatchString, responseSIM_IO},
- {RIL_REQUEST_VOICE_RADIO_TECH, dispatchVoiceRadioTech, responseInts},
- {0, NULL, NULL}, //none
- {RIL_REQUEST_GET_SIM_STATUS, dispatchVoid, responseSimStatus},
- {RIL_REQUEST_ENTER_SIM_PIN, dispatchStrings, responseInts},
- {RIL_REQUEST_ENTER_SIM_PUK, dispatchStrings, responseInts},
- {RIL_REQUEST_ENTER_SIM_PIN2, dispatchStrings, responseInts},
- {RIL_REQUEST_ENTER_SIM_PUK2, dispatchStrings, responseInts},
- {RIL_REQUEST_CHANGE_SIM_PIN, dispatchStrings, responseInts},
- {RIL_REQUEST_CHANGE_SIM_PIN2, dispatchStrings, responseInts},
- {RIL_REQUEST_ENTER_NETWORK_DEPERSONALIZATION, dispatchStrings, responseInts},
- {RIL_REQUEST_GET_CURRENT_CALLS, dispatchVoid, responseCallList},
- {RIL_REQUEST_DIAL, dispatchDial, responseVoid},
- {RIL_REQUEST_GET_IMSI, dispatchStrings, responseString},
- {RIL_REQUEST_HANGUP, dispatchInts, responseVoid},
- {RIL_REQUEST_HANGUP_WAITING_OR_BACKGROUND, dispatchVoid, responseVoid},
- {RIL_REQUEST_HANGUP_FOREGROUND_RESUME_BACKGROUND, dispatchVoid, responseVoid},
- {RIL_REQUEST_SWITCH_WAITING_OR_HOLDING_AND_ACTIVE, dispatchVoid, responseVoid},
- {RIL_REQUEST_CONFERENCE, dispatchVoid, responseVoid},
- {RIL_REQUEST_UDUB, dispatchVoid, responseVoid},
- {RIL_REQUEST_LAST_CALL_FAIL_CAUSE, dispatchVoid, responseInts},
- {RIL_REQUEST_SIGNAL_STRENGTH, dispatchVoid, responseRilSignalStrength},
- {RIL_REQUEST_VOICE_REGISTRATION_STATE, dispatchVoid, responseStrings},
- {RIL_REQUEST_DATA_REGISTRATION_STATE, dispatchVoid, responseStrings},
- {RIL_REQUEST_OPERATOR, dispatchVoid, responseStrings},
- {RIL_REQUEST_RADIO_POWER, dispatchInts, responseVoid},
- {RIL_REQUEST_DTMF, dispatchString, responseVoid},
- {RIL_REQUEST_SEND_SMS, dispatchStrings, responseSMS},
- {RIL_REQUEST_SEND_SMS_EXPECT_MORE, dispatchStrings, responseSMS},
- {RIL_REQUEST_SETUP_DATA_CALL, dispatchDataCall, responseSetupDataCall},
- {RIL_REQUEST_SIM_IO, dispatchSIM_IO, responseSIM_IO},
- {RIL_REQUEST_SEND_USSD, dispatchString, responseVoid},
- {RIL_REQUEST_CANCEL_USSD, dispatchVoid, responseVoid},
- {RIL_REQUEST_GET_CLIR, dispatchVoid, responseInts},
- {RIL_REQUEST_SET_CLIR, dispatchInts, responseVoid},
- {RIL_REQUEST_QUERY_CALL_FORWARD_STATUS, dispatchCallForward, responseCallForwards},
- {RIL_REQUEST_SET_CALL_FORWARD, dispatchCallForward, responseVoid},
- {RIL_REQUEST_QUERY_CALL_WAITING, dispatchInts, responseInts},
- {RIL_REQUEST_SET_CALL_WAITING, dispatchInts, responseVoid},
- {RIL_REQUEST_SMS_ACKNOWLEDGE, dispatchInts, responseVoid},
- {RIL_REQUEST_GET_IMEI, dispatchVoid, responseString},
- {RIL_REQUEST_GET_IMEISV, dispatchVoid, responseString},
- {RIL_REQUEST_ANSWER,dispatchVoid, responseVoid},
- {RIL_REQUEST_DEACTIVATE_DATA_CALL, dispatchStrings, responseVoid},
- {RIL_REQUEST_QUERY_FACILITY_LOCK, dispatchStrings, responseInts},
- {RIL_REQUEST_SET_FACILITY_LOCK, dispatchStrings, responseInts},
- {RIL_REQUEST_CHANGE_BARRING_PASSWORD, dispatchStrings, responseVoid},
- {RIL_REQUEST_QUERY_NETWORK_SELECTION_MODE, dispatchVoid, responseInts},
- {RIL_REQUEST_SET_NETWORK_SELECTION_AUTOMATIC, dispatchVoid, responseVoid},
- {RIL_REQUEST_SET_NETWORK_SELECTION_MANUAL, dispatchString, responseVoid},
- {RIL_REQUEST_QUERY_AVAILABLE_NETWORKS , dispatchVoid, responseStrings},
- {RIL_REQUEST_DTMF_START, dispatchString, responseVoid},
- {RIL_REQUEST_DTMF_STOP, dispatchVoid, responseVoid},
- {RIL_REQUEST_BASEBAND_VERSION, dispatchVoid, responseString},
- {RIL_REQUEST_SEPARATE_CONNECTION, dispatchInts, responseVoid},
- {RIL_REQUEST_SET_MUTE, dispatchInts, responseVoid},
- {RIL_REQUEST_GET_MUTE, dispatchVoid, responseInts},
- {RIL_REQUEST_QUERY_CLIP, dispatchVoid, responseInts},
- {RIL_REQUEST_LAST_DATA_CALL_FAIL_CAUSE, dispatchVoid, responseInts},
- {RIL_REQUEST_DATA_CALL_LIST, dispatchVoid, responseDataCallList},
- {RIL_REQUEST_RESET_RADIO, dispatchVoid, responseVoid},
- {RIL_REQUEST_OEM_HOOK_RAW, dispatchRaw, responseRaw},
- {RIL_REQUEST_OEM_HOOK_STRINGS, dispatchStrings, responseStrings},
- {RIL_REQUEST_SCREEN_STATE, dispatchInts, responseVoid},
- {RIL_REQUEST_SET_SUPP_SVC_NOTIFICATION, dispatchInts, responseVoid},
- {RIL_REQUEST_WRITE_SMS_TO_SIM, dispatchSmsWrite, responseInts},
- {RIL_REQUEST_DELETE_SMS_ON_SIM, dispatchInts, responseVoid},
- {RIL_REQUEST_SET_BAND_MODE, dispatchInts, responseVoid},
- {RIL_REQUEST_QUERY_AVAILABLE_BAND_MODE, dispatchVoid, responseInts},
- {RIL_REQUEST_STK_GET_PROFILE, dispatchVoid, responseString},
- {RIL_REQUEST_STK_SET_PROFILE, dispatchString, responseVoid},
- {RIL_REQUEST_STK_SEND_ENVELOPE_COMMAND, dispatchString, responseString},
- {RIL_REQUEST_STK_SEND_TERMINAL_RESPONSE, dispatchString, responseVoid},
- {RIL_REQUEST_STK_HANDLE_CALL_SETUP_REQUESTED_FROM_SIM, dispatchInts, responseVoid},
- {RIL_REQUEST_EXPLICIT_CALL_TRANSFER, dispatchVoid, responseVoid},
- {RIL_REQUEST_SET_PREFERRED_NETWORK_TYPE, dispatchInts, responseVoid},
- {RIL_REQUEST_GET_PREFERRED_NETWORK_TYPE, dispatchVoid, responseInts},
- {RIL_REQUEST_GET_NEIGHBORING_CELL_IDS, dispatchVoid, responseCellList},
- {RIL_REQUEST_SET_LOCATION_UPDATES, dispatchInts, responseVoid},
- {RIL_REQUEST_CDMA_SET_SUBSCRIPTION_SOURCE, dispatchInts, responseVoid},
- {RIL_REQUEST_CDMA_SET_ROAMING_PREFERENCE, dispatchInts, responseVoid},
- {RIL_REQUEST_CDMA_QUERY_ROAMING_PREFERENCE, dispatchVoid, responseInts},
- {RIL_REQUEST_SET_TTY_MODE, dispatchInts, responseVoid},
- {RIL_REQUEST_QUERY_TTY_MODE, dispatchVoid, responseInts},
- {RIL_REQUEST_CDMA_SET_PREFERRED_VOICE_PRIVACY_MODE, dispatchInts, responseVoid},
- {RIL_REQUEST_CDMA_QUERY_PREFERRED_VOICE_PRIVACY_MODE, dispatchVoid, responseInts},
- {RIL_REQUEST_CDMA_FLASH, dispatchString, responseVoid},
- {RIL_REQUEST_CDMA_BURST_DTMF, dispatchStrings, responseVoid},
- {RIL_REQUEST_CDMA_VALIDATE_AND_WRITE_AKEY, dispatchString, responseVoid},
- {RIL_REQUEST_CDMA_SEND_SMS, dispatchCdmaSms, responseSMS},
- {RIL_REQUEST_CDMA_SMS_ACKNOWLEDGE, dispatchCdmaSmsAck, responseVoid},
- {RIL_REQUEST_GSM_GET_BROADCAST_SMS_CONFIG, dispatchVoid, responseGsmBrSmsCnf},
- {RIL_REQUEST_GSM_SET_BROADCAST_SMS_CONFIG, dispatchGsmBrSmsCnf, responseVoid},
- {RIL_REQUEST_GSM_SMS_BROADCAST_ACTIVATION, dispatchInts, responseVoid},
- {RIL_REQUEST_CDMA_GET_BROADCAST_SMS_CONFIG, dispatchVoid, responseCdmaBrSmsCnf},
- {RIL_REQUEST_CDMA_SET_BROADCAST_SMS_CONFIG, dispatchCdmaBrSmsCnf, responseVoid},
- {RIL_REQUEST_CDMA_SMS_BROADCAST_ACTIVATION, dispatchInts, responseVoid},
- {RIL_REQUEST_CDMA_SUBSCRIPTION, dispatchVoid, responseStrings},
- {RIL_REQUEST_CDMA_WRITE_SMS_TO_RUIM, dispatchRilCdmaSmsWriteArgs, responseInts},
- {RIL_REQUEST_CDMA_DELETE_SMS_ON_RUIM, dispatchInts, responseVoid},
- {RIL_REQUEST_DEVICE_IDENTITY, dispatchVoid, responseStrings},
- {RIL_REQUEST_EXIT_EMERGENCY_CALLBACK_MODE, dispatchVoid, responseVoid},
- {RIL_REQUEST_GET_SMSC_ADDRESS, dispatchVoid, responseString},
- {RIL_REQUEST_SET_SMSC_ADDRESS, dispatchString, responseVoid},
- {RIL_REQUEST_REPORT_SMS_MEMORY_STATUS, dispatchInts, responseVoid},
- {RIL_REQUEST_REPORT_STK_SERVICE_IS_RUNNING, dispatchVoid, responseVoid},
- {RIL_REQUEST_CDMA_GET_SUBSCRIPTION_SOURCE, dispatchCdmaSubscriptionSource, responseInts},
- {RIL_REQUEST_ISIM_AUTHENTICATION, dispatchString, responseString},
- {RIL_REQUEST_ACKNOWLEDGE_INCOMING_GSM_SMS_WITH_PDU, dispatchStrings, responseVoid},
- {RIL_REQUEST_STK_SEND_ENVELOPE_WITH_STATUS, dispatchString, responseSIM_IO},
- {RIL_REQUEST_VOICE_RADIO_TECH, dispatchVoiceRadioTech, responseInts},
2.unSolicited Response:Bp主动给Ap发送事件,该类型的AT指令及其回调函数以数组的形式存放在ril_unsol_commands.h文件中:
{数组中的索引号,响应回调函数,类型}
- {RIL_UNSOL_RESPONSE_RADIO_STATE_CHANGED, responseVoid, WAKE_PARTIAL},
- {RIL_UNSOL_RESPONSE_CALL_STATE_CHANGED, responseVoid, WAKE_PARTIAL},
- {RIL_UNSOL_RESPONSE_VOICE_NETWORK_STATE_CHANGED, responseVoid, WAKE_PARTIAL},
- {RIL_UNSOL_RESPONSE_NEW_SMS, responseString, WAKE_PARTIAL},
- {RIL_UNSOL_RESPONSE_NEW_SMS_STATUS_REPORT, responseString, WAKE_PARTIAL},
- {RIL_UNSOL_RESPONSE_NEW_SMS_ON_SIM, responseInts, WAKE_PARTIAL},
- {RIL_UNSOL_ON_USSD, responseStrings, WAKE_PARTIAL},
- {RIL_UNSOL_ON_USSD_REQUEST, responseVoid, DONT_WAKE},
- {RIL_UNSOL_NITZ_TIME_RECEIVED, responseString, WAKE_PARTIAL},
- {RIL_UNSOL_SIGNAL_STRENGTH, responseRilSignalStrength, DONT_WAKE},
- {RIL_UNSOL_DATA_CALL_LIST_CHANGED, responseDataCallList, WAKE_PARTIAL},
- {RIL_UNSOL_SUPP_SVC_NOTIFICATION, responseSsn, WAKE_PARTIAL},
- {RIL_UNSOL_STK_SESSION_END, responseVoid, WAKE_PARTIAL},
- {RIL_UNSOL_STK_PROACTIVE_COMMAND, responseString, WAKE_PARTIAL},
- {RIL_UNSOL_STK_EVENT_NOTIFY, responseString, WAKE_PARTIAL},
- {RIL_UNSOL_STK_CALL_SETUP, responseInts, WAKE_PARTIAL},
- {RIL_UNSOL_SIM_SMS_STORAGE_FULL, responseVoid, WAKE_PARTIAL},
- {RIL_UNSOL_SIM_REFRESH, responseSimRefresh, WAKE_PARTIAL},
- {RIL_UNSOL_CALL_RING, responseCallRing, WAKE_PARTIAL},
- {RIL_UNSOL_RESPONSE_SIM_STATUS_CHANGED, responseVoid, WAKE_PARTIAL},
- {RIL_UNSOL_RESPONSE_CDMA_NEW_SMS, responseCdmaSms, WAKE_PARTIAL},
- {RIL_UNSOL_RESPONSE_NEW_BROADCAST_SMS, responseRaw, WAKE_PARTIAL},
- {RIL_UNSOL_CDMA_RUIM_SMS_STORAGE_FULL, responseVoid, WAKE_PARTIAL},
- {RIL_UNSOL_RESTRICTED_STATE_CHANGED, responseInts, WAKE_PARTIAL},
- {RIL_UNSOL_ENTER_EMERGENCY_CALLBACK_MODE, responseVoid, WAKE_PARTIAL},
- {RIL_UNSOL_CDMA_CALL_WAITING, responseCdmaCallWaiting, WAKE_PARTIAL},
- {RIL_UNSOL_CDMA_OTA_PROVISION_STATUS, responseInts, WAKE_PARTIAL},
- {RIL_UNSOL_CDMA_INFO_REC, responseCdmaInformationRecords, WAKE_PARTIAL},
- {RIL_UNSOL_OEM_HOOK_RAW, responseRaw, WAKE_PARTIAL},
- {RIL_UNSOL_RINGBACK_TONE, responseInts, WAKE_PARTIAL},
- {RIL_UNSOL_RESEND_INCALL_MUTE, responseVoid, WAKE_PARTIAL},
- {RIL_UNSOL_CDMA_SUBSCRIPTION_SOURCE_CHANGED, responseInts, WAKE_PARTIAL},
- {RIL_UNSOL_CDMA_PRL_CHANGED, responseInts, WAKE_PARTIAL},
- {RIL_UNSOL_EXIT_EMERGENCY_CALLBACK_MODE, responseVoid, WAKE_PARTIAL},
- {RIL_UNSOL_RIL_CONNECTED, responseInts, WAKE_PARTIAL},
- {RIL_UNSOL_VOICE_RADIO_TECH_CHANGED, responseInts, WAKE_PARTIAL},
- {RIL_UNSOL_RESPONSE_RADIO_STATE_CHANGED, responseVoid, WAKE_PARTIAL},
- {RIL_UNSOL_RESPONSE_CALL_STATE_CHANGED, responseVoid, WAKE_PARTIAL},
- {RIL_UNSOL_RESPONSE_VOICE_NETWORK_STATE_CHANGED, responseVoid, WAKE_PARTIAL},
- {RIL_UNSOL_RESPONSE_NEW_SMS, responseString, WAKE_PARTIAL},
- {RIL_UNSOL_RESPONSE_NEW_SMS_STATUS_REPORT, responseString, WAKE_PARTIAL},
- {RIL_UNSOL_RESPONSE_NEW_SMS_ON_SIM, responseInts, WAKE_PARTIAL},
- {RIL_UNSOL_ON_USSD, responseStrings, WAKE_PARTIAL},
- {RIL_UNSOL_ON_USSD_REQUEST, responseVoid, DONT_WAKE},
- {RIL_UNSOL_NITZ_TIME_RECEIVED, responseString, WAKE_PARTIAL},
- {RIL_UNSOL_SIGNAL_STRENGTH, responseRilSignalStrength, DONT_WAKE},
- {RIL_UNSOL_DATA_CALL_LIST_CHANGED, responseDataCallList, WAKE_PARTIAL},
- {RIL_UNSOL_SUPP_SVC_NOTIFICATION, responseSsn, WAKE_PARTIAL},
- {RIL_UNSOL_STK_SESSION_END, responseVoid, WAKE_PARTIAL},
- {RIL_UNSOL_STK_PROACTIVE_COMMAND, responseString, WAKE_PARTIAL},
- {RIL_UNSOL_STK_EVENT_NOTIFY, responseString, WAKE_PARTIAL},
- {RIL_UNSOL_STK_CALL_SETUP, responseInts, WAKE_PARTIAL},
- {RIL_UNSOL_SIM_SMS_STORAGE_FULL, responseVoid, WAKE_PARTIAL},
- {RIL_UNSOL_SIM_REFRESH, responseSimRefresh, WAKE_PARTIAL},
- {RIL_UNSOL_CALL_RING, responseCallRing, WAKE_PARTIAL},
- {RIL_UNSOL_RESPONSE_SIM_STATUS_CHANGED, responseVoid, WAKE_PARTIAL},
- {RIL_UNSOL_RESPONSE_CDMA_NEW_SMS, responseCdmaSms, WAKE_PARTIAL},
- {RIL_UNSOL_RESPONSE_NEW_BROADCAST_SMS, responseRaw, WAKE_PARTIAL},
- {RIL_UNSOL_CDMA_RUIM_SMS_STORAGE_FULL, responseVoid, WAKE_PARTIAL},
- {RIL_UNSOL_RESTRICTED_STATE_CHANGED, responseInts, WAKE_PARTIAL},
- {RIL_UNSOL_ENTER_EMERGENCY_CALLBACK_MODE, responseVoid, WAKE_PARTIAL},
- {RIL_UNSOL_CDMA_CALL_WAITING, responseCdmaCallWaiting, WAKE_PARTIAL},
- {RIL_UNSOL_CDMA_OTA_PROVISION_STATUS, responseInts, WAKE_PARTIAL},
- {RIL_UNSOL_CDMA_INFO_REC, responseCdmaInformationRecords, WAKE_PARTIAL},
- {RIL_UNSOL_OEM_HOOK_RAW, responseRaw, WAKE_PARTIAL},
- {RIL_UNSOL_RINGBACK_TONE, responseInts, WAKE_PARTIAL},
- {RIL_UNSOL_RESEND_INCALL_MUTE, responseVoid, WAKE_PARTIAL},
- {RIL_UNSOL_CDMA_SUBSCRIPTION_SOURCE_CHANGED, responseInts, WAKE_PARTIAL},
- {RIL_UNSOL_CDMA_PRL_CHANGED, responseInts, WAKE_PARTIAL},
- {RIL_UNSOL_EXIT_EMERGENCY_CALLBACK_MODE, responseVoid, WAKE_PARTIAL},
- {RIL_UNSOL_RIL_CONNECTED, responseInts, WAKE_PARTIAL},
- {RIL_UNSOL_VOICE_RADIO_TECH_CHANGED, responseInts, WAKE_PARTIAL},
不同手机厂商使用的AT命令不完全相同,为了保密,AP与BP之间通过各厂商自己的相关动态库来通信。
RIL模块由rild守护进程、libril.so、librefrence.so三部分组成:
1.rild模块被编译为一个可执行文件,实现一个main函数作为整个ril模块的入口点。在初始化时使用dlopen打开librefrence_ril.so,从中取出并执行RIL_Init函数,得到RIL_RadioFunctions指针,通过RIL_register()函数注册到libril.so库中,其源码结构如下:
2.libril.so是共享库,主要负责同上层的通信工作,接收ril的请求,并传递给librefrence_ril.so,同时将librefrence_ril.so返回的消息送给调用进程,源码结构如下所示:
3.librefrence_ril.so是由各手机厂商自己实现,在rild进程运行中通过dlopen方式加载,主要负责跟modem硬件通信,转换来自libril.so的请求为AT命令,同时监听Modem的反馈信息给libril.so
Android的电话系统主要分为三个部分,java层的各种电话相关应用,java层的Phone Service,主要为上层提供API,同时与native进行通信,可以看做为电话系统的客户端,native层的电话服务进程RILD,负责为上层提供各种电话功能服务,直接与modem进行交互:
Android电话系统设计框架图:
由于Android 开发者使用的Modem 是不一样的,各种指令格式,初始化序列都可能不一样,所以为了消除这些差别,Android 设计者将ril 做了一个抽象,使用一个虚拟电话的概念,不同modem相关的AT指令或者通信协议编译成相应的动态链接库.so文件,Rild 是具体的AT 指令合成者和应答解析者。
Android电话系统代码结构图:
RILD框架设计
在android的电话系统中,在native层实现了电话服务的服务端,由RILD服务与modem的交互,在java层实现电话的客户端,本文主要介绍电话系统的服务端RILD进程,以下是RILD的设计框架图:
RILD源码分析
接下来通过源码对RILD的整个框架进行详细介绍。
在kernel启动完成后,将启动第一个应用进程Init进程,在android之Init进程启动过程源码分析一文中对init进程的启动流程进行了详细的介绍。init进程在启动过程中将读取init.rc文件来启动一些重量级的native服务,rild进程就是通过配置在init.rc中来启动的。
- service ril-daemon /system/bin/rild
- class main
- socket rild stream 660 root radio
- socket rild-debug stream 660 radio system
- user root
- group radio cache inet misc audio sdcard_rw log
- service ril-daemon /system/bin/rild
- class main
- socket rild stream 660 root radio
- socket rild-debug stream 660 radio system
- user root
- group radio cache inet misc audio sdcard_rw log
RILD进程入口函数分析
接下来给出的是RILD进程启动的时序图:
hardware\ril\rild\rild.c
- int main(int argc, char **argv)
- {
- const char * rilLibPath = NULL;
- char **rilArgv;
- void *dlHandle;
- const RIL_RadioFunctions *(*rilInit)(const struct RIL_Env *, int, char **);
- const RIL_RadioFunctions *funcs;
- char libPath[PROPERTY_VALUE_MAX];
- unsigned char hasLibArgs = 0;
- int i;
- 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 {
- usage(argv[0]);
- }
- }
- if (rilLibPath == NULL) {
-
- if ( 0 == property_get(LIB_PATH_PROPERTY, libPath, NULL)) {
- goto done;
- } else {
- rilLibPath = libPath;
- }
- }
- ##################################################################################
- 判断是否为模拟器
- ##################################################################################
- #if 1
- {
- static char* arg_overrides[3];
- static char arg_device[32];
- int done = 0;
- #define REFERENCE_RIL_PATH "/system/lib/libreference-ril.so"
-
- char buffer[1024], *p, *q;
- int len;
- int fd = open("/proc/cmdline",O_RDONLY);
- if (fd < 0) {
- LOGD("could not open /proc/cmdline:%s", strerror(errno));
- goto OpenLib;
- }
-
- do {
- len = read(fd,buffer,sizeof(buffer)); }
- while (len == -1 && errno == EINTR);
- if (len < 0) {
- LOGD("could not read /proc/cmdline:%s", strerror(errno));
- close(fd);
- goto OpenLib;
- }
- close(fd);
-
- if (strstr(buffer, "android.qemud=") != NULL)
- {
- int tries = 5;
- #define QEMUD_SOCKET_NAME "qemud"
- while (1) {
- int fd;
- sleep(1);
- fd = socket_local_client(QEMUD_SOCKET_NAME,
- ANDROID_SOCKET_NAMESPACE_RESERVED,
- SOCK_STREAM );
- if (fd >= 0) {
- close(fd);
- snprintf( arg_device, sizeof(arg_device), "%s/%s",
- ANDROID_SOCKET_DIR, QEMUD_SOCKET_NAME );
- arg_overrides[1] = "-s";
- arg_overrides[2] = arg_device;
- done = 1;
- break;
- }
- LOGD("could not connect to %s socket: %s",QEMUD_SOCKET_NAME, strerror(errno));
- if (--tries == 0)
- break;
- }
- if (!done) {
- LOGE("could not connect to %s socket (giving up): %s",
- QEMUD_SOCKET_NAME, strerror(errno));
- while(1)
- sleep(0x00ffffff);
- }
- }
-
-
- if (!done) do {
- #define KERNEL_OPTION "android.ril="
- #define DEV_PREFIX "/dev/"
-
- p = strstr( buffer, KERNEL_OPTION );
- if (p == NULL)
- break;
- p += sizeof(KERNEL_OPTION)-1;
- q = strpbrk( p, " \t\n\r" );
- if (q != NULL)
- *q = 0;
- snprintf( arg_device, sizeof(arg_device), DEV_PREFIX "%s", p );
- arg_device[sizeof(arg_device)-1] = 0;
- arg_overrides[1] = "-d";
- arg_overrides[2] = arg_device;
- done = 1;
- } while (0);
-
- if (done) {
- argv = arg_overrides;
- argc = 3;
- i = 1;
- hasLibArgs = 1;
- rilLibPath = REFERENCE_RIL_PATH;
- LOGD("overriding with %s %s", arg_overrides[1], arg_overrides[2]);
- }
- }
- OpenLib:
- #endif
- ##################################################################################
- 动态库装载
- ##################################################################################
-
- switchUser();
-
- ①dlHandle = dlopen(rilLibPath, RTLD_NOW);
- if (dlHandle == NULL) {
- fprintf(stderr, "dlopen failed: %s\n", dlerror());
- exit(-1);
- }
-
- ②RIL_startEventLoop();
-
- ③rilInit = (const RIL_RadioFunctions *(*)(const struct RIL_Env *, int, char **))dlsym(dlHandle, "RIL_Init");
- if (rilInit == NULL) {
- fprintf(stderr, "RIL_Init not defined or exported in %s\n", rilLibPath);
- exit(-1);
- }
- if (hasLibArgs) {
- rilArgv = argv + i - 1;
- argc = argc -i + 1;
- } else {
- static char * newArgv[MAX_LIB_ARGS];
- static char args[PROPERTY_VALUE_MAX];
- rilArgv = newArgv;
- property_get(LIB_ARGS_PROPERTY, args, "");
- argc = make_argv(args, rilArgv);
- }
-
- rilArgv[0] = argv[0];
-
- ④funcs = rilInit(&s_rilEnv, argc, rilArgv);
-
- ⑤RIL_register(funcs);
- done:
- while(1) {
-
- sleep(0x00ffffff);
- }
- }
- int main(int argc, char **argv)
- {
- const char * rilLibPath = NULL;
- char **rilArgv;
- void *dlHandle;
- const RIL_RadioFunctions *(*rilInit)(const struct RIL_Env *, int, char **);
- const RIL_RadioFunctions *funcs;
- char libPath[PROPERTY_VALUE_MAX];
- unsigned char hasLibArgs = 0;
- int i;
- 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 {
- usage(argv[0]);
- }
- }
- if (rilLibPath == NULL) {
-
- if ( 0 == property_get(LIB_PATH_PROPERTY, libPath, NULL)) {
- goto done;
- } else {
- rilLibPath = libPath;
- }
- }
- ##################################################################################
- 判断是否为模拟器
- ##################################################################################
- #if 1
- {
- static char* arg_overrides[3];
- static char arg_device[32];
- int done = 0;
- #define REFERENCE_RIL_PATH "/system/lib/libreference-ril.so"
-
- char buffer[1024], *p, *q;
- int len;
- int fd = open("/proc/cmdline",O_RDONLY);
- if (fd < 0) {
- LOGD("could not open /proc/cmdline:%s", strerror(errno));
- goto OpenLib;
- }
-
- do {
- len = read(fd,buffer,sizeof(buffer)); }
- while (len == -1 && errno == EINTR);
- if (len < 0) {
- LOGD("could not read /proc/cmdline:%s", strerror(errno));
- close(fd);
- goto OpenLib;
- }
- close(fd);
-
- if (strstr(buffer, "android.qemud=") != NULL)
- {
- int tries = 5;
- #define QEMUD_SOCKET_NAME "qemud"
- while (1) {
- int fd;
- sleep(1);
- fd = socket_local_client(QEMUD_SOCKET_NAME,
- ANDROID_SOCKET_NAMESPACE_RESERVED,
- SOCK_STREAM );
- if (fd >= 0) {
- close(fd);
- snprintf( arg_device, sizeof(arg_device), "%s/%s",
- ANDROID_SOCKET_DIR, QEMUD_SOCKET_NAME );
- arg_overrides[1] = "-s";
- arg_overrides[2] = arg_device;
- done = 1;
- break;
- }
- LOGD("could not connect to %s socket: %s",QEMUD_SOCKET_NAME, strerror(errno));
- if (--tries == 0)
- break;
- }
- if (!done) {
- LOGE("could not connect to %s socket (giving up): %s",
- QEMUD_SOCKET_NAME, strerror(errno));
- while(1)
- sleep(0x00ffffff);
- }
- }
-
-
- if (!done) do {
- #define KERNEL_OPTION "android.ril="
- #define DEV_PREFIX "/dev/"
-
- p = strstr( buffer, KERNEL_OPTION );
- if (p == NULL)
- break;
- p += sizeof(KERNEL_OPTION)-1;
- q = strpbrk( p, " \t\n\r" );
- if (q != NULL)
- *q = 0;
- snprintf( arg_device, sizeof(arg_device), DEV_PREFIX "%s", p );
- arg_device[sizeof(arg_device)-1] = 0;
- arg_overrides[1] = "-d";
- arg_overrides[2] = arg_device;
- done = 1;
- } while (0);
-
- if (done) {
- argv = arg_overrides;
- argc = 3;
- i = 1;
- hasLibArgs = 1;
- rilLibPath = REFERENCE_RIL_PATH;
- LOGD("overriding with %s %s", arg_overrides[1], arg_overrides[2]);
- }
- }
- OpenLib:
- #endif
- ##################################################################################
- 动态库装载
- ##################################################################################
-
- switchUser();
-
- ①dlHandle = dlopen(rilLibPath, RTLD_NOW);
- if (dlHandle == NULL) {
- fprintf(stderr, "dlopen failed: %s\n", dlerror());
- exit(-1);
- }
-
- ②RIL_startEventLoop();
-
- ③rilInit = (const RIL_RadioFunctions *(*)(const struct RIL_Env *, int, char **))dlsym(dlHandle, "RIL_Init");
- if (rilInit == NULL) {
- fprintf(stderr, "RIL_Init not defined or exported in %s\n", rilLibPath);
- exit(-1);
- }
- if (hasLibArgs) {
- rilArgv = argv + i - 1;
- argc = argc -i + 1;
- } else {
- static char * newArgv[MAX_LIB_ARGS];
- static char args[PROPERTY_VALUE_MAX];
- rilArgv = newArgv;
- property_get(LIB_ARGS_PROPERTY, args, "");
- argc = make_argv(args, rilArgv);
- }
-
- rilArgv[0] = argv[0];
-
- ④funcs = rilInit(&s_rilEnv, argc, rilArgv);
-
- ⑤RIL_register(funcs);
- done:
- while(1) {
-
- sleep(0x00ffffff);
- }
- }
在main函数中主要完成以下工作:
1.解析命令行参数,通过判断是否为模拟器采取不同的方式来读取libreference-ril.so库的存放路径;
2.使用dlopen手动装载libreference-ril.so库;
3.启动事件循环处理;
4.从libreference-ril.so库中取得RIL_Init函数地址,并使用该函数将libril.so库中的RIL_Env接口注册到libreference-ril.so库,同时将libreference-ril.so库中的RIL_RadioFunctions接口注册到到libril.so库中,建立起libril.so库与libreference-ril.so库通信桥梁;
启动事件循环处理eventLoop工作线程
建立多路I/O驱动机制的消息队列,用来接收上层发出的命令以及往Modem发送AT指令的工作,时整个RIL系统的核心部分。创建一个事件分发线程s_tid_dispatch,线程执行体为eventLoop。
hardware\ril\libril\Ril.cpp
- extern "C" void RIL_startEventLoop(void) {
- int ret;
- pthread_attr_t attr;
-
- s_started = 0;
- pthread_mutex_lock(&s_startupMutex);
- pthread_attr_init (&attr);
- pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
-
- ret = pthread_create(&s_tid_dispatch, &attr, eventLoop, NULL);
-
- while (s_started == 0) {
- pthread_cond_wait(&s_startupCond, &s_startupMutex);
- }
- pthread_mutex_unlock(&s_startupMutex);
- if (ret < 0) {
- LOGE("Failed to create dispatch thread errno:%d", errno);
- return;
- }
- }
- extern "C" void RIL_startEventLoop(void) {
- int ret;
- pthread_attr_t attr;
-
- s_started = 0;
- pthread_mutex_lock(&s_startupMutex);
- pthread_attr_init (&attr);
- pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
-
- ret = pthread_create(&s_tid_dispatch, &attr, eventLoop, NULL);
-
- while (s_started == 0) {
- pthread_cond_wait(&s_startupCond, &s_startupMutex);
- }
- pthread_mutex_unlock(&s_startupMutex);
- if (ret < 0) {
- LOGE("Failed to create dispatch thread errno:%d", errno);
- return;
- }
- }
eventLoop执行时序图:
- static void * eventLoop(void *param) {
- int ret;
- int filedes[2];
- ril_event_init();
- pthread_mutex_lock(&s_startupMutex);
- s_started = 1;
- pthread_cond_broadcast(&s_startupCond);
- pthread_mutex_unlock(&s_startupMutex);
-
- ret = pipe(filedes);
- if (ret < 0) {
- LOGE("Error in pipe() errno:%d", errno);
- return NULL;
- }
-
- s_fdWakeupRead = filedes[0];
-
- s_fdWakeupWrite = filedes[1];
-
- fcntl(s_fdWakeupRead, F_SETFL, O_NONBLOCK);
-
- ril_event_set (&s_wakeupfd_event, s_fdWakeupRead, true,processWakeupCallback, NULL);
- ①rilEventAddWakeup (&s_wakeupfd_event);
-
- ②ril_event_loop();
- LOGE ("error in event_loop_base errno:%d", errno);
- return NULL;
- }
- static void * eventLoop(void *param) {
- int ret;
- int filedes[2];
- ril_event_init();
- pthread_mutex_lock(&s_startupMutex);
- s_started = 1;
- pthread_cond_broadcast(&s_startupCond);
- pthread_mutex_unlock(&s_startupMutex);
-
- ret = pipe(filedes);
- if (ret < 0) {
- LOGE("Error in pipe() errno:%d", errno);
- return NULL;
- }
-
- s_fdWakeupRead = filedes[0];
-
- s_fdWakeupWrite = filedes[1];
-
- fcntl(s_fdWakeupRead, F_SETFL, O_NONBLOCK);
-
- ril_event_set (&s_wakeupfd_event, s_fdWakeupRead, true,processWakeupCallback, NULL);
- ①rilEventAddWakeup (&s_wakeupfd_event);
-
- ②ril_event_loop();
- LOGE ("error in event_loop_base errno:%d", errno);
- return NULL;
- }
在rild中定义了event的概念,Rild
支持两种类型的事件:
1. 定时事件:根据事件的执行时间来启动执行,通过ril_timer_add添加到time_list队列中
2. Wakeup事件:这些事件的句柄fd将加入的select IO多路复用的句柄池readFDs中,当对应的fd可读时将触发这些事件。对于处于listen端的socket,fd可读表示有个客户端连接,此时需要调用accept接受连接。
事件定义如下:
- struct ril_event {
- struct ril_event *next;
- struct ril_event *prev;
- int fd;
- int index;
- bool persist;
- struct timeval timeout;
- ril_event_cb func;
- void *param;
- };
- struct ril_event {
- struct ril_event *next;
- struct ril_event *prev;
- int fd;
- int index;
- bool persist;
- struct timeval timeout;
- ril_event_cb func;
- void *param;
- };
在Rild进程中的几个重要事件有
- static struct ril_event s_commands_event;
- ril_event_set (&s_commands_event, s_fdCommand, 1,processCommandsCallback, p_rs)
-
- static struct ril_event s_wakeupfd_event;
- ril_event_set (&s_wakeupfd_event, s_fdWakeupRead, true,processWakeupCallback, NULL)
-
- static struct ril_event s_listen_event;
- ril_event_set (&s_listen_event, s_fdListen, false,listenCallback, NULL)
-
- static struct ril_event s_wake_timeout_event;
- ril_timer_add(&(p_info->event), &myRelativeTime);
- static struct ril_event s_commands_event;
- ril_event_set (&s_commands_event, s_fdCommand, 1,processCommandsCallback, p_rs)
-
- static struct ril_event s_wakeupfd_event;
- ril_event_set (&s_wakeupfd_event, s_fdWakeupRead, true,processWakeupCallback, NULL)
-
- static struct ril_event s_listen_event;
- ril_event_set (&s_listen_event, s_fdListen, false,listenCallback, NULL)
-
- static struct ril_event s_wake_timeout_event;
- ril_timer_add(&(p_info->event), &myRelativeTime);
- static struct ril_event s_debug_event;
- ril_event_set (&s_debug_event, s_fdDebug, true,debugCallback, NULL)
- static struct ril_event s_debug_event;
- ril_event_set (&s_debug_event, s_fdDebug, true,debugCallback, NULL)
在RILD中定义了三个事件队列,用于处理不同的事件:
/事件监控队列
static struct ril_event * watch_table[MAX_FD_EVENTS];
//定时事件队列
static struct ril_event timer_list;
//处理事件队列
static struct ril_event pending_list; //待处理事件队列,事件已经触发,需要所回调处理的事件
添加事件
1.添加
Wakeup 事件
- static void rilEventAddWakeup(struct ril_event *ev) {
- ril_event_add(ev);
- triggerEvLoop();
- }
- static void rilEventAddWakeup(struct ril_event *ev) {
- ril_event_add(ev);
- triggerEvLoop();
- }
- void ril_event_add(struct ril_event * ev)
- {
- dlog("~~~~ +ril_event_add ~~~~");
- MUTEX_ACQUIRE();
- for (int i = 0; i < MAX_FD_EVENTS; i++) {
- if (watch_table[i] == NULL) {
- watch_table[i] = ev;
- ev->index = i;
- dlog("~~~~ added at %d ~~~~", i);
- dump_event(ev);
- FD_SET(ev->fd, &readFds);
- if (ev->fd >= nfds) nfds = ev->fd+1;
- dlog("~~~~ nfds = %d ~~~~", nfds);
- break;
- }
- }
- MUTEX_RELEASE();
- dlog("~~~~ -ril_event_add ~~~~");
- }
- void ril_event_add(struct ril_event * ev)
- {
- dlog("~~~~ +ril_event_add ~~~~");
- MUTEX_ACQUIRE();
- for (int i = 0; i < MAX_FD_EVENTS; i++) {
- if (watch_table[i] == NULL) {
- watch_table[i] = ev;
- ev->index = i;
- dlog("~~~~ added at %d ~~~~", i);
- dump_event(ev);
- FD_SET(ev->fd, &readFds);
- if (ev->fd >= nfds) nfds = ev->fd+1;
- dlog("~~~~ nfds = %d ~~~~", nfds);
- break;
- }
- }
- MUTEX_RELEASE();
- dlog("~~~~ -ril_event_add ~~~~");
- }
2.添加定时事件
- void ril_timer_add(struct ril_event * ev, struct timeval * tv)
- {
- dlog("~~~~ +ril_timer_add ~~~~");
- MUTEX_ACQUIRE();
- struct ril_event * list;
- if (tv != NULL) {
- list = timer_list.next;
- ev->fd = -1;
- struct timeval now;
- getNow(&now);
- timeradd(&now, tv, &ev->timeout);
-
- while (timercmp(&list->timeout, &ev->timeout, < ) && (list != &timer_list)) {
- list = list->next;
- }
-
- addToList(ev, list);
- }
- MUTEX_RELEASE();
- dlog("~~~~ -ril_timer_add ~~~~");
- }
- void ril_timer_add(struct ril_event * ev, struct timeval * tv)
- {
- dlog("~~~~ +ril_timer_add ~~~~");
- MUTEX_ACQUIRE();
- struct ril_event * list;
- if (tv != NULL) {
- list = timer_list.next;
- ev->fd = -1;
- struct timeval now;
- getNow(&now);
- timeradd(&now, tv, &ev->timeout);
-
- while (timercmp(&list->timeout, &ev->timeout, < ) && (list != &timer_list)) {
- list = list->next;
- }
-
- addToList(ev, list);
- }
- MUTEX_RELEASE();
- dlog("~~~~ -ril_timer_add ~~~~");
- }
触发事件
- static void triggerEvLoop() {
- int ret;
- if (!pthread_equal(pthread_self(), s_tid_dispatch)) {
- do {
- ret = write (s_fdWakeupWrite, " ", 1);
- } while (ret < 0 && errno == EINTR);
- }
- }
- static void triggerEvLoop() {
- int ret;
- if (!pthread_equal(pthread_self(), s_tid_dispatch)) {
- do {
- ret = write (s_fdWakeupWrite, " ", 1);
- } while (ret < 0 && errno == EINTR);
- }
- }
处理事件
- void ril_event_loop()
- {
- int n;
- fd_set rfds;
- struct timeval tv;
- struct timeval * ptv;
- for (;;) {
- memcpy(&rfds, &readFds, sizeof(fd_set));
- if (-1 == calcNextTimeout(&tv)) {
- dlog("~~~~ no timers; blocking indefinitely ~~~~");
- ptv = NULL;
- } else {
- dlog("~~~~ blocking for %ds + %dus ~~~~", (int)tv.tv_sec, (int)tv.tv_usec);
- ptv = &tv;
- }
-
- printReadies(&rfds);
- n = select(nfds, &rfds, NULL, NULL, ptv);
- printReadies(&rfds);
- dlog("~~~~ %d events fired ~~~~", n);
- if (n < 0) {
- if (errno == EINTR) continue;
- LOGE("ril_event: select error (%d)", errno);
- return;
- }
- processTimeouts();
- processReadReadies(&rfds, n);
-
- firePending();
- }
- }
- void ril_event_loop()
- {
- int n;
- fd_set rfds;
- struct timeval tv;
- struct timeval * ptv;
- for (;;) {
- memcpy(&rfds, &readFds, sizeof(fd_set));
- if (-1 == calcNextTimeout(&tv)) {
- dlog("~~~~ no timers; blocking indefinitely ~~~~");
- ptv = NULL;
- } else {
- dlog("~~~~ blocking for %ds + %dus ~~~~", (int)tv.tv_sec, (int)tv.tv_usec);
- ptv = &tv;
- }
-
- printReadies(&rfds);
- n = select(nfds, &rfds, NULL, NULL, ptv);
- printReadies(&rfds);
- dlog("~~~~ %d events fired ~~~~", n);
- if (n < 0) {
- if (errno == EINTR) continue;
- LOGE("ril_event: select error (%d)", errno);
- return;
- }
- processTimeouts();
- processReadReadies(&rfds, n);
-
- firePending();
- }
- }
在eventLoop工作线程中,循环处理到来的事件及定时结束事件,整个处理流程如下图所示:
首先通过Linux中的select多路I/O复用对句柄池中的所有句柄进行监控,当有事件到来时select返回,否则阻塞。当select返回时,表示有事件的到来,通过调用processTimeouts函数来处理超时事件,处理方式是遍历time_list链表以查询超时事件,并将超时事件移入到pending_list链表中,接着调用processReadReadies函数来处理触发的事件,处理方式为遍历watch_table列表以查询触发的事件,并将触发的事件移入到pending_list链表中,如果该事件不是持久事件,还需要从watch_table列表中移除,当查询完两种待处理的事件并放入到pending_list链表中后,调用firePending函数对待处理的事件进行集中处理,处理方式为遍历链表,调用每一个事件的回调函数。
1.超时事件查询
- static void processTimeouts()
- {
- dlog("~~~~ +processTimeouts ~~~~");
- MUTEX_ACQUIRE();
- struct timeval now;
- struct ril_event * tev = timer_list.next;
- struct ril_event * next;
- getNow(&now);
- dlog("~~~~ Looking for timers <= %ds + %dus ~~~~", (int)now.tv_sec, (int)now.tv_usec);
-
- while ((tev != &timer_list) && (timercmp(&now, &tev->timeout, >))) {
- dlog("~~~~ firing timer ~~~~");
- next = tev->next;
- removeFromList(tev);
- addToList(tev, &pending_list);
- tev = next;
- }
- MUTEX_RELEASE();
- dlog("~~~~ -processTimeouts ~~~~");
- }
- static void processTimeouts()
- {
- dlog("~~~~ +processTimeouts ~~~~");
- MUTEX_ACQUIRE();
- struct timeval now;
- struct ril_event * tev = timer_list.next;
- struct ril_event * next;
- getNow(&now);
- dlog("~~~~ Looking for timers <= %ds + %dus ~~~~", (int)now.tv_sec, (int)now.tv_usec);
-
- while ((tev != &timer_list) && (timercmp(&now, &tev->timeout, >))) {
- dlog("~~~~ firing timer ~~~~");
- next = tev->next;
- removeFromList(tev);
- addToList(tev, &pending_list);
- tev = next;
- }
- MUTEX_RELEASE();
- dlog("~~~~ -processTimeouts ~~~~");
- }
2.可读事件查询
- static void processReadReadies(fd_set * rfds, int n)
- {
- dlog("~~~~ +processReadReadies (%d) ~~~~", n);
- MUTEX_ACQUIRE();
-
- for (int i = 0; (i < MAX_FD_EVENTS) && (n > 0); i++) {
- struct ril_event * rev = watch_table[i];
- if (rev != NULL && FD_ISSET(rev->fd, rfds)) {
- addToList(rev, &pending_list);
- if (rev->persist == false) {
- removeWatch(rev, i);
- }
- n--;
- }
- }
- MUTEX_RELEASE();
- dlog("~~~~ -processReadReadies (%d) ~~~~", n);
- }
- static void processReadReadies(fd_set * rfds, int n)
- {
- dlog("~~~~ +processReadReadies (%d) ~~~~", n);
- MUTEX_ACQUIRE();
-
- for (int i = 0; (i < MAX_FD_EVENTS) && (n > 0); i++) {
- struct ril_event * rev = watch_table[i];
- if (rev != NULL && FD_ISSET(rev->fd, rfds)) {
- addToList(rev, &pending_list);
- if (rev->persist == false) {
- removeWatch(rev, i);
- }
- n--;
- }
- }
- MUTEX_RELEASE();
- dlog("~~~~ -processReadReadies (%d) ~~~~", n);
- }
3.事件处理
- static void firePending()
- {
- dlog("~~~~ +firePending ~~~~");
- struct ril_event * ev = pending_list.next;
- while (ev != &pending_list) {
- struct ril_event * next = ev->next;
- removeFromList(ev);
- ev->func(ev->fd, 0, ev->param);
- ev = next;
- }
- dlog("~~~~ -firePending ~~~~");
- }
- static void firePending()
- {
- dlog("~~~~ +firePending ~~~~");
- struct ril_event * ev = pending_list.next;
- while (ev != &pending_list) {
- struct ril_event * next = ev->next;
- removeFromList(ev);
- ev->func(ev->fd, 0, ev->param);
- ev = next;
- }
- dlog("~~~~ -firePending ~~~~");
- }
RIL_Env定义
hardware\ril\include\telephony\ril.h
- struct RIL_Env {
-
- void (*OnRequestComplete)(RIL_Token t, RIL_Errno e,void *response, size_t responselen);
-
- void (*OnUnsolicitedResponse)(int unsolResponse, const void *data,size_t datalen);
-
- void (*RequestTimedCallback) (RIL_TimedCallback callback,void *param, const struct timeval *relativeTime);
- };
- struct RIL_Env {
-
- void (*OnRequestComplete)(RIL_Token t, RIL_Errno e,void *response, size_t responselen);
-
- void (*OnUnsolicitedResponse)(int unsolResponse, const void *data,size_t datalen);
-
- void (*RequestTimedCallback) (RIL_TimedCallback callback,void *param, const struct timeval *relativeTime);
- };
hardware\ril\rild\rild.c
s_rilEnv变量定义:
- static struct RIL_Env s_rilEnv = {
- RIL_onRequestComplete,
- RIL_onUnsolicitedResponse,
- RIL_requestTimedCallback
- };
- static struct RIL_Env s_rilEnv = {
- RIL_onRequestComplete,
- RIL_onUnsolicitedResponse,
- RIL_requestTimedCallback
- };
在hardware\ril\libril\ril.cpp中实现了RIL_Env的各个接口函数
1.RIL_onRequestComplete
- extern "C" void RIL_onRequestComplete(RIL_Token t, RIL_Errno e, void *response, size_t responselen) {
- RequestInfo *pRI;
- int ret;
- size_t errorOffset;
- pRI = (RequestInfo *)t;
- if (!checkAndDequeueRequestInfo(pRI)) {
- LOGE ("RIL_onRequestComplete: invalid RIL_Token");
- return;
- }
- if (pRI->local > 0) {
-
-
- LOGD("C[locl]< %s", requestToString(pRI->pCI->requestNumber));
- goto done;
- }
- appendPrintBuf("[%04d]< %s",pRI->token, requestToString(pRI->pCI->requestNumber));
- if (pRI->cancelled == 0) {
- Parcel p;
- p.writeInt32 (RESPONSE_SOLICITED);
- p.writeInt32 (pRI->token);
- errorOffset = p.dataPosition();
- p.writeInt32 (e);
- if (response != NULL) {
-
- ret = pRI->pCI->responseFunction(p, response, responselen);
-
- if (ret != 0) {
- p.setDataPosition(errorOffset);
- p.writeInt32 (ret);
- }
- }
- if (e != RIL_E_SUCCESS) {
- appendPrintBuf("%s fails by %s", printBuf, failCauseToString(e));
- }
- if (s_fdCommand < 0) {
- LOGD ("RIL onRequestComplete: Command channel closed");
- }
- sendResponse(p);
- }
- done:
- free(pRI);
- }
- extern "C" void RIL_onRequestComplete(RIL_Token t, RIL_Errno e, void *response, size_t responselen) {
- RequestInfo *pRI;
- int ret;
- size_t errorOffset;
- pRI = (RequestInfo *)t;
- if (!checkAndDequeueRequestInfo(pRI)) {
- LOGE ("RIL_onRequestComplete: invalid RIL_Token");
- return;
- }
- if (pRI->local > 0) {
-
-
- LOGD("C[locl]< %s", requestToString(pRI->pCI->requestNumber));
- goto done;
- }
- appendPrintBuf("[%04d]< %s",pRI->token, requestToString(pRI->pCI->requestNumber));
- if (pRI->cancelled == 0) {
- Parcel p;
- p.writeInt32 (RESPONSE_SOLICITED);
- p.writeInt32 (pRI->token);
- errorOffset = p.dataPosition();
- p.writeInt32 (e);
- if (response != NULL) {
-
- ret = pRI->pCI->responseFunction(p, response, responselen);
-
- if (ret != 0) {
- p.setDataPosition(errorOffset);
- p.writeInt32 (ret);
- }
- }
- if (e != RIL_E_SUCCESS) {
- appendPrintBuf("%s fails by %s", printBuf, failCauseToString(e));
- }
- if (s_fdCommand < 0) {
- LOGD ("RIL onRequestComplete: Command channel closed");
- }
- sendResponse(p);
- }
- done:
- free(pRI);
- }
通过调用responseXXX将底层响应传给客户进程
2.RIL_onUnsolicitedResponse
- extern "C" void RIL_onUnsolicitedResponse(int unsolResponse, void *data,
- size_t datalen)
- {
- int unsolResponseIndex;
- int ret;
- int64_t timeReceived = 0;
- bool shouldScheduleTimeout = false;
- if (s_registerCalled == 0) {
-
- LOGW("RIL_onUnsolicitedResponse called before RIL_register");
- return;
- }
- unsolResponseIndex = unsolResponse - RIL_UNSOL_RESPONSE_BASE;
- if ((unsolResponseIndex < 0)
- || (unsolResponseIndex >= (int32_t)NUM_ELEMS(s_unsolResponses))) {
- LOGE("unsupported unsolicited response code %d", unsolResponse);
- return;
- }
-
-
-
- switch (s_unsolResponses[unsolResponseIndex].wakeType) {
- case WAKE_PARTIAL:
- grabPartialWakeLock();
- shouldScheduleTimeout = true;
- break;
- case DONT_WAKE:
- default:
-
- shouldScheduleTimeout = false;
- break;
- }
-
-
-
-
- if (unsolResponse == RIL_UNSOL_NITZ_TIME_RECEIVED) {
- timeReceived = elapsedRealtime();
- }
- appendPrintBuf("[UNSL]< %s", requestToString(unsolResponse));
- Parcel p;
- p.writeInt32 (RESPONSE_UNSOLICITED);
- p.writeInt32 (unsolResponse);
- ret = s_unsolResponses[unsolResponseIndex].responseFunction(p, data, datalen);
- if (ret != 0) {
-
- goto error_exit;
- }
-
- switch(unsolResponse) {
- case RIL_UNSOL_RESPONSE_RADIO_STATE_CHANGED:
- p.writeInt32(s_callbacks.onStateRequest());
- appendPrintBuf("%s {%s}", printBuf,
- radioStateToString(s_callbacks.onStateRequest()));
- break;
- case RIL_UNSOL_NITZ_TIME_RECEIVED:
-
-
-
-
-
- p.writeInt64(timeReceived);
- break;
- }
- ret = sendResponse(p);
- if (ret != 0 && unsolResponse == RIL_UNSOL_NITZ_TIME_RECEIVED) {
-
-
-
-
- if (s_lastNITZTimeData != NULL) {
- free (s_lastNITZTimeData);
- s_lastNITZTimeData = NULL;
- }
- s_lastNITZTimeData = malloc(p.dataSize());
- s_lastNITZTimeDataSize = p.dataSize();
- memcpy(s_lastNITZTimeData, p.data(), p.dataSize());
- }
-
-
- if (shouldScheduleTimeout) {
-
- if (s_last_wake_timeout_info != NULL) {
- s_last_wake_timeout_info->userParam = (void *)1;
- }
- s_last_wake_timeout_info= internalRequestTimedCallback(wakeTimeoutCallback, NULL,
- &TIMEVAL_WAKE_TIMEOUT);
- }
- return;
- error_exit:
- if (shouldScheduleTimeout) {
- releaseWakeLock();
- }
- }
- extern "C" void RIL_onUnsolicitedResponse(int unsolResponse, void *data,
- size_t datalen)
- {
- int unsolResponseIndex;
- int ret;
- int64_t timeReceived = 0;
- bool shouldScheduleTimeout = false;
- if (s_registerCalled == 0) {
-
- LOGW("RIL_onUnsolicitedResponse called before RIL_register");
- return;
- }
- unsolResponseIndex = unsolResponse - RIL_UNSOL_RESPONSE_BASE;
- if ((unsolResponseIndex < 0)
- || (unsolResponseIndex >= (int32_t)NUM_ELEMS(s_unsolResponses))) {
- LOGE("unsupported unsolicited response code %d", unsolResponse);
- return;
- }
-
-
-
- switch (s_unsolResponses[unsolResponseIndex].wakeType) {
- case WAKE_PARTIAL:
- grabPartialWakeLock();
- shouldScheduleTimeout = true;
- break;
- case DONT_WAKE:
- default:
-
- shouldScheduleTimeout = false;
- break;
- }
-
-
-
-
- if (unsolResponse == RIL_UNSOL_NITZ_TIME_RECEIVED) {
- timeReceived = elapsedRealtime();
- }
- appendPrintBuf("[UNSL]< %s", requestToString(unsolResponse));
- Parcel p;
- p.writeInt32 (RESPONSE_UNSOLICITED);
- p.writeInt32 (unsolResponse);
- ret = s_unsolResponses[unsolResponseIndex].responseFunction(p, data, datalen);
- if (ret != 0) {
-
- goto error_exit;
- }
-
- switch(unsolResponse) {
- case RIL_UNSOL_RESPONSE_RADIO_STATE_CHANGED:
- p.writeInt32(s_callbacks.onStateRequest());
- appendPrintBuf("%s {%s}", printBuf,
- radioStateToString(s_callbacks.onStateRequest()));
- break;
- case RIL_UNSOL_NITZ_TIME_RECEIVED:
-
-
-
-
-
- p.writeInt64(timeReceived);
- break;
- }
- ret = sendResponse(p);
- if (ret != 0 && unsolResponse == RIL_UNSOL_NITZ_TIME_RECEIVED) {
-
-
-
-
- if (s_lastNITZTimeData != NULL) {
- free (s_lastNITZTimeData);
- s_lastNITZTimeData = NULL;
- }
- s_lastNITZTimeData = malloc(p.dataSize());
- s_lastNITZTimeDataSize = p.dataSize();
- memcpy(s_lastNITZTimeData, p.data(), p.dataSize());
- }
-
-
- if (shouldScheduleTimeout) {
-
- if (s_last_wake_timeout_info != NULL) {
- s_last_wake_timeout_info->userParam = (void *)1;
- }
- s_last_wake_timeout_info= internalRequestTimedCallback(wakeTimeoutCallback, NULL,
- &TIMEVAL_WAKE_TIMEOUT);
- }
- return;
- error_exit:
- if (shouldScheduleTimeout) {
- releaseWakeLock();
- }
- }
这个函数处理modem从网络端接收到的各种事件,如网络信号变化,拨入的电话,收到短信等。然后传给客户进程。
3.RIL_requestTimedCallback
- extern "C" void RIL_requestTimedCallback (RIL_TimedCallback callback, void *param,
- const struct timeval *relativeTime) {
- internalRequestTimedCallback (callback, param, relativeTime);
- }
- extern "C" void RIL_requestTimedCallback (RIL_TimedCallback callback, void *param,
- const struct timeval *relativeTime) {
- internalRequestTimedCallback (callback, param, relativeTime);
- }
- static UserCallbackInfo *internalRequestTimedCallback (RIL_TimedCallback callback, void *param,
- const struct timeval *relativeTime)
- {
- struct timeval myRelativeTime;
- UserCallbackInfo *p_info;
- p_info = (UserCallbackInfo *) malloc (sizeof(UserCallbackInfo));
- p_info->p_callback = callback;
- p_info->userParam = param;
- if (relativeTime == NULL) {
-
- memset (&myRelativeTime, 0, sizeof(myRelativeTime));
- } else {
-
- memcpy (&myRelativeTime, relativeTime, sizeof(myRelativeTime));
- }
- ril_event_set(&(p_info->event), -1, false, userTimerCallback, p_info);
- ril_timer_add(&(p_info->event), &myRelativeTime);
- triggerEvLoop();
- return p_info;
- }
- static UserCallbackInfo *internalRequestTimedCallback (RIL_TimedCallback callback, void *param,
- const struct timeval *relativeTime)
- {
- struct timeval myRelativeTime;
- UserCallbackInfo *p_info;
- p_info = (UserCallbackInfo *) malloc (sizeof(UserCallbackInfo));
- p_info->p_callback = callback;
- p_info->userParam = param;
- if (relativeTime == NULL) {
-
- memset (&myRelativeTime, 0, sizeof(myRelativeTime));
- } else {
-
- memcpy (&myRelativeTime, relativeTime, sizeof(myRelativeTime));
- }
- ril_event_set(&(p_info->event), -1, false, userTimerCallback, p_info);
- ril_timer_add(&(p_info->event), &myRelativeTime);
- triggerEvLoop();
- return p_info;
- }
RIL_RadioFunctions定义
客户端向Rild发送请求的接口,由各手机厂商实现。
hardware\ril\include\telephony\Ril.h
- typedef struct {
- int version;
- RIL_RequestFunc onRequest;
- RIL_RadioStateRequest onStateRequest;
- RIL_Supports supports;
- RIL_Cancel onCancel;
- RIL_GetVersion getVersion;
- } RIL_RadioFunctions;
- typedef struct {
- int version;
- RIL_RequestFunc onRequest;
- RIL_RadioStateRequest onStateRequest;
- RIL_Supports supports;
- RIL_Cancel onCancel;
- RIL_GetVersion getVersion;
- } RIL_RadioFunctions;
变量定义:
- static const RIL_RadioFunctions s_callbacks = {
- RIL_VERSION,
- onRequest,
- currentState,
- onSupports,
- onCancel,
- getVersion
- };
- static const RIL_RadioFunctions s_callbacks = {
- RIL_VERSION,
- onRequest,
- currentState,
- onSupports,
- onCancel,
- getVersion
- };
在hardware\ril\reference-ril\reference-ril.c中实现了RIL_RadioFunctions的各个接口函数
1.onRequest
- static void onRequest (int request, void *data, size_t datalen, RIL_Token t)
- {
- ATResponse *p_response;
- int err;
- LOGD("onRequest: %s", requestToString(request));
-
-
-
- if (sState == RADIO_STATE_UNAVAILABLE
- && request != RIL_REQUEST_GET_SIM_STATUS
- ) {
- RIL_onRequestComplete(t, RIL_E_RADIO_NOT_AVAILABLE, NULL, 0);
- return;
- }
-
-
-
- if (sState == RADIO_STATE_OFF&& !(request == RIL_REQUEST_RADIO_POWER
- || request == RIL_REQUEST_GET_SIM_STATUS)
- ) {
- RIL_onRequestComplete(t, RIL_E_RADIO_NOT_AVAILABLE, NULL, 0);
- return;
- }
- switch (request) {
- case RIL_REQUEST_GET_SIM_STATUS: {
- RIL_CardStatus *p_card_status;
- char *p_buffer;
- int buffer_size;
- int result = getCardStatus(&p_card_status);
- if (result == RIL_E_SUCCESS) {
- p_buffer = (char *)p_card_status;
- buffer_size = sizeof(*p_card_status);
- } else {
- p_buffer = NULL;
- buffer_size = 0;
- }
- RIL_onRequestComplete(t, result, p_buffer, buffer_size);
- freeCardStatus(p_card_status);