Android(安卓)Rild模块源码分析
Android 电话系统框架介绍
在android系统中rild运行在AP上,AP上的应用通过rild发送AT指令给BP,BP接收到信息后又通过rild传送给AP。AP与BP之间有两种通信方式:
1.SolicitedResponse:Ap向Bp发送请求,Bp给Ap发送回复,该类型的AT指令及其回调函数以数组的形式存放在Ril_commands.h文件中:
{数组中的索引号,请求回调函数,响应回调函数}
[plain] view plain copy
- {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.unSolicitedResponse:Bp主动给Ap发送事件,该类型的AT指令及其回调函数以数组的形式存放在ril_unsol_commands.h文件中:
{数组中的索引号,响应回调函数,类型}
[plain] view plain copy
- {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中来启动的。
[plain] view plain copy- serviceril-daemon/system/bin/rild
- classmain
- socketrildstream660rootradio
- socketrild-debugstream660radiosystem
- userroot
- groupradiocacheinetmiscaudiosdcard_rwlog
- serviceril-daemon/system/bin/rild
- classmain
- socketrildstream660rootradio
- socketrild-debugstream660radiosystem
- userroot
- groupradiocacheinetmiscaudiosdcard_rwlog
RILD进程入口函数分析
接下来给出的是RILD进程启动的时序图:
hardware\ril\rild\rild.c
[cpp] view plain copy- intmain(intargc,char**argv)
- {
- constchar*rilLibPath=NULL;
- char**rilArgv;
- void*dlHandle;
- constRIL_RadioFunctions*(*rilInit)(conststructRIL_Env*,int,char**);
- constRIL_RadioFunctions*funcs;
- charlibPath[PROPERTY_VALUE_MAX];
- unsignedcharhasLibArgs=0;
- inti;
- umask(S_IRGRP|S_IWGRP|S_IXGRP|S_IROTH|S_IWOTH|S_IXOTH);
- //rild启动无参数
- for(i=1;i<argc;){
- if(0==strcmp(argv[i],"-l")&&(argc-i>1)){
- rilLibPath=argv[i+1];
- i+=2;
- }elseif(0==strcmp(argv[i],"--")){
- i++;
- hasLibArgs=1;
- break;
- }else{
- usage(argv[0]);
- }
- }
- if(rilLibPath==NULL){
- //通过Android属性系统读取属性"rild.libpath"的值,即lib库的存放路径
- if(0==property_get(LIB_PATH_PROPERTY,libPath,NULL)){
- gotodone;
- }else{
- rilLibPath=libPath;
- }
- }
- ##################################################################################
- 判断是否为模拟器
- ##################################################################################
- #if1
- {
- staticchar*arg_overrides[3];
- staticchararg_device[32];
- intdone=0;
- #defineREFERENCE_RIL_PATH"/system/lib/libreference-ril.so"
- /*first,read/proc/cmdlineintomemory*/
- charbuffer[1024],*p,*q;
- intlen;
- intfd=open("/proc/cmdline",O_RDONLY);
- if(fd<0){
- LOGD("couldnotopen/proc/cmdline:%s",strerror(errno));
- gotoOpenLib;
- }
- //读取/proc/cmdline文件中的内容
- do{
- len=read(fd,buffer,sizeof(buffer));}
- while(len==-1&&errno==EINTR);
- if(len<0){
- LOGD("couldnotread/proc/cmdline:%s",strerror(errno));
- close(fd);
- gotoOpenLib;
- }
- close(fd);
- //判断是否为模拟器,对于真机,此处条件为false
- if(strstr(buffer,"android.qemud=")!=NULL)
- {
- inttries=5;
- #defineQEMUD_SOCKET_NAME"qemud"
- while(1){
- intfd;
- 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("couldnotconnectto%ssocket:%s",QEMUD_SOCKET_NAME,strerror(errno));
- if(--tries==0)
- break;
- }
- if(!done){
- LOGE("couldnotconnectto%ssocket(givingup):%s",
- QEMUD_SOCKET_NAME,strerror(errno));
- while(1)
- sleep(0x00ffffff);
- }
- }
- /*otherwise,trytoseeifwepassedadevicenamefromthekernel*/
- if(!done)do{//true
- #defineKERNEL_OPTION"android.ril="
- #defineDEV_PREFIX"/dev/"
- //判断/proc/cmdline中的内容是否包含"android.ril="
- 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){//false
- argv=arg_overrides;
- argc=3;
- i=1;
- hasLibArgs=1;
- rilLibPath=REFERENCE_RIL_PATH;
- LOGD("overridingwith%s%s",arg_overrides[1],arg_overrides[2]);
- }
- }
- OpenLib:
- #endif
- ##################################################################################
- 动态库装载
- ##################################################################################
- switchUser();//设置Rild进程的组用户为radio
- //加载厂商自定义的库
- ①dlHandle=dlopen(rilLibPath,RTLD_NOW);
- if(dlHandle==NULL){
- fprintf(stderr,"dlopenfailed:%s\n",dlerror());
- exit(-1);
- }
- //<spanstyle="color:rgb(0,128,0);line-height:1.5;font-family:'CourierNew';white-space:pre-wrap;">创建客户端事件监听线程</span>
- ②RIL_startEventLoop();
- //<spanstyle="color:rgb(0,128,0);line-height:1.5;font-family:'CourierNew';white-space:pre-wrap;">通过dlsym定位到RIL_Init函数的地址,并且强制转换为RIL_RadioFunctions的函数指针</span>
- ③rilInit=(constRIL_RadioFunctions*(*)(conststructRIL_Env*,int,char**))dlsym(dlHandle,"RIL_Init");
- if(rilInit==NULL){
- fprintf(stderr,"RIL_Initnotdefinedorexportedin%s\n",rilLibPath);
- exit(-1);
- }
- if(hasLibArgs){//false
- rilArgv=argv+i-1;
- argc=argc-i+1;
- }else{
- staticchar*newArgv[MAX_LIB_ARGS];
- staticcharargs[PROPERTY_VALUE_MAX];
- rilArgv=newArgv;
- property_get(LIB_ARGS_PROPERTY,args,"");//通过属性系统读取"rild.libargs"属性值
- argc=make_argv(args,rilArgv);
- }
- //Makesurethere'sareasonableargv[0]
- rilArgv[0]=argv[0];
- //调用RIL_Init函数来初始化rild,传入参数s_rilEnv,返回RIL_RadioFunctions地址
- ④funcs=rilInit(&s_rilEnv,argc,rilArgv);
- //<spanstyle="color:rgb(0,128,0);line-height:1.5;font-family:'CourierNew';white-space:pre-wrap;">注册客户端事件处理接口</span><spanstyle="color:rgb(0,128,0);font-family:'CourierNew';line-height:1.5;white-space:pre-wrap;">RIL_RadioFunctions</span><spanstyle="color:rgb(0,128,0);line-height:1.5;font-family:'CourierNew';white-space:pre-wrap;">,并创建socket监听事件</span>
- ⑤RIL_register(funcs);
- done:
- while(1){
- //sleep(UINT32_MAX)seemstoreturnimmediatelyonbionic
- sleep(0x00ffffff);
- }
- }
- intmain(intargc,char**argv)
- {
- constchar*rilLibPath=NULL;
- char**rilArgv;
- void*dlHandle;
- constRIL_RadioFunctions*(*rilInit)(conststructRIL_Env*,int,char**);
- constRIL_RadioFunctions*funcs;
- charlibPath[PROPERTY_VALUE_MAX];
- unsignedcharhasLibArgs=0;
- inti;
- umask(S_IRGRP|S_IWGRP|S_IXGRP|S_IROTH|S_IWOTH|S_IXOTH);
- //rild启动无参数
- for(i=1;i<argc;){
- if(0==strcmp(argv[i],"-l")&&(argc-i>1)){
- rilLibPath=argv[i+1];
- i+=2;
- }elseif(0==strcmp(argv[i],"--")){
- i++;
- hasLibArgs=1;
- break;
- }else{
- usage(argv[0]);
- }
- }
- if(rilLibPath==NULL){
- //通过Android属性系统读取属性"rild.libpath"的值,即lib库的存放路径
- if(0==property_get(LIB_PATH_PROPERTY,libPath,NULL)){
- gotodone;
- }else{
- rilLibPath=libPath;
- }
- }
- ##################################################################################
- 判断是否为模拟器
- ##################################################################################
- #if1
- {
- staticchar*arg_overrides[3];
- staticchararg_device[32];
- intdone=0;
- #defineREFERENCE_RIL_PATH"/system/lib/libreference-ril.so"
- /*first,read/proc/cmdlineintomemory*/
- charbuffer[1024],*p,*q;
- intlen;
- intfd=open("/proc/cmdline",O_RDONLY);
- if(fd<0){
- LOGD("couldnotopen/proc/cmdline:%s",strerror(errno));
- gotoOpenLib;
- }
- //读取/proc/cmdline文件中的内容
- do{
- len=read(fd,buffer,sizeof(buffer));}
- while(len==-1&&errno==EINTR);
- if(len<0){
- LOGD("couldnotread/proc/cmdline:%s",strerror(errno));
- close(fd);
- gotoOpenLib;
- }
- close(fd);
- //判断是否为模拟器,对于真机,此处条件为false
- if(strstr(buffer,"android.qemud=")!=NULL)
- {
- inttries=5;
- #defineQEMUD_SOCKET_NAME"qemud"
- while(1){
- intfd;
- 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("couldnotconnectto%ssocket:%s",QEMUD_SOCKET_NAME,strerror(errno));
- if(--tries==0)
- break;
- }
- if(!done){
- LOGE("couldnotconnectto%ssocket(givingup):%s",
- QEMUD_SOCKET_NAME,strerror(errno));
- while(1)
- sleep(0x00ffffff);
- }
- }
- /*otherwise,trytoseeifwepassedadevicenamefromthekernel*/
- if(!done)do{//true
- #defineKERNEL_OPTION"android.ril="
- #defineDEV_PREFIX"/dev/"
- //判断/proc/cmdline中的内容是否包含"android.ril="
- 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){//false
- argv=arg_overrides;
- argc=3;
- i=1;
- hasLibArgs=1;
- rilLibPath=REFERENCE_RIL_PATH;
- LOGD("overridingwith%s%s",arg_overrides[1],arg_overrides[2]);
- }
- }
- OpenLib:
- #endif
- ##################################################################################
- 动态库装载
- ##################################################################################
- switchUser();//设置Rild进程的组用户为radio
- //加载厂商自定义的库
- ①dlHandle=dlopen(rilLibPath,RTLD_NOW);
- if(dlHandle==NULL){
- fprintf(stderr,"dlopenfailed:%s\n",dlerror());
- exit(-1);
- }
- //<spanstyle="font-family:'CourierNew';color:#080000;line-height:1.5;white-space:pre-wrap;">创建客户端事件监听线程</span>
- ②RIL_startEventLoop();
- //<spanstyle="font-family:'CourierNew';color:#080000;line-height:1.5;white-space:pre-wrap;">通过dlsym定位到RIL_Init函数的地址,并且强制转换为RIL_RadioFunctions的函数指针</span>
- ③rilInit=(constRIL_RadioFunctions*(*)(conststructRIL_Env*,int,char**))dlsym(dlHandle,"RIL_Init");
- if(rilInit==NULL){
- fprintf(stderr,"RIL_Initnotdefinedorexportedin%s\n",rilLibPath);
- exit(-1);
- }
- if(hasLibArgs){//false
- rilArgv=argv+i-1;
- argc=argc-i+1;
- }else{
- staticchar*newArgv[MAX_LIB_ARGS];
- staticcharargs[PROPERTY_VALUE_MAX];
- rilArgv=newArgv;
- property_get(LIB_ARGS_PROPERTY,args,"");//通过属性系统读取"rild.libargs"属性值
- argc=make_argv(args,rilArgv);
- }
- //Makesurethere'sareasonableargv[0]
- rilArgv[0]=argv[0];
- //调用RIL_Init函数来初始化rild,传入参数s_rilEnv,返回RIL_RadioFunctions地址
- ④funcs=rilInit(&s_rilEnv,argc,rilArgv);
- //<spanstyle="font-family:'CourierNew';color:#080000;line-height:1.5;white-space:pre-wrap;">注册客户端事件处理接口</span><spanstyle="font-family:'CourierNew';color:#080000;line-height:1.5;white-space:pre-wrap;">RIL_RadioFunctions</span><spanstyle="font-family:'CourierNew';color:#080000;line-height:1.5;white-space:pre-wrap;">,并创建socket监听事件</span>
- ⑤RIL_register(funcs);
- done:
- while(1){
- //sleep(UINT32_MAX)seemstoreturnimmediatelyonbionic
- sleep(0x00ffffff);
- }
- }
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
[cpp] view plain copy- extern"C"voidRIL_startEventLoop(void){
- intret;
- pthread_attr_tattr;
- /*spinupeventLoopthreadandwaitforittogetstarted*/
- s_started=0;
- pthread_mutex_lock(&s_startupMutex);
- pthread_attr_init(&attr);
- pthread_attr_setdetachstate(&attr,PTHREAD_CREATE_DETACHED);
- //创建一个工作线程eventLoop
- ret=pthread_create(&s_tid_dispatch,&attr,eventLoop,NULL);
- //确保函数返回前eventLoop线程启动运行
- while(s_started==0){
- pthread_cond_wait(&s_startupCond,&s_startupMutex);
- }
- pthread_mutex_unlock(&s_startupMutex);
- if(ret<0){
- LOGE("Failedtocreatedispatchthreaderrno:%d",errno);
- return;
- }
- }
- extern"C"voidRIL_startEventLoop(void){
- intret;
- pthread_attr_tattr;
- /*spinupeventLoopthreadandwaitforittogetstarted*/
- s_started=0;
- pthread_mutex_lock(&s_startupMutex);
- pthread_attr_init(&attr);
- pthread_attr_setdetachstate(&attr,PTHREAD_CREATE_DETACHED);
- //创建一个工作线程eventLoop
- ret=pthread_create(&s_tid_dispatch,&attr,eventLoop,NULL);
- //确保函数返回前eventLoop线程启动运行
- while(s_started==0){
- pthread_cond_wait(&s_startupCond,&s_startupMutex);
- }
- pthread_mutex_unlock(&s_startupMutex);
- if(ret<0){
- LOGE("Failedtocreatedispatchthreaderrno:%d",errno);
- return;
- }
- }
- staticvoid*eventLoop(void*param){
- intret;
- intfiledes[2];
- ril_event_init();//初始化请求队列
- pthread_mutex_lock(&s_startupMutex);
- s_started=1;//eventLoop线程运行标志位
- pthread_cond_broadcast(&s_startupCond);
- pthread_mutex_unlock(&s_startupMutex);
- //创建匿名管道
- ret=pipe(filedes);
- if(ret<0){
- LOGE("Errorinpipe()errno:%d",errno);
- returnNULL;
- }
- //s_fdWakeupRead为管道读端
- s_fdWakeupRead=filedes[0];
- //s_fdWakeupWrite为管道写端
- s_fdWakeupWrite=filedes[1];
- //设置管道读端为O_NONBLOCK非阻塞
- fcntl(s_fdWakeupRead,F_SETFL,O_NONBLOCK);
- //初始化s_wakeupfd_event结构体的内容,句柄为s_fdWakeupRead,回调函数为processWakeupCallback
- ril_event_set(&s_wakeupfd_event,s_fdWakeupRead,true,processWakeupCallback,NULL);
- ①rilEventAddWakeup(&s_wakeupfd_event);
- //Onlyreturnsonerror
- ②ril_event_loop();
- LOGE("errorinevent_loop_baseerrno:%d",errno);
- returnNULL;
- }
- staticvoid*eventLoop(void*param){
- intret;
- intfiledes[2];
- ril_event_init();//初始化请求队列
- pthread_mutex_lock(&s_startupMutex);
- s_started=1;//eventLoop线程运行标志位
- pthread_cond_broadcast(&s_startupCond);
- pthread_mutex_unlock(&s_startupMutex);
- //创建匿名管道
- ret=pipe(filedes);
- if(ret<0){
- LOGE("Errorinpipe()errno:%d",errno);
- returnNULL;
- }
- //s_fdWakeupRead为管道读端
- s_fdWakeupRead=filedes[0];
- //s_fdWakeupWrite为管道写端
- s_fdWakeupWrite=filedes[1];
- //设置管道读端为O_NONBLOCK非阻塞
- fcntl(s_fdWakeupRead,F_SETFL,O_NONBLOCK);
- //初始化s_wakeupfd_event结构体的内容,句柄为s_fdWakeupRead,回调函数为processWakeupCallback
- ril_event_set(&s_wakeupfd_event,s_fdWakeupRead,true,processWakeupCallback,NULL);
- ①rilEventAddWakeup(&s_wakeupfd_event);
- //Onlyreturnsonerror
- ②ril_event_loop();
- LOGE("errorinevent_loop_baseerrno:%d",errno);
- returnNULL;
- }
1.定时事件:根据事件的执行时间来启动执行,通过ril_timer_add添加到time_list队列中
2.Wakeup事件:这些事件的句柄fd将加入的selectIO多路复用的句柄池readFDs中,当对应的fd可读时将触发这些事件。对于处于listen端的socket,fd可读表示有个客户端连接,此时需要调用accept接受连接。
事件定义如下: [cpp] view plain copy- structril_event{
- structril_event*next;
- structril_event*prev;
- intfd;//文件句柄
- intindex;//该事件在监控表中的索引
- boolpersist;//如果是保持的,则不从watch_list中删除
- structtimevaltimeout;//任务执行时间
- ril_event_cbfunc;//回调事件处理函数
- void*param;//回调时参数
- };
- structril_event{
- structril_event*next;
- structril_event*prev;
- intfd;//文件句柄
- intindex;//该事件在监控表中的索引
- boolpersist;//如果是保持的,则不从watch_list中删除
- structtimevaltimeout;//任务执行时间
- ril_event_cbfunc;//回调事件处理函数
- void*param;//回调时参数
- };
在Rild进程中的几个重要事件有
[cpp] view plain copy- staticstructril_events_commands_event;
- ril_event_set(&s_commands_event,s_fdCommand,1,processCommandsCallback,p_rs)
- staticstructril_events_wakeupfd_event;
- ril_event_set(&s_wakeupfd_event,s_fdWakeupRead,true,processWakeupCallback,NULL)
- staticstructril_events_listen_event;
- ril_event_set(&s_listen_event,s_fdListen,false,listenCallback,NULL)
- staticstructril_events_wake_timeout_event;
- ril_timer_add(&(p_info->event),&myRelativeTime);
- staticstructril_events_commands_event;
- ril_event_set(&s_commands_event,s_fdCommand,1,processCommandsCallback,p_rs)
- staticstructril_events_wakeupfd_event;
- ril_event_set(&s_wakeupfd_event,s_fdWakeupRead,true,processWakeupCallback,NULL)
- staticstructril_events_listen_event;
- ril_event_set(&s_listen_event,s_fdListen,false,listenCallback,NULL)
- staticstructril_events_wake_timeout_event;
- ril_timer_add(&(p_info->event),&myRelativeTime);
- staticstructril_events_debug_event;
- ril_event_set(&s_debug_event,s_fdDebug,true,debugCallback,NULL)
- staticstructril_events_debug_event;
- ril_event_set(&s_debug_event,s_fdDebug,true,debugCallback,NULL)
在RILD中定义了三个事件队列,用于处理不同的事件:
/事件监控队列
staticstructril_event*watch_table[MAX_FD_EVENTS];
//定时事件队列
staticstructril_eventtimer_list;
//处理事件队列
staticstructril_eventpending_list;//待处理事件队列,事件已经触发,需要所回调处理的事件
添加事件
1.添加 Wakeup 事件 [cpp] view plain copy- staticvoidrilEventAddWakeup(structril_event*ev){
- ril_event_add(ev);//向监控表watch_table添加一个s_wakeupfd_event事件
- triggerEvLoop();//向管道s_fdWakeupWrite中写入之来触发事件循环
- }
- staticvoidrilEventAddWakeup(structril_event*ev){
- ril_event_add(ev);//向监控表watch_table添加一个s_wakeupfd_event事件
- triggerEvLoop();//向管道s_fdWakeupWrite中写入之来触发事件循环
- }
[cpp] view plain copy
- voidril_event_add(structril_event*ev)
- {
- dlog("~~~~+ril_event_add~~~~");
- MUTEX_ACQUIRE();
- for(inti=0;i<MAX_FD_EVENTS;i++){//遍历监控表watch_table
- if(watch_table[i]==NULL){//从监控表中查找空闲的索引,然后把该任务加入到监控表中
- watch_table[i]=ev;//向监控表中添加事件
- ev->index=i;//事件的索引设置为在监控表中的索引
- dlog("~~~~addedat%d~~~~",i);
- dump_event(ev);
- FD_SET(ev->fd,&readFds);//将添加的事件对应的句柄添加到句柄池readFds中
- if(ev->fd>=nfds)nfds=ev->fd+1;//修改句柄最大值
- dlog("~~~~nfds=%d~~~~",nfds);
- break;
- }
- }
- MUTEX_RELEASE();
- dlog("~~~~-ril_event_add~~~~");
- }
- voidril_event_add(structril_event*ev)
- {
- dlog("~~~~+ril_event_add~~~~");
- MUTEX_ACQUIRE();
- for(inti=0;i<MAX_FD_EVENTS;i++){//遍历监控表watch_table
- if(watch_table[i]==NULL){//从监控表中查找空闲的索引,然后把该任务加入到监控表中
- watch_table[i]=ev;//向监控表中添加事件
- ev->index=i;//事件的索引设置为在监控表中的索引
- dlog("~~~~addedat%d~~~~",i);
- dump_event(ev);
- FD_SET(ev->fd,&readFds);//将添加的事件对应的句柄添加到句柄池readFds中
- if(ev->fd>=nfds)nfds=ev->fd+1;//修改句柄最大值
- dlog("~~~~nfds=%d~~~~",nfds);
- break;
- }
- }
- MUTEX_RELEASE();
- dlog("~~~~-ril_event_add~~~~");
- }
2.添加定时事件 [cpp] view plain copy
- voidril_timer_add(structril_event*ev,structtimeval*tv)
- {
- dlog("~~~~+ril_timer_add~~~~");
- MUTEX_ACQUIRE();
- structril_event*list;
- if(tv!=NULL){
- list=timer_list.next;
- ev->fd=-1;//makesurefdisinvalid
- structtimevalnow;
- getNow(&now);
- timeradd(&now,tv,&ev->timeout);
- //keeplistsorted
- while(timercmp(&list->timeout,&ev->timeout,<)&&(list!=&timer_list)){
- list=list->next;
- }
- //listnowpointstothefirsteventolderthanev
- addToList(ev,list);
- }
- MUTEX_RELEASE();
- dlog("~~~~-ril_timer_add~~~~");
- }
- voidril_timer_add(structril_event*ev,structtimeval*tv)
- {
- dlog("~~~~+ril_timer_add~~~~");
- MUTEX_ACQUIRE();
- structril_event*list;
- if(tv!=NULL){
- list=timer_list.next;
- ev->fd=-1;//makesurefdisinvalid
- structtimevalnow;
- getNow(&now);
- timeradd(&now,tv,&ev->timeout);
- //keeplistsorted
- while(timercmp(&list->timeout,&ev->timeout,<)&&(list!=&timer_list)){
- list=list->next;
- }
- //listnowpointstothefirsteventolderthanev
- addToList(ev,list);
- }
- MUTEX_RELEASE();
- dlog("~~~~-ril_timer_add~~~~");
- }
触发事件
[cpp] view plain copy- staticvoidtriggerEvLoop(){
- intret;
- if(!pthread_equal(pthread_self(),s_tid_dispatch)){//如果当前线程ID不等于事件分发线程eventLoop的线程ID
- do{
- ret=write(s_fdWakeupWrite,"",1);//向管道写端写入值1来触发eventLoop事件循环
- }while(ret<0&&errno==EINTR);
- }
- }
- staticvoidtriggerEvLoop(){
- intret;
- if(!pthread_equal(pthread_self(),s_tid_dispatch)){//如果当前线程ID不等于事件分发线程eventLoop的线程ID
- do{
- ret=write(s_fdWakeupWrite,"",1);//向管道写端写入值1来触发eventLoop事件循环
- }while(ret<0&&errno==EINTR);
- }
- }
处理事件
[cpp] view plain copy- voidril_event_loop()
- {
- intn;
- fd_setrfds;
- structtimevaltv;
- structtimeval*ptv;
- for(;;){
- memcpy(&rfds,&readFds,sizeof(fd_set));
- if(-1==calcNextTimeout(&tv)){
- dlog("~~~~notimers;blockingindefinitely~~~~");
- ptv=NULL;
- }else{
- dlog("~~~~blockingfor%ds+%dus~~~~",(int)tv.tv_sec,(int)tv.tv_usec);
- ptv=&tv;
- }
- //使用select函数等待在FDS上,只要FDS中记录的设备有数据到来,select就会设置相应的标志位并返回。readFDS记录了所有的事件相关设备句柄。readFDS中句柄是在在AddEvent加入的。
- printReadies(&rfds);
- n=select(nfds,&rfds,NULL,NULL,ptv);
- printReadies(&rfds);
- dlog("~~~~%deventsfired~~~~",n);
- if(n<0){
- if(errno==EINTR)continue;
- LOGE("ril_event:selecterror(%d)",errno);
- return;
- }
- processTimeouts();//从timer_list中查询执行时间已到的事件,并添加到pending_list中
- processReadReadies(&rfds,n);//从watch_table中查询数据可读的事件,并添加到pending_list中去处理,如果该事件不是持久事件,则同时从watch_table中删除
- //遍历pending_list,调用事件处理回调函数处理所有事件
- firePending();
- }
- }
- voidril_event_loop()
- {
- intn;
- fd_setrfds;
- structtimevaltv;
- structtimeval*ptv;
- for(;;){
- memcpy(&rfds,&readFds,sizeof(fd_set));
- if(-1==calcNextTimeout(&tv)){
- dlog("~~~~notimers;blockingindefinitely~~~~");
- ptv=NULL;
- }else{
- dlog("~~~~blockingfor%ds+%dus~~~~",(int)tv.tv_sec,(int)tv.tv_usec);
- ptv=&tv;
- }
- //使用select函数等待在FDS上,只要FDS中记录的设备有数据到来,select就会设置相应的标志位并返回。readFDS记录了所有的事件相关设备句柄。readFDS中句柄是在在AddEvent加入的。
- printReadies(&rfds);
- n=select(nfds,&rfds,NULL,NULL,ptv);
- printReadies(&rfds);
- dlog("~~~~%deventsfired~~~~",n);
- if(n<0){
- if(errno==EINTR)continue;
- LOGE("ril_event:selecterror(%d)",errno);
- return;
- }
- processTimeouts();//从timer_list中查询执行时间已到的事件,并添加到pending_list中
- processReadReadies(&rfds,n);//从watch_table中查询数据可读的事件,并添加到pending_list中去处理,如果该事件不是持久事件,则同时从watch_table中删除
- //遍历pending_list,调用事件处理回调函数处理所有事件
- firePending();
- }
- }
在eventLoop工作线程中,循环处理到来的事件及定时结束事件,整个处理流程如下图所示:
首先通过Linux中的select多路I/O复用对句柄池中的所有句柄进行监控,当有事件到来时select返回,否则阻塞。当select返回时,表示有事件的到来,通过调用processTimeouts函数来处理超时事件,处理方式是遍历time_list链表以查询超时事件,并将超时事件移入到pending_list链表中,接着调用processReadReadies函数来处理触发的事件,处理方式为遍历watch_table列表以查询触发的事件,并将触发的事件移入到pending_list链表中,如果该事件不是持久事件,还需要从watch_table列表中移除,当查询完两种待处理的事件并放入到pending_list链表中后,调用firePending函数对待处理的事件进行集中处理,处理方式为遍历链表,调用每一个事件的回调函数。
1.超时事件查询
[cpp] view plain copy- staticvoidprocessTimeouts()
- {
- dlog("~~~~+processTimeouts~~~~");
- MUTEX_ACQUIRE();
- structtimevalnow;
- structril_event*tev=timer_list.next;
- structril_event*next;
- getNow(&now);//获取当前时间
- dlog("~~~~Lookingfortimers<=%ds+%dus~~~~",(int)now.tv_sec,(int)now.tv_usec);
- //如果当前时间大于事件的超时时间,则将该事件从timer_list中移除,添加到pending_list
- while((tev!=&timer_list)&&(timercmp(&now,&tev->timeout,>))){
- dlog("~~~~firingtimer~~~~");
- next=tev->next;
- removeFromList(tev);//从timer_list中移除事件
- addToList(tev,&pending_list);//将事件添加到pending_list
- tev=next;
- }
- MUTEX_RELEASE();
- dlog("~~~~-processTimeouts~~~~");
- }
- staticvoidprocessTimeouts()
- {
- dlog("~~~~+processTimeouts~~~~");
- MUTEX_ACQUIRE();
- structtimevalnow;
- structril_event*tev=timer_list.next;
- structril_event*next;
- getNow(&now);//获取当前时间
- dlog("~~~~Lookingfortimers<=%ds+%dus~~~~",(int)now.tv_sec,(int)now.tv_usec);
- //如果当前时间大于事件的超时时间,则将该事件从timer_list中移除,添加到pending_list
- while((tev!=&timer_list)&&(timercmp(&now,&tev->timeout,>))){
- dlog("~~~~firingtimer~~~~");
- next=tev->next;
- removeFromList(tev);//从timer_list中移除事件
- addToList(tev,&pending_list);//将事件添加到pending_list
- tev=next;
- }
- MUTEX_RELEASE();
- dlog("~~~~-processTimeouts~~~~");
- }
2.可读事件查询
[cpp] view plain copy- staticvoidprocessReadReadies(fd_set*rfds,intn)
- {
- dlog("~~~~+processReadReadies(%d)~~~~",n);
- MUTEX_ACQUIRE();
- //遍历watch_table数组,根据select返回的句柄n查找对应的事件
- for(inti=0;(i<MAX_FD_EVENTS)&&(n>0);i++){
- structril_event*rev=watch_table[i];//得到相应的事件
- if(rev!=NULL&&FD_ISSET(rev->fd,rfds)){
- addToList(rev,&pending_list);//将该事件添加到pending_list中
- if(rev->persist==false){//如果该事件不是持久事件还要从watch_table中移除
- removeWatch(rev,i);
- }
- n--;
- }
- }
- MUTEX_RELEASE();
- dlog("~~~~-processReadReadies(%d)~~~~",n);
- }
- staticvoidprocessReadReadies(fd_set*rfds,intn)
- {
- dlog("~~~~+processReadReadies(%d)~~~~",n);
- MUTEX_ACQUIRE();
- //遍历watch_table数组,根据select返回的句柄n查找对应的事件
- for(inti=0;(i<MAX_FD_EVENTS)&&(n>0);i++){
- structril_event*rev=watch_table[i];//得到相应的事件
- if(rev!=NULL&&FD_ISSET(rev->fd,rfds)){
- addToList(rev,&pending_list);//将该事件添加到pending_list中
- if(rev->persist==false){//如果该事件不是持久事件还要从watch_table中移除
- removeWatch(rev,i);
- }
- n--;
- }
- }
- MUTEX_RELEASE();
- dlog("~~~~-processReadReadies(%d)~~~~",n);
- }
3.事件处理
[cpp] view plain copy- staticvoidfirePending()
- {
- dlog("~~~~+firePending~~~~");
- structril_event*ev=pending_list.next;
- while(ev!=&pending_list){//遍历pending_list链表,处理链表中的所有事件
- structril_event*next=ev->next;
- removeFromList(ev);//将处理完的事件从pending_list中移除
- ev->func(ev->fd,0,ev->param);//调用事件处理的回调函数
- ev=next;
- }
- dlog("~~~~-firePending~~~~");
- }
- staticvoidfirePending()
- {
- dlog("~~~~+firePending~~~~");
- structril_event*ev=pending_list.next;
- while(ev!=&pending_list){//遍历pending_list链表,处理链表中的所有事件
- structril_event*next=ev->next;
- removeFromList(ev);//将处理完的事件从pending_list中移除
- ev->func(ev->fd,0,ev->param);//调用事件处理的回调函数
- ev=next;
- }
- dlog("~~~~-firePending~~~~");
- }
RIL_Env定义
hardware\ril\include\telephony\ril.h
[cpp] view plain copy- structRIL_Env{
- //动态库完成请求后通知处理结果的接口
- void(*OnRequestComplete)(RIL_Tokent,RIL_Errnoe,void*response,size_tresponselen);
- //动态库unSolicitedResponse通知接口
- void(*OnUnsolicitedResponse)(intunsolResponse,constvoid*data,size_tdatalen);
- //向Rild提交一个超时任务的接口
- void(*RequestTimedCallback)(RIL_TimedCallbackcallback,void*param,conststructtimeval*relativeTime);
- };
- structRIL_Env{
- //动态库完成请求后通知处理结果的接口
- void(*OnRequestComplete)(RIL_Tokent,RIL_Errnoe,void*response,size_tresponselen);
- //动态库unSolicitedResponse通知接口
- void(*OnUnsolicitedResponse)(intunsolResponse,constvoid*data,size_tdatalen);
- //向Rild提交一个超时任务的接口
- void(*RequestTimedCallback)(RIL_TimedCallbackcallback,void*param,conststructtimeval*relativeTime);
- };
hardware\ril\rild\rild.c
s_rilEnv变量定义:
[cpp] view plain copy- staticstructRIL_Envs_rilEnv={
- RIL_onRequestComplete,
- RIL_onUnsolicitedResponse,
- RIL_requestTimedCallback
- };
- staticstructRIL_Envs_rilEnv={
- RIL_onRequestComplete,
- RIL_onUnsolicitedResponse,
- RIL_requestTimedCallback
- };
在hardware\ril\libril\ril.cpp中实现了RIL_Env的各个接口函数
1.RIL_onRequestComplete
[cpp] view plain copy- extern"C"voidRIL_onRequestComplete(RIL_Tokent,RIL_Errnoe,void*response,size_tresponselen){
- RequestInfo*pRI;
- intret;
- size_terrorOffset;
- pRI=(RequestInfo*)t;
- if(!checkAndDequeueRequestInfo(pRI)){
- LOGE("RIL_onRequestComplete:invalidRIL_Token");
- return;
- }
- if(pRI->local>0){
- //Locallyissuedcommand...voidonly!
- //responsedoesnotgobackupthecommandsocket
- LOGD("C[locl]<%s",requestToString(pRI->pCI->requestNumber));
- gotodone;
- }
- appendPrintBuf("[%04d]<%s",pRI->token,requestToString(pRI->pCI->requestNumber));
- if(pRI->cancelled==0){
- Parcelp;
- p.writeInt32(RESPONSE_SOLICITED);
- p.writeInt32(pRI->token);
- errorOffset=p.dataPosition();
- p.writeInt32(e);
- if(response!=NULL){
- //thereisaresponsepayload,nomattersuccessornot.
- ret=pRI->pCI->responseFunction(p,response,responselen);
- /*ifanerroroccurred,rewindandmarkit*/
- if(ret!=0){
- p.setDataPosition(errorOffset);
- p.writeInt32(ret);
- }
- }
- if(e!=RIL_E_SUCCESS){
- appendPrintBuf("%sfailsby%s",printBuf,failCauseToString(e));
- }
- if(s_fdCommand<0){
- LOGD("RILonRequestComplete:Commandchannelclosed");
- }
- sendResponse(p);
- }
- done:
- free(pRI);
- }
- extern"C"voidRIL_onRequestComplete(RIL_Tokent,RIL_Errnoe,void*response,size_tresponselen){
- RequestInfo*pRI;
- intret;
- size_terrorOffset;
- pRI=(RequestInfo*)t;
- if(!checkAndDequeueRequestInfo(pRI)){
- LOGE("RIL_onRequestComplete:invalidRIL_Token");
- return;
- }
- if(pRI->local>0){
- //Locallyissuedcommand...voidonly!
- //responsedoesnotgobackupthecommandsocket
- LOGD("C[locl]<%s",requestToString(pRI->pCI->requestNumber));
- gotodone;
- }
- appendPrintBuf("[%04d]<%s",pRI->token,requestToString(pRI->pCI->requestNumber));
- if(pRI->cancelled==0){
- Parcelp;
- p.writeInt32(RESPONSE_SOLICITED);
- p.writeInt32(pRI->token);
- errorOffset=p.dataPosition();
- p.writeInt32(e);
- if(response!=NULL){
- //thereisaresponsepayload,nomattersuccessornot.
- ret=pRI->pCI->responseFunction(p,response,responselen);
- /*ifanerroroccurred,rewindandmarkit*/
- if(ret!=0){
- p.setDataPosition(errorOffset);
- p.writeInt32(ret);
- }
- }
- if(e!=RIL_E_SUCCESS){
- appendPrintBuf("%sfailsby%s",printBuf,failCauseToString(e));
- }
- if(s_fdCommand<0){
- LOGD("RILonRequestComplete:Commandchannelclosed");
- }
- sendResponse(p);
- }
- done:
- free(pRI);
- }
通过调用responseXXX将底层响应传给客户进程
2.RIL_onUnsolicitedResponse
[cpp] view plain copy- extern"C"voidRIL_onUnsolicitedResponse(intunsolResponse,void*data,
- size_tdatalen)
- {
- intunsolResponseIndex;
- intret;
- int64_ttimeReceived=0;
- boolshouldScheduleTimeout=false;
- if(s_registerCalled==0){
- //IgnoreRIL_onUnsolicitedResponsebeforeRIL_register
- LOGW("RIL_onUnsolicitedResponsecalledbeforeRIL_register");
- return;
- }
- unsolResponseIndex=unsolResponse-RIL_UNSOL_RESPONSE_BASE;
- if((unsolResponseIndex<0)
- ||(unsolResponseIndex>=(int32_t)NUM_ELEMS(s_unsolResponses))){
- LOGE("unsupportedunsolicitedresponsecode%d",unsolResponse);
- return;
- }
- //Grabawakelockifneededforthisreponse,
- //asweexitwe'lleitherreleaseitimmediately
- //orsetatimertoreleaseitlater.
- switch(s_unsolResponses[unsolResponseIndex].wakeType){
- caseWAKE_PARTIAL:
- grabPartialWakeLock();
- shouldScheduleTimeout=true;
- break;
- caseDONT_WAKE:
- default:
- //Nowakelockisgrabedsodon'tsettimeout
- shouldScheduleTimeout=false;
- break;
- }
- //Markthetimethiswasreceived,doingthis
- //aftergrabingthewakelockincasegetting
- //theelapsedRealTimemightcauseustogoto
- //sleep.
- if(unsolResponse==RIL_UNSOL_NITZ_TIME_RECEIVED){
- timeReceived=elapsedRealtime();
- }
- appendPrintBuf("[UNSL]<%s",requestToString(unsolResponse));
- Parcelp;
- p.writeInt32(RESPONSE_UNSOLICITED);
- p.writeInt32(unsolResponse);
- ret=s_unsolResponses[unsolResponseIndex].responseFunction(p,data,datalen);
- if(ret!=0){
- //Problemwiththeresponse.Don'tcontinue;
- gotoerror_exit;
- }
- //somethingsgetmorepayload
- switch(unsolResponse){
- caseRIL_UNSOL_RESPONSE_RADIO_STATE_CHANGED:
- p.writeInt32(s_callbacks.onStateRequest());
- appendPrintBuf("%s{%s}",printBuf,
- radioStateToString(s_callbacks.onStateRequest()));
- break;
- caseRIL_UNSOL_NITZ_TIME_RECEIVED:
- //Storethetimethatthiswasreceivedsothe
- //handlerofthismessagecanaccountfor
- //thetimeittakestoarriveandprocess.In
- //particularthesystemhasbeenknowntosleep
- //beforethismessagecanbeprocessed.
- p.writeInt64(timeReceived);
- break;
- }
- ret=sendResponse(p);
- if(ret!=0&&unsolResponse==RIL_UNSOL_NITZ_TIME_RECEIVED){
- //Unfortunately,NITZtimeisnotpoll/updatelikeeverything
- //elseinthesystem.So,iftheupstreamclientisn'tconnected,
- //keepacopyofthelastNITZresponse(withreceivetimenoted
- //above)aroundsowecandeliveritwhenitisconnected
- 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());
- }
- //Fornow,weautomaticallygobacktosleepafterTIMEVAL_WAKE_TIMEOUT
- //FIXMEThejavacodeshouldhandshakeheretoreleasewakelock
- if(shouldScheduleTimeout){
- //Cancelthepreviousrequest
- 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"voidRIL_onUnsolicitedResponse(intunsolResponse,void*data,
- size_tdatalen)
- {
- intunsolResponseIndex;
- intret;
- int64_ttimeReceived=0;
- boolshouldScheduleTimeout=false;
- if(s_registerCalled==0){
- //IgnoreRIL_onUnsolicitedResponsebeforeRIL_register
- LOGW("RIL_onUnsolicitedResponsecalledbeforeRIL_register");
- return;
- }
- unsolResponseIndex=unsolResponse-RIL_UNSOL_RESPONSE_BASE;
- if((unsolResponseIndex<0)
- ||(unsolResponseIndex>=(int32_t)NUM_ELEMS(s_unsolResponses))){
- LOGE("unsupportedunsolicitedresponsecode%d",unsolResponse);
- return;
- }
- //Grabawakelockifneededforthisreponse,
- //asweexitwe'lleitherreleaseitimmediately
- //orsetatimertoreleaseitlater.
- switch(s_unsolResponses[unsolResponseIndex].wakeType){
- caseWAKE_PARTIAL:
- grabPartialWakeLock();
- shouldScheduleTimeout=true;
- break;
- caseDONT_WAKE:
- default:
- //Nowakelockisgrabedsodon'tsettimeout
- shouldScheduleTimeout=false;
- break;
- }
- //Markthetimethiswasreceived,doingthis
- //aftergrabingthewakelockincasegetting
- //theelapsedRealTimemightcauseustogoto
- //sleep.
- if(unsolResponse==RIL_UNSOL_NITZ_TIME_RECEIVED){
- timeReceived=elapsedRealtime();
- }
- appendPrintBuf("[UNSL]<%s",requestToString(unsolResponse));
- Parcelp;
- p.writeInt32(RESPONSE_UNSOLICITED);
- p.writeInt32(unsolResponse);
- ret=s_unsolResponses[unsolResponseIndex].responseFunction(p,data,datalen);
- if(ret!=0){
- //Problemwiththeresponse.Don'tcontinue;
- gotoerror_exit;
- }
- //somethingsgetmorepayload
- switch(unsolResponse){
- caseRIL_UNSOL_RESPONSE_RADIO_STATE_CHANGED:
- p.writeInt32(s_callbacks.onStateRequest());
- appendPrintBuf("%s{%s}",printBuf,
- radioStateToString(s_callbacks.onStateRequest()));
- break;
- caseRIL_UNSOL_NITZ_TIME_RECEIVED:
- //Storethetimethatthiswasreceivedsothe
- //handlerofthismessagecanaccountfor
- //thetimeittakestoarriveandprocess.In
- //particularthesystemhasbeenknowntosleep
- //beforethismessagecanbeprocessed.
- p.writeInt64(timeReceived);
- break;
- }
- ret=sendResponse(p);
- if(ret!=0&&unsolResponse==RIL_UNSOL_NITZ_TIME_RECEIVED){
- //Unfortunately,NITZtimeisnotpoll/updatelikeeverything
- //elseinthesystem.So,iftheupstreamclientisn'tconnected,
- //keepacopyofthelastNITZresponse(withreceivetimenoted
- //above)aroundsowecandeliveritwhenitisconnected
- 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());
- }
- //Fornow,weautomaticallygobacktosleepafterTIMEVAL_WAKE_TIMEOUT
- //FIXMEThejavacodeshouldhandshakeheretoreleasewakelock
- if(shouldScheduleTimeout){
- //Cancelthepreviousrequest
- 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
[cpp] view plain copy- extern"C"voidRIL_requestTimedCallback(RIL_TimedCallbackcallback,void*param,
- conststructtimeval*relativeTime){
- internalRequestTimedCallback(callback,param,relativeTime);
- }
- extern"C"voidRIL_requestTimedCallback(RIL_TimedCallbackcallback,void*param,
- conststructtimeval*relativeTime){
- internalRequestTimedCallback(callback,param,relativeTime);
- }
[cpp] view plain copy
- staticUserCallbackInfo*internalRequestTimedCallback(RIL_TimedCallbackcallback,void*param,
- conststructtimeval*relativeTime)
- {
- structtimevalmyRelativeTime;
- UserCallbackInfo*p_info;
- p_info=(UserCallbackInfo*)malloc(sizeof(UserCallbackInfo));
- p_info->p_callback=callback;
- p_info->userParam=param;
- if(relativeTime==NULL){
- /*treatnullparameterasa0relativetime*/
- memset(&myRelativeTime,0,sizeof(myRelativeTime));
- }else{
- /*FIXMEIthinkevent_add'stvparamisreallyconstanyway*/
- memcpy(&myRelativeTime,relativeTime,sizeof(myRelativeTime));
- }
- ril_event_set(&(p_info->event),-1,false,userTimerCallback,p_info);
- ril_timer_add(&(p_info->event),&myRelativeTime);
- triggerEvLoop();
- returnp_info;
- }
- staticUserCallbackInfo*internalRequestTimedCallback(RIL_TimedCallbackcallback,void*param,
- conststructtimeval*relativeTime)
- {
- structtimevalmyRelativeTime;
- UserCallbackInfo*p_info;
- p_info=(UserCallbackInfo*)malloc(sizeof(UserCallbackInfo));
- p_info->p_callback=callback;
- p_info->userParam=param;
- if(relativeTime==NULL){
- /*treatnullparameterasa0relativetime*/
- memset(&myRelativeTime,0,sizeof(myRelativeTime));
- }else{
- /*FIXMEIthinkevent_add'stvparamisreallyconstanyway*/
- memcpy(&myRelativeTime,relativeTime,sizeof(myRelativeTime));
- }
- ril_event_set(&(p_info->event),-1,false,userTimerCallback,p_info);
- ril_timer_add(&(p_info->event),&myRelativeTime);
- triggerEvLoop();
- returnp_info;
- }
RIL_RadioFunctions定义
客户端向Rild发送请求的接口,由各手机厂商实现。
hardware\ril\include\telephony\Ril.h
[cpp] view plain copy- typedefstruct{
- intversion;//Rild版本
- RIL_RequestFunconRequest;//AP请求接口
- RIL_RadioStateRequestonStateRequest;//BP状态查询
- RIL_Supportssupports;
- RIL_CancelonCancel;
- RIL_GetVersiongetVersion;//动态库版本
- }RIL_RadioFunctions;
- typedefstruct{
- intversion;//Rild版本
- RIL_RequestFunconRequest;//AP请求接口
- RIL_RadioStateRequestonStateRequest;//BP状态查询
- RIL_Supportssupports;
- RIL_CancelonCancel;
- RIL_GetVersiongetVersion;//动态库版本
- }RIL_RadioFunctions;
- staticconstRIL_RadioFunctionss_callbacks={
- RIL_VERSION,
- onRequest,
- currentState,
- onSupports,
- onCancel,
- getVersion
- };
- staticconstRIL_RadioFunctionss_callbacks={
- RIL_VERSION,
- onRequest,
- currentState,
- onSupports,
- onCancel,
- getVersion
- };
在hardware\ril\reference-ril\reference-ril.c中实现了RIL_RadioFunctions的各个接口函数
1.onRequest
[cpp] view plain copy- staticvoidonRequest(intrequest,void*data,size_tdatalen,RIL_Tokent)
- {
- ATResponse*p_response;
- interr;
- LOGD("onRequest:%s",requestToString(request));
- /*IgnoreallrequestsexceptRIL_REQUEST_GET_SIM_STATUS
- *whenRADIO_STATE_UNAVAILABLE.
- */
- if(sState==RADIO_STATE_UNAVAILABLE
- &&request!=RIL_REQUEST_GET_SIM_STATUS
- ){
- RIL_onRequestComplete(t,RIL_E_RADIO_NOT_AVAILABLE,NULL,0);
- return;
- }
- /*Ignoreallnon-powerrequestswhenRADIO_STATE_OFF
- *(exceptRIL_REQUEST_GET_SIM_STATUS)
- */
- 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){
- caseRIL_REQUEST_GET_SIM_STATUS:{
- RIL_CardStatus*p_card_status;
- char*p_buffer;
- intbuffer_size;
- intresult=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);
- break;
- }
- caseRIL_REQUEST_GET_CURRENT_CALLS:
- requestGetCurrentCalls(data,datalen,t);
- break;
- caseRIL_REQUEST_DIAL:
- requestDial(data,datalen,t);
- break;
- caseRIL_REQUEST_HANGUP:
- requestHangup(data,datalen,t);
- break;
- caseRIL_REQUEST_HANGUP_WAITING_OR_BACKGROUND:
- //3GPP22.0306.5.5
- //"ReleasesallheldcallsorsetsUserDeterminedUserBusy
- //(UDUB)forawaitingcall."
- at_send_command("AT+CHLD=0",NULL);
- /*successorfailureisignoredbytheupperlayerhere.
- itwillcallGET_CURRENT_CALLSanddeterminesuccessthatway*/
- RIL_onRequestComplete(t,RIL_E_SUCCESS,NULL,0);
- break;
- caseRIL_REQUEST_HANGUP_FOREGROUND_RESUME_BACKGROUND:
- //3GPP22.0306.5.5
- //"Releasesallactivecalls(ifanyexist)andaccepts
- //theother(heldorwaiting)call."
- at_send_command("AT+CHLD=1",NULL);
- /*successorfailureisignoredbytheupperlayerhere.
- itwillcallGET_CURRENT_CALLSanddeterminesuccessthatway*/
- RIL_onRequestComplete(t,RIL_E_SUCCESS,NULL,0);
- break;
- caseRIL_REQUEST_SWITCH_WAITING_OR_HOLDING_AND_ACTIVE:
- //3GPP22.0306.5.5
- //"Placesallactivecalls(ifanyexist)onholdandaccepts
- //theother(heldorwaiting)call."
- at_send_command("AT+CHLD=2",NULL);
- #ifdefWORKAROUND_ERRONEOUS_ANSWER
- s_expectAnswer=1;
- #endif/*WORKAROUND_ERRONEOUS_ANSWER*/
- /*successorfailureisignoredbytheupperlayerhere.
- itwillcallGET_CURRENT_CALLSanddeterminesuccessthatway*/
- RIL_onRequestComplete(t,RIL_E_SUCCESS,NULL,0);
- break;
- caseRIL_REQUEST_ANSWER:
- at_send_command("ATA",NULL);
- #ifdefWORKAROUND_ERRONEOUS_ANSWER
- s_expectAnswer=1;
- #endif/*WORKAROUND_ERRONEOUS_ANSWER*/
- /*successorfailureisignoredbytheupperlayerhere.
- itwillcallGET_CURRENT_CALLSanddeterminesuccessthatway*/
- RIL_onRequestComplete(t,RIL_E_SUCCESS,NULL,0);
- break;
- caseRIL_REQUEST_CONFERENCE:
- //3GPP22.0306.5.5
- //"Addsaheldcalltotheconversation"
- at_send_command("AT+CHLD=3",NULL);
- /*successorfailureisignoredbytheupperlayerhere.
- itwillcallGET_CURRENT_CALLSanddeterminesuccessthatway*/
- RIL_onRequestComplete(t,RIL_E_SUCCESS,NULL,0);
- break;
- caseRIL_REQUEST_UDUB:
- /*userdetermineduserbusy*/
- /*sometimesused:ATH*/
- at_send_command("ATH",NULL);
- /*successorfailureisignoredbytheupperlayerhere.
- itwillcallGET_CURRENT_CALLSanddeterminesuccessthatway*/
- RIL_onRequestComplete(t,RIL_E_SUCCESS,NULL,0);
- break;
- caseRIL_REQUEST_SEPARATE_CONNECTION:
- {
- charcmd[12];
- intparty=((int*)data)[0];
更多相关文章
- android在framework层增加自己的service仿照GPS
- Android活动生命周期
- 可左右两侧挤压傍边布局的Android抽屉
- Dalvik虚拟机JNI方法的注册过程分析
- Android单元测试研究与实践
- 第26章、OnKeyListener键盘事件(从零开始学Android)
- Android手掌抑制功能的实现
- 如何用Android(安卓)webview播放HTML5 video标签
- Android(安卓)App压力测试(Monkey和ADB)